代码之家  ›  专栏  ›  技术社区  ›  user1184100

画布中的图像闪烁

  •  0
  • user1184100  · 技术社区  · 11 年前

    我已经使用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 回复  |  直到 11 年前
        1
  •  2
  •   Community CDub    7 年前

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

    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.

        2
  •  0
  •   Philipp    11 年前

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