HTML画布在调整大小后更新次数过多 [英] HTML canvas updates too many times after resize
问题描述
我有一个帆布,其中我动画的东西。我听窗口调整大小事件,更新画布大小,并再次开始递归绘图。但是似乎老的draw()调用继续,这导致动画比预期更快。
下面是代码:
HTML
; canvas id =myCanvaswidth =1000height =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();
}
//计算draw()每秒的调用次数 - >它在window.resize上增加
function drawCalls(){
setTimeout(function(){
console.log(draw()called+ count +times) b count = 0;
drawCalls();
},1000)
}
drawCalls();
//启动循环
resizeCanvas();如何防止老的draw()调用在resize上继续递归执行?
这是一个有同样问题的代码: http:// codepen .io / Sebkasanzew / pen / GZGZVP
解决方案您忘记取消 setTimeout ()
- 我建议如下:
var timer;
window.addEventListener('resize',function(){
cancelAnimationFrame(timer); //取消上一个请求
timer = requestAnimationFrame(function(){// create a new request
resizeCanvas();
})
});
I have a canvas in which I animate stuff. I listen to the window resize event, update the canvas size and start the recursive drawing again. But it seems like the old draw() calls continue and this causes the animation to go faster than intended.
Here is the code:
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();
How I can prevent the old draw() calls continue their recursive execution on resize?
Here is a codepen with the same issue: http://codepen.io/Sebkasanzew/pen/GZGZVP
解决方案 You are forgetting to cancel the setTimeout()
- I would suggest the following:
var timer;
window.addEventListener('resize', function() {
cancelAnimationFrame(timer); // cancel previous request
timer = requestAnimationFrame(function() { // create a new request
resizeCanvas();
})
});
这篇关于HTML画布在调整大小后更新次数过多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!