I've been playind with canvas lately and started today to work on using setInterval to refresh / animate it regularly. I was surprised to see how this is heavy for the cpu and slows down eveyrthing. Looking at example online I m sure there is something wrong with my way of doing. I then simplified what I wanted to do at the maximum (not playing with image but rectangles, not using too many objects, etc) but still got the same problem.
I was trying to get a white flash (at 12fps) on top of two rectangles...So nothing complicate at all...
Here is my code.
function Canvas(name){
this.ctx=document.getElementById(name).getContext('2d');
this.canvas=this.ctx.canvas;
this.width=this.canvas.width;
this.height=this.canvas.height;
this.layers=new Array();
this.draw = function() {
this.canvas.width = this.canvas.width;
this.ctx.beginPath();
this.ctx.rect(0,0,this.width,this.height);
this.ctx.closePath();
this.ctx.fillStyle="#eaeaea";
this.ctx.fill();
this.ctx.beginPath();
this.ctx.rect(250,50,300,250);
this.ctx.closePath();
this.ctx.fillStyle="#ff0000";
this.ctx.fill();
intensity=Math.random();
this.flash(intensity);
};
this.flash = function(intensity) {
this.ctx.globalAlpha = intensity;
this.ctx.beginPath();
this.ctx.rect(0,0,this.width,this.height);
this.ctx.closePath();
this.ctx.fillStyle="#fff";
this.ctx.fill();
this.ctx.globalAlpha = 1;
setInterval(this.draw.bind(this),1000);
};
function initCanvas(){
mycanvas=new Canvas('myCanvas');
mycanvas.draw();
}
$(document).ready(function() {
initCanvas();
});
Solution found:
Use setTimeout instead of setInterval .
Close all the paths, which you open:
this.draw = function() {
this.canvas.width = this.canvas.width;
this.ctx.beginPath();
this.ctx.rect(0,0,this.width,this.height);
this.ctx.closePath(); //Closing
this.ctx.fillStyle="#eaeaea";
this.ctx.fill();
this.ctx.beginPath();
this.ctx.rect(250,50,300,250);
this.ctx.closePath(); //Closing
this.ctx.fillStyle="#ff0000";
this.ctx.fill();
this.flash(40);
};
this.flash = function(intensity) {
this.ctx.globalAlpha = intensity;
this.ctx.beginPath();
this.ctx.rect(0,0,this.width,this.height);
this.ctx.closePath(); //Closing
this.ctx.fillStyle="#fff";
this.ctx.fill();
this.ctx.globalAlpha = 1;
setInterval(this.draw.bind(this),1000);
};
You've got a massive memory leak because you keep using setInterval
in the flash
function. Let's look at the sequence of events
draw
every second draw
To solve it, use setTimeout
in flash
. So it calls draw
after a second, which calls flash
and then calls draw
again in a second. Also, 1000ms won't give you 12fps. 1000/12 will.
Also, use ctx.closePath();
to close the paths you opened with beginPath()
You also never closed the Canvas
function with a }
.
Here's a demo
I don't know if this is relevant anymore, but I found myself in a similar situation and wanted to give an even better answer. Use requestAnimationFrame(yourLoop)
, especially for games since it is faster and has better performance. http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.