首页 > 解决方案 > 使用requestAnimationFrame时,如何让部分动画更新更快

问题描述

我正在使用requestAnimationFrame做一个游戏(游戏像蛇),游戏的帧更新速度最初是每秒更新一次

它需要将这条蛇的“requestAnimationFrame”从每次一秒更新到每次0.5秒。由于许多蛇的设计,当蛇接触任何物品时,它会获得 10 秒的加速情况。

我的问题是如何维护主要的“requestAnimationFrame”(每秒更新一次),还有另一个“requestAnimationFrame”(每0.5秒更新一次)?

主请求动画帧代码

    let speed = 1;
    let lastRenderTime = 0;

    const doAnimation = function (currentTime) {

        window.requestAnimationFrame(doAnimation);

        const secondRender = (currentTime - lastRenderTime) / 1000;  // secondRender is used to control the update per second

        if (secondRender < 1 / speed) {
            return;
        }
        lastRenderTime = currentTime
    }

    window.requestAnimationFrame(doAnimation);

标签: javascriptbrowserfrontendrequestanimationframe

解决方案


requestAnimationFrame射速通常在 60Hz 左右。即每秒 60 次调用,最大理论精度约为 16 毫秒(0.016 秒)。

这意味着在您的循环中,您可以使事物以高于此的任何速率进行更新。但是为什么要截断精度呢?

关键requestAnimationFrame是要准确知道重绘何时发生,并在正确的时间传递有关您的动画的信息。举个例子:如果你的蛇必须每秒移动 1000 像素,你为什么要每秒通知浏览器更新?理想情况下,您应该在每一帧上更新您的视图。所以在这个例子中,每 16 毫秒有 16 像素的变化。

请参阅以下代码段,并注意在任何地方都没有条件。但只是不断更新。

显然最终的实现将取决于您的用例,但这只是工作原理。

const boxA = document.getElementById('boxA'); // DEMO
const boxB = document.getElementById('boxB'); // DEMO

let xA = 0; // DEMO
let xB = 0; // DEMO

const speedA = 80; // [px/s]
const speedB = 160; // [px/s]

let then = 0;

const animate = function (now) {
    window.requestAnimationFrame(animate);

    const delta = (now - then) / 1000;

    // A
    const a = speedA * delta;
    boxA.style.transform = `translateX(${xA += a}px)`; // DEMO
    
    // B
    const b = speedB * delta;
    boxB.style.transform = `translateX(${xB += b}px)`; // DEMO
    
    then = now
}

window.requestAnimationFrame(animate);
.container {
  display: flex;
  flex-direction: column;
}

#boxA,
#boxB {
  display: inline-block;
  height: 50px;
  width: 50px;
  transform: translateX(0);
}

#boxA {
  background-color: #ff0000;
}

#boxB {
  background-color: #0000ff;
}
<div class='container'>
  <span id='boxA'></span>
  <span id='boxB'></span>
</div>


推荐阅读