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

HTML canvas updates too many times after resize

本文关键字:更新 HTML 布更新 调整      更新时间:2023-09-26

我有一个画布,可以在其中制作动画。我收听窗口大小调整事件,更新画布大小,然后再次开始递归绘图。但似乎旧的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()调用在调整大小时继续递归执行?

这是一个有相同问题的代码笔:http://codepen.io/Sebkasanzew/pen/GZGZVP

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

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