html5 canvas redraw on resize

后端 未结 3 1202
暗喜
暗喜 2020-12-09 12:56

I have two canvas elements and need them to be resized on buttons click.

3条回答
  •  一向
    一向 (楼主)
    2020-12-09 13:20

    If you need scale-independent positions you could use normalized values ([0, 1]) instead and use the size of canvas as the scale factor. This way you can scale and store values without too much concern about the actual target size.

    You would also be able to use the mouse positions almost as is and normalize by just dividing them on canvas size.

    For example:

    When rendering, a point of (1,1) will always draw in lower-right corner as you would do (1 * canvas.width, 1 * canvas.height).

    When you store a point you would use the mouse position and divide it on the canvas dimension, for example, if I click in the lower right corner of a canvas of size 400x200, the points would be 400/400 = 1, 200/200 = 1.

    Note that width and height would be exclusive (ie. width-1 etc.), but for sake of simplicity...

    Example

    In this example you can start with any size of the canvas, draw points which are normalized, change size of canvas and have the points redrawn proportionally relative to the original position.

    var rng = document.querySelector("input"),
        c = document.querySelector("canvas"),
        ctx = c.getContext("2d"),
        points = [];
    
    // change canvas size and redraw all points
    rng.onchange = function() {
      c.width = +this.value;
      render();
    };
    
    // add a new normalized point to array
    c.onclick = function(e) {
      var r = this.getBoundingClientRect(),   // to adjust mouse position
          x = e.clientX - r.left,
          y = e.clientY - r.top;
      points.push({
        x: x / c.width,                       // normalize value to range [0, 1]
        y: y / c.height
      });                                     // store point
      render();                               // redraw (for demo)
    };
    
    function render() {
      ctx.clearRect(0, 0, c.width, c.height); // clear canvas
      ctx.beginPath();                        // clear path
      for(var i = 0, p; p = points[i]; i++) { // draw points as fixed-size circles
        var x = p.x * c.width,                // normalized to absolute values
            y = p.y * c.height;
        
        ctx.moveTo(x + 5, y);
        ctx.arc(x, y, 5, 0, 6.28);
        ctx.closePath();
      }
      ctx.stroke();
    }
    canvas {background:#ffffd}

    Click on canvas to add points, then resize


提交回复
热议问题