Reputation: 6894
I've written a simple image slider using HTML5 canvas. After each image reaches end of screen it is removed from the array which is causing random image flickering. How can i fix this.
JSFiddle : http://jsfiddle.net/mbe5R/2/
this.animate = function() {
this.y += this.speed;
this.x = this.xrandom * albumWall.canvas.width - 250;
if(this.y > innerHeight) {
albumWall.fbImages.splice(albumWall.fbImages.indexOf(this),1);
if(albumWall.count==(albumWall.imgArr.length-1)) {
albumWall.count=-1;
}else{
albumWall.count++;
var img = albumWall.imgArr[albumWall.count];
console.log(img)
albumWall.fbImages.push(new self.fbImage(albumWall.count, img, img.width, img.height));
}
}
};
When the image reaches the end of window i'm removing it
albumWall.fbImages.splice(albumWall.fbImages.indexOf(this),1);
I think this is causing the problem for the screen to flicker randomly.
Upvotes: 1
Views: 2665
Reputation: 69673
While the answer by Evan is a workaround for older browsers, newer browsers support requestAnimationFrame which is a much cleaner way to prevent flickering.
By setting
function yourDrawingFunction() {
// your drawing code here
window.requestAnimationFrame(yourDrawingFunction);
};
window.requestAnimationFrame( yourDrawingFunction );
the frame-drawing code will be executed whenever the browser is ready and will automatically use double-buffering (nothing will be shown to the user before the function has finished). This also has two positive side-effects for performance:
Most browsers already support this, but some only with their vendor-specific prefix. This polyfiller snippet in your initialization routine provides compatibility and also provides a fallback for browsers which don't support it at all:
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
Upvotes: 0
Reputation: 825
You were right, as far as I can tell. The issue was that by pulling the image out of the array in the middle of the animation, you produced a frame where another image (the one now in its place, most likely) was not rendered. This can be fixed by changing that above line to this:
var that = this;
setTimeout( function() {
albumWall.fbImages.splice(albumWall.fbImages.indexOf(that),1);
}, 0);
The short explanation is that the timeout will make the splice wait until your current animation function is complete before triggering. More information can be found at this helpful answer about using setTimeout to send functions down the stack.
Upvotes: 2