HTML canvas updates too many times after resize

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

Answers:

Answer

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();
  })
});

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.