Canvas width and height in HTML5

后端 未结 4 1012
青春惊慌失措
青春惊慌失措 2020-11-22 04:46

Is it possible to fix the width and height of an HTML5 canvas element?

The usual way is the following :



        
4条回答
  •  隐瞒了意图╮
    2020-11-22 05:25

    A canvas has 2 sizes, the dimension of the pixels in the canvas (it's backingstore or drawingBuffer) and the display size. The number of pixels is set using the the canvas attributes. In HTML

    
    

    Or in JavaScript

    someCanvasElement.width = 400;
    someCanvasElement.height = 300;
    

    Separate from that are the canvas's CSS style width and height

    In CSS

    canvas {  /* or some other selector */
       width: 500px;
       height: 400px;
    }
    

    Or in JavaScript

    canvas.style.width = "500px";
    canvas.style.height = "400px";
    

    The arguably best way to make a canvas 1x1 pixels is to ALWAYS USE CSS to choose the size then write a tiny bit of JavaScript to make the number of pixels match that size.

    function resizeCanvasToDisplaySize(canvas) {
       // look up the size the canvas is being displayed
       const width = canvas.clientWidth;
       const height = canvas.clientHeight;
    
       // If it's resolution does not match change it
       if (canvas.width !== width || canvas.height !== height) {
         canvas.width = width;
         canvas.height = height;
         return true;
       }
    
       return false;
    }
    

    Why is this the best way? Because it works in most cases without having to change any code.

    Here's a full window canvas:

    const ctx = document.querySelector("#c").getContext("2d");
    
    function render(time) {
      time *= 0.001;
      resizeCanvasToDisplaySize(ctx.canvas);
     
      ctx.fillStyle = "#DDE";
      ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
      ctx.save();
     
      const spacing = 64;
      const size = 48;
      const across = ctx.canvas.width / spacing + 1;
      const down = ctx.canvas.height / spacing + 1;
      const s = Math.sin(time);
      const c = Math.cos(time);
      for (let y = 0; y < down; ++y) {
        for (let x = 0; x < across; ++x) {
          ctx.setTransform(c, -s, s, c, x * spacing, y * spacing);
          ctx.strokeRect(-size / 2, -size / 2, size, size);
        }
      }
      
      ctx.restore();
      
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
    
    function resizeCanvasToDisplaySize(canvas) {
       // look up the size the canvas is being displayed
       const width = canvas.clientWidth;
       const height = canvas.clientHeight;
    
       // If it's resolution does not match change it
       if (canvas.width !== width || canvas.height !== height) {
         canvas.width = width;
         canvas.height = height;
         return true;
       }
    
       return false;
    }
    body { margin: 0; }
    canvas { display: block; width: 100vw; height: 100vh; }

    And Here's a canvas as a float in a paragraph

    const ctx = document.querySelector("#c").getContext("2d");
    
    function render(time) {
      time *= 0.001;
      resizeCanvasToDisplaySize(ctx.canvas);
     
      ctx.fillStyle = "#DDE";
      ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
      ctx.save();
     
      const spacing = 64;
      const size = 48;
      const across = ctx.canvas.width  / spacing + 1;
      const down   = ctx.canvas.height / spacing + 1;
      const s = Math.sin(time);
      const c = Math.cos(time);
      for (let y = 0; y <= down; ++y) {
        for (let x = 0; x <= across; ++x) {
          ctx.setTransform(c, -s, s, c, x * spacing, y * spacing);
          ctx.strokeRect(-size / 2, -size / 2, size, size);
        }
      }
      
      ctx.restore();
      
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
    
    function resizeCanvasToDisplaySize(canvas) {
       // look up the size the canvas is being displayed
       const width = canvas.clientWidth;
       const height = canvas.clientHeight;
    
       // If it's resolution does not match change it
       if (canvas.width !== width || canvas.height !== height) {
         canvas.width = width;
         canvas.height = height;
         return true;
       }
    
       return false;
    }
    span { 
       width: 250px; 
       height: 100px; 
       float: left; 
       padding: 1em 1em 1em 0;
       display: inline-block;
    }
    canvas {
       width: 100%;
       height: 100%;
    }

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus venenatis metus. Mauris ac nibh at odio scelerisque scelerisque. Donec ut enim vel urna gravida imperdiet id ac odio. Aenean congue hendrerit eros id facilisis. In vitae leo ullamcorper, aliquet leo a, vehicula magna. Proin sollicitudin vestibulum aliquet. Sed et varius justo.

    Quisque tempor metus in porttitor placerat. Nulla vehicula sem nec ipsum commodo, at tincidunt orci porttitor. Duis porttitor egestas dui eu viverra. Sed et ipsum eget odio pharetra semper. Integer tempor orci quam, eget aliquet velit consectetur sit amet. Maecenas maximus placerat arcu in varius. Morbi semper, quam a ullamcorper interdum, augue nisl sagittis urna, sed pharetra lectus ex nec elit. Nullam viverra lacinia tellus, bibendum maximus nisl dictum id. Phasellus mauris quam, rutrum ut congue non, hendrerit sollicitudin urna.

    Here's a canvas in a sizable control panel

    const ctx = document.querySelector("#c").getContext("2d");
    
    function render(time) {
      time *= 0.001;
      resizeCanvasToDisplaySize(ctx.canvas);
    
      ctx.fillStyle = "#DDE";
      ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
      ctx.save();
     
      const spacing = 64;
      const size = 48;
      const across = ctx.canvas.width / spacing + 1;
      const down = ctx.canvas.height / spacing + 1;
      const s = Math.sin(time);
      const c = Math.cos(time);
      for (let y = 0; y < down; ++y) {
        for (let x = 0; x < across; ++x) {
          ctx.setTransform(c, -s, s, c, x * spacing, y * spacing);
          ctx.strokeRect(-size / 2, -size / 2, size, size);
        }
      }
      
      ctx.restore();
      
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
    
    function resizeCanvasToDisplaySize(canvas) {
       // look up the size the canvas is being displayed
       const width = canvas.clientWidth;
       const height = canvas.clientHeight;
    
       // If it's resolution does not match change it
       if (canvas.width !== width || canvas.height !== height) {
         canvas.width = width;
         canvas.height = height;
         return true;
       }
    
       return false;
    }
    
    // ----- the code above related to the canvas does not change ----
    // ---- the code below is related to the slider ----
    const $ = document.querySelector.bind(document);
    const left = $(".left");
    const slider = $(".slider");
    let dragging;
    let lastX;
    let startWidth;
    
    slider.addEventListener('mousedown', e => {
     lastX = e.pageX;
     dragging = true;
    });
    
    window.addEventListener('mouseup', e => {
     dragging = false;
    });
    
    window.addEventListener('mousemove', e => {
      if (dragging) {
        const deltaX = e.pageX - lastX;
        left.style.width = left.clientWidth + deltaX + "px";
        lastX = e.pageX;
      }
    });
    body { 
      margin: 0;
    }
    .frame {
      display: flex;
      align-items: space-between;
      height: 100vh;
    }
    .left {
      width: 70%;
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
    }  
    canvas {
      width: 100%;
      height: 100%;
    }
    pre {
      padding: 1em;
    }
    .slider {
      width: 10px;
      background: #000;
    }
    .right {
      flex 1 1 auto;
    }
    * controls
    * go 
    * here
    
    <- drag this
         

    here's a canvas as a background

    const ctx = document.querySelector("#c").getContext("2d");
    
    function render(time) {
      time *= 0.001;
      resizeCanvasToDisplaySize(ctx.canvas);
     
      ctx.fillStyle = "#DDE";
      ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
      ctx.save();
     
      const spacing = 64;
      const size = 48;
      const across = ctx.canvas.width / spacing + 1;
      const down = ctx.canvas.height / spacing + 1;
      const s = Math.sin(time);
      const c = Math.cos(time);
      for (let y = 0; y < down; ++y) {
        for (let x = 0; x < across; ++x) {
          ctx.setTransform(c, -s, s, c, x * spacing, y * spacing);
          ctx.strokeRect(-size / 2, -size / 2, size, size);
        }
      }
      
      ctx.restore();
      
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
    
    function resizeCanvasToDisplaySize(canvas) {
       // look up the size the canvas is being displayed
       const width = canvas.clientWidth;
       const height = canvas.clientHeight;
    
       // If it's resolution does not match change it
       if (canvas.width !== width || canvas.height !== height) {
         canvas.width = width;
         canvas.height = height;
         return true;
       }
    
       return false;
    }
    body { margin: 0; }
    canvas { 
      display: block; 
      width: 100vw; 
      height: 100vh;  
      position: fixed;
    }
    #content {
      position: absolute;
      margin: 0 1em;
      font-size: xx-large;
      font-family: sans-serif;
      font-weight: bold;
      text-shadow: 2px  2px 0 #FFF, 
                  -2px -2px 0 #FFF,
                  -2px  2px 0 #FFF,
                   2px -2px 0 #FFF;
    }
    
    

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus venenatis metus. Mauris ac nibh at odio scelerisque scelerisque. Donec ut enim vel urna gravida imperdiet id ac odio. Aenean congue hendrerit eros id facilisis. In vitae leo ullamcorper, aliquet leo a, vehicula magna. Proin sollicitudin vestibulum aliquet. Sed et varius justo.

    Quisque tempor metus in porttitor placerat. Nulla vehicula sem nec ipsum commodo, at tincidunt orci porttitor. Duis porttitor egestas dui eu viverra. Sed et ipsum eget odio pharetra semper. Integer tempor orci quam, eget aliquet velit consectetur sit amet. Maecenas maximus placerat arcu in varius. Morbi semper, quam a ullamcorper interdum, augue nisl sagittis urna, sed pharetra lectus ex nec elit. Nullam viverra lacinia tellus, bibendum maximus nisl dictum id. Phasellus mauris quam, rutrum ut congue non, hendrerit sollicitudin urna.

    Because I didn't set the attributes the only thing that changed in each sample is the CSS (as far as the canvas is concerned)

    Notes:

    • Don't put borders or padding on a canvas element. Computing the size to subtract from the number of dimensions of the element is troublesome

提交回复
热议问题