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

发布于 2024-09-07 13:37:44 字数 647 浏览 2 评论 0原文

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

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

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

但是,如何保持所有这一切的一致性,因为您不能总是确定浏览器何时会变慢,或者何时会执行得很快。例如,如果有巨大的运动峰值,我们减少间隔以保持帧速率稳定,然后突然大多数运动物体停止或不运动太多,它会突然执行得非常快!

有什么想法吗?

I have a function that calculates the next frame in an animation of various objects moving in both X and Y axis [ I call it frameRender() ] and a function that applies that resulting frame to the objects [ I call that frameDisplay() ]. The objects don't just move from point A to B, they move constantly, always receiving new target coords. I use a setInterval() with a 1000/frameRate interval but that doesn't seem to work at all as browsers don't have accurate timings.

The question is: How can I make sure the animation has a constant frame rate, and will run at the same speed on all browsers, on all systems? I have tried everything and can't seem to get an accurate result even on just different browsers (I test on Firefox and Chrome, Chrome usually displays a lot faster).

The result should be: When it plays slow, the animation interval should decrease at first, and then try to skip some frames [ by skipping frameDisplay() ] if it the DOM displays slow, until it plays correctly. When it plays fast, the animation interval should increase, making the animation play at the correct speed.

But how do you keep consistency in all of this, since you can't always be sure when the browsers will become slow, or when they will perform fast. For example, if there is huge spike of movements, and we decrease the interval to keep the frame rate steady, and then suddenly most of the moving objects stop or don't move much, it will suddenly perform really fast!

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绻影浮沉 2024-09-14 13:37:44

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

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

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

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

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

The question is: How can I make sure the animation has a constant frame rate, and will run at the same speed on all browsers, on all systems?

You can't do anything about the framerate. The only thing you can control is how your application updates based on time passed. This is true outside of browsers as well, and a common topic in game development.

The best thing to do is track the delta (read: time difference) between updates.

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

Notice the use of setTimeout here. This is to avoid the loop() from being called out of sync. setInterval will keep firing it even if a previous call didn't finish.

じее 2024-09-14 13:37:44

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

The answer is here, a great article by Glenn Fiedler, needs a little tweaking to convert it in Javascript but the principles are the same. Basically, you need to use an accumulator that adds up delta timings, and execute steps based on that. No need to change any physics math or anything, the solution is plug n play. Also has a cool interpolator that removes stuttering and also allows you to do super slow smooth motion (for replays etc.). It's fantastic, works for physics and should work on any step based motion. Basically all you need for accurate timing game motion is there.

临走之时 2024-09-14 13:37:44

您可以将动画与系统时间同步。

将当前系统时间保存在变量中。
在所有帧上,然后您想要重绘图片,检查当前时间 - 您的变量是否等于某个增量时间。然后重新绘制你的动画。否则等等这个差异

You can synhronize your animation with system time.

Save current system time in variable.
On the all of frames then you want to redraw picture check if current time - your variable equal some delta time. then redrow your animation. else wait this difference

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文