使用requestAnimationFrame实现一些稳定的帧速率?

时间:2013-05-15 09:19:04

标签: javascript performance animation requestanimationframe

我正在玩requestAnimationFrame,但我在除Chrome之外的任何其他浏览器中都会看到非常生涩的动画。

我创建了一个这样的对象:

var object = function() {

    var lastrender = (new Date()).getTime();
    var delta = 0;

    return {

        update: function() {
             //do updates using delta value in calculations.
        },

        loop: function() {
            var looptimestamp = (new Date()).getTime();
            delta = looptimestamp - lastrender;
            lastrender = looptimestamp;

            this.update();

            window.requestAnimationFrame(this.loop.bind(this));
        }
    };
}

现在我只是在画布元素上绘制一个矩形并移动它。它是处理器上非常轻量级的操作。这在Chrome中运行得相当顺利,当我控制日志记录delta值时,它几乎在~17左右。但是,如果我在Firefox或Safari中执行相同的操作,我会得到以下delta值:

17-3-17-2-32-34-32-31-19-31-17-3-0-14-3-14-35-31-16-3-17-2 ... and so on

看起来好像浏览器没有很好地与显示器同步,而在Chrome以外的所有其他情况下,使用旧的setTimeout方法以16ms作为目标超时,可以获得更流畅的动画。

有没有人知道,如果可以在Chrome以外的浏览器中使用requestAnimationFrame制作更流畅的动画?有没有人成功获得比上面发布的Firefox更稳定的delta值?

2 个答案:

答案 0 :(得分:4)

动画平滑帧率降低的原因是因为浏览器的内存与画布有关。我不知道浏览器性能的真实细节,但firefox几乎立即有帧率下降,而在Chrome中,下降时间会发生。

帧率下降的真正问题是由于canvas元素占用的内存。每次向画布绘制一些内容时,操作都会保存到画布的路径中。每次在画布上绘制内容时,此路径占用的内存更多。如果不清空画布的路径,则会出现帧率下降。通过使用context.clearRect(x, y, w, h);清除画布无法清空画布路径,而是必须通过使用context.beginPath();开始新路径来重置画布路径。例如:

// function that draws you content or animation
function draw(){
    // start a new path/empty canvas path
    canvas.beginPath(); 

    // actual drawing of content or animation here 
}

答案 1 :(得分:0)

如果您在delta<时跳过更新,则可能会获得更流畅的动画。阈值,例如:

if (delta > 5) this.update();