0

我使用 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);

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

4

2 回答 2

2

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

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

简短的解释是超时将使拼接等到您当前的动画功能完成后再触发。有关使用 setTimeout 将函数向下发送到堆栈的有用答案,可以找到更多信息。

这是你更新的小提琴。

于 2013-10-27T15:14:22.973 回答
0

虽然 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);
          };
})();
于 2013-10-28T09:58:12.760 回答