图像在画布中闪烁

时间:2013-10-27 15:02:06

标签: javascript jquery html5 html5-canvas

我使用HTML5画布编写了一个简单的图像滑块。在每个图像到达屏幕的末端之后,将其从阵列中移除,这导致随机图像闪烁。我该如何解决这个问题。

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


                }

            };

当图像到达窗口的末尾时,我将其移除

albumWall.fbImages.splice(albumWall.fbImages.indexOf(this),1);

我认为这会导致屏幕随机闪烁的问题。

2 个答案:

答案 0 :(得分:2)

据我所知,你是对的。问题在于,通过在动画中间将图像拉出数组,您生成了一个框架,其中未渲染另一个图像(现在位于其中的图像)。这可以通过将上面的行更改为:

来解决
var that = this;
setTimeout( function() {
  albumWall.fbImages.splice(albumWall.fbImages.indexOf(that),1);
}, 0);

简短的解释是超时将使拼接等到当前动画功能完成后再触发。有关详细信息,请访问this helpful answer about using setTimeout to send functions down the stack

Here's your updated fiddle.

答案 1 :(得分:-1)

虽然Evan的答案是旧版浏览器的解决方法,但较新的浏览器支持requestAnimationFrame,这是一种更加清晰的防止闪烁的方法。

通过设置

 function yourDrawingFunction() {

      // your drawing code here

      window.requestAnimationFrame(yourDrawingFunction);
 };

 window.requestAnimationFrame( yourDrawingFunction );

只要浏览器准备好就会执行框架绘制代码,并且将自动使用双缓冲(在功能完成之前不会向用户显示任何内容)。这对性能也有两个积极的副作用:

  • 在大多数浏览器上绘图速度更快,因为它们更容易将绘图合并到自己的页面渲染管道的调度中
  • 当前浏览器选项卡不可见时,将不会执行代码,从而节省了用户计算机上的资源。但这意味着你必须确保你的框架绘图代码中没有实际的应用程序逻辑(但你不应该这样做)。

大多数浏览器已经支持此功能,但有些浏览器只支持其特定于供应商的前缀。初始化例程中的这个polyfiller代码段提供了兼容性,并且还为完全不支持它的浏览器提供了回退:

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          window.msRequestAnimationFrame     ||
          window.oRequestAnimationFrame      ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();