HTML画布在调整大小后更新次数过多 [英] HTML canvas updates too many times after resize

查看:108
本文介绍了HTML画布在调整大小后更新次数过多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个帆布,其中我动画的东西。我听窗口调整大小事件,更新画布大小,并再次开始递归绘图。但是似乎老的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆