调整大小后,HTML画布更新次数太多

时间:2016-04-19 12:30:38

标签: javascript html5 canvas

我有一个画布,我在其中制作动画。我听窗口调整大小事件,更新画布大小并再次启动递归绘图。但似乎旧的draw()调用继续,这导致动画比预期更快。 这是代码:

HTML

<canvas id="myCanvas" width="1000" height="1000"></canvas>

CSS

* {
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100%;
  height: 100%;
}

canvas {
  display: block;
}

的JavaScript

var canvas = document.getElementById("myCanvas");
var context = canvas.getContext('2d');
var frameCount = 0;
var count = 0;

var rectDistance = 100;
var rectSize = 72;
var rectOffset = (rectDistance - rectSize) / 2;
var angleSpeed = 1;

var draw = function() {
  count++;

  var xCount = canvas.width / rectDistance;
  var yCount = canvas.height / rectDistance;

  context.fillStyle = "rgba(255,255,255,1)";
  context.fillRect(0, 0, canvas.width, canvas.height);

  for (var i = 0; i < xCount; i++) {
    for (var j = 0; j < yCount; j++) {

      context.save();

      var r = Math.round(i / xCount * 255);
      var g = Math.round(j / xCount * 255);

      xPos = i * rectDistance + rectOffset + Math.sin(j + frameCount / 20) * 10;
      yPos = j * rectDistance + rectOffset + Math.cos(i + frameCount / 20) * 10;

      context.translate(xPos + rectSize / 2, yPos + rectSize / 2);
      context.rotate(frameCount / 100 * angleSpeed * Math.sin(frameCount / 500) * 5);

      context.fillStyle = "rgba(" + r + "," + g + ",0,1)";
      context.fillRect(-rectSize / 2, -rectSize / 2, rectSize, rectSize);
      context.restore();
    }
  }

  frameCount = frameCount + 1;
  requestAnimationFrame(draw);
};

window.addEventListener('resize', function() {
  setTimeout(function() {
    resizeCanvas();
  }, 500);
}, false);

function resizeCanvas() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;

  draw();
}

// count the calls of draw() per second -> it's increasing on window.resize
function drawCalls() {
  setTimeout(function() {
    console.log("draw() called " + count + " times");
    count = 0;
    drawCalls();
  }, 1000)
}
drawCalls();

// start the loop
resizeCanvas();

如何阻止旧的draw()调用继续在resize上递归执行?

以下是具有相同问题的codepen:http://codepen.io/Sebkasanzew/pen/GZGZVP

1 个答案:

答案 0 :(得分:2)

您忘记取消setTimeout() - 我建议如下:

var timer;

window.addEventListener('resize', function() {
  cancelAnimationFrame(timer);                  // cancel previous request
  timer = requestAnimationFrame(function() {    // create a new request
    resizeCanvas();
  })
});