2

我有这幅画布动画,它表现出一些奇怪的特征:

http://jsbin.com/olaso​​l/2/edit

我使用的是最新版本的 Chrome。我正在使用 Chrome 的内置 FPS 监视器(您可以通过转到 来激活它about:flags)。我在 JavaScript 部分中标记了我认为是潜在罪魁祸首的行:

fallingctx.clear();

这条线没有什么特别的。它调用一个函数,该函数又调用clearRect().

我注意到的“奇怪”的事情是:

  1. clear();功能在我的笔记本电脑(Core 2 Duo)上导致非常明显的 FPS 下降,但在我的台式机(i5 2500k)上没有。

  2. 仅删除那条线就足以在我的笔记本电脑上产生 60fps 的速度。正如预期的那样,画布在每一帧后都不会清晰,但仍然可以产生稳定的 60fps。

  3. 仅当我的 Chrome 窗口位于较大的一侧时,才会发生 FPS 下降!当我缩小窗口并重新加载时,它不会发生!(清除更大的矩形是否更昂贵?)。

  4. 我尝试用全白 JPEG 替换clear()drawImage()覆盖画布。JavaScript 能够drawImage()为较小的图像粒子在每个循环中执行 200 次(从第二点可以看出)。drawImage但是,当我为整个画布添加一个单曲时,它又滞后了!(确保输出占据整个屏幕以重现结果。)

为什么会发生这一切?我如何解决它?

4

1 回答 1

2

真的取决于硬件,但想想调用clearRect必须做什么!本质上必须将一块足够大的内存清零以处理画布内容。那可能代价高昂。想想在 HD 分辨率下需要多少内存来保存 RGBA……这是超过 200 万像素的数据,大约 8 MB字节将内存推送到视频卡或您每秒执行 60 次的操作……好吧,期待问题。

我经常听到的只是为了清除以前绘制图像的位置。见http://jsbin.com/olaso​​l/6/edit

我为您做了以下更改。

    for (var i=0; i< noOfDrops; ++i)
    {
        fallingctx.clearRect(
          fallingDrops[i].x-1,
          fallingDrops[i].y-1,
          fallingDrops[i].image.width+2,
          fallingDrops[i].image.height+2);
    }
    for (var i=0; i< noOfDrops; ++i)
    {
        fallingDrops[i].y += fallingDrops[i].speed; //Set the falling speed
        fallingctx.drawImage (fallingDrops[i].image, fallingDrops[i].x, fallingDrops[i].y);
    }

可能有一个很好的理由,我需要clearRect 围绕图像的渲染位置,但一个简单的原因让我无法理解。(这与在指定像素处渲染的东西不完全有关......我完全忘记了)。

您还需要在加载图像(也在 jsbin 中)之前启动渲染循环这一事实,所以我添加了

var imgSource = "http://lorempixel.com/20/20/sports/"; 
var imgObj = new Image();

并更换superinit

function superinit()
{ 
    imgObj.onload = function(){
        flowerfallsetup();
        requestAnimFrame(flowerfall);
    }
    imgObj.onerror = function (){
        alert("could not load image");
    }
    imgObj.src = imgSource;
}

编辑:由于先前的图像设置,我忘了提及,我确实更改了您的行flowerfallsetup

      fallingDr["image"] = imgObj; 

处理图像的异步加载有很多方法,我只是选择了一个对这个例子来说很容易的方法。

编辑:我不得不承认,这可能还有更多。它在桌面浏览器上运行良好,但在 iPhone 上,存在剪辑问题。如果我能找出导致问题的原因,我会尝试发布更新。

于 2013-05-13T19:56:13.573 回答