如何在所有系统上的所有浏览器上以相同的速度播放JavaScript动画?

sta*_*gas 6 javascript performance animation frame-rate cross-browser

我有一个函数,计算在X和Y轴上移动的各种对象的动画中的下一帧[我称之为frameRender()]和一个将结果帧应用于对象的函数[我称之为frameDisplay()].物体不仅从A点移动到B点,它们不断移动,总是接收新的目标坐标.我使用setInterval()1000/frameRate间隔的但是由于浏览器没有准确的计时,这似乎根本不起作用.

问题是:如何确保动画具有恒定的帧速率,并且将在所有系统上的所有浏览器上以相同的速度运行?我已经尝试了一切,即使只是在不同的浏览器上也无法获得准确的结果(我在Firefox和Chrome上测试,Chrome通常显示得更快).

结果应该是:当它播放缓慢时,动画间隔应首先减小,然后尝试跳过一些帧[跳过frameDisplay()],如果DOM显示缓慢,直到它正确播放.当它快速播放时,动画间隔应该增加,使动画以正确的速度播放.

但是如何保持所有这一切的一致性,因为你不能总是确定浏览器什么时候变慢,或者什么时候它们会快速执行.例如,如果有大幅度的移动,我们减少间隔以保持帧速率稳定,然后突然大多数移动物体停止或移动不多,它会突然执行得非常快!

有任何想法吗?

Mat*_*att 7

问题是:如何确保动画具有恒定的帧速率,并且将在所有系统上的所有浏览器上以相同的速度运行?

你无法对帧率做任何事情.您可以控制的唯一事情是您的应用程序如何根据时间的推移进行更新.这在浏览器之外也是如此,并且是游戏开发中的常见主题.

最好的办法是跟踪更新之间的增量(读取:时差).

(function () {
    function getTime() {
        return new Date().getTime();
    }
    var last = getTime();

    function update(delta) {
        // Update your application state on delta (ms of time passed)
    }

    (function loop() {
        update(last = getTime()-last);
        render();
        setTimeout(loop, 20); // 20 = attempt 50fps
    }());
}());
Run Code Online (Sandbox Code Playgroud)

注意这里使用setTimeout.这是为了避免loop()被调用不同步.即使之前的调用没有完成,setInterval也会继续触发它.


sta*_*gas 3

答案就在这里,Glenn Fiedler 写的一篇很棒的文章,需要一些调整才能将其转换为 Javascript,但原理是相同的。基本上,您需要使用累加器来累加增量时序,并基于此执行步骤。无需改变任何物理数学或任何东西,解决方案是即插即用。还有一个很酷的插值器,可以消除口吃,还可以让您进行超级慢速平滑运动(用于重播等)。它太棒了,适用于物理,并且应该适用于任何基于步骤的运动。基本上,精确计时游戏动作所需的一切都在这里。