You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用RequestAnimationFrame在保持60fps刷新率时放慢动画?

理解RequestAnimationFrame与慢动画实现

我完全理解这种困惑——很多人刚接触requestAnimationFrame(rAF)时,都会把“渲染帧率”和“动画速度”混为一谈。先帮你把rAF的核心机制掰明白,再给你一个简单的方案,既能保持Canvas 60fps的流畅渲染,又能轻松控制动画快慢。

先搞懂RequestAnimationFrame的工作逻辑

rAF不是一个固定间隔的定时器,它的核心是和浏览器的屏幕刷新同步:

  • 浏览器每次准备刷新屏幕前(通常是60次/秒,也就是每~16.67ms一次),会调用你传给rAF的回调函数。
  • 它会自动在页面隐藏时暂停执行,避免浪费资源,这是setInterval做不到的。
  • 回调函数会接收一个关键参数:timestamp,这是一个高精度的时间戳(从页面加载开始计算的毫秒数),用来计算两次回调之间的时间差。

你之前可能误以为要通过“减少rAF的调用次数”来放慢动画,但这会直接破坏和屏幕的同步,导致掉帧、卡顿,完全没必要——我们要分开控制渲染帧率(保持60fps,让画面流畅)和动画速度(让元素动得慢一些)。

正确实现:用时间差控制动画速度

核心思路是:动画的变化量基于时间,而不是rAF的调用次数。不管rAF的调用间隔有没有微小波动(比如偶尔因为主线程繁忙,间隔变成17ms),动画的速度都会保持稳定,同时渲染依然跟着屏幕刷新走,保持60fps。

举个具体的例子,假设你原来的代码是每次rAF就让元素移动固定像素:

let x = 0;
function animate() {
  x += 1; // 每次移动1px
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillRect(x, 50, 50, 50);
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

改成基于时间差的版本后,就能轻松控制速度:

let x = 0;
let lastTimestamp = 0;
const moveSpeed = 50; // 元素每秒移动50px(基础速度)
const speedScale = 0.5; // 动画放慢到50%,想更快就改大,比如2就是两倍速

function animate(timestamp) {
  // 初始化上一次时间戳
  if (!lastTimestamp) lastTimestamp = timestamp;
  
  // 计算两次回调的时间差,转换成秒(方便计算每秒移动的距离)
  const deltaTime = (timestamp - lastTimestamp) / 1000;
  lastTimestamp = timestamp;

  // 基于时间差计算本次要移动的距离:速度 × 时间 × 缩放因子
  x += moveSpeed * deltaTime * speedScale;

  // 正常执行Canvas绘制
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillRect(x, 50, 50, 50);

  // 继续请求下一次渲染
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

关键点解释:

  1. deltaTime:两次rAF回调之间的时间差,确保动画速度不受浏览器临时卡顿的影响,始终稳定。
  2. speedScale:这就是你要的“放慢动画”的开关——把它改成0.3就是30%速度,改成2就是两倍速,完全不影响渲染帧率。
  3. 保持60fps:rAF依然会跟着屏幕刷新频率调用,每次回调都执行一次绘制,所以画面依然是每秒60帧的流畅状态,只是元素每次绘制时的位移变小了,看起来动画变慢了。

总结一下

  • 不要试图修改rAF的调用间隔来控制动画速度,这会破坏和屏幕的同步,导致卡顿。
  • 用rAF提供的timestamp计算时间差,基于时间来驱动动画变化,这是专业动画的标准做法。
  • 放慢/加快动画只需要调整速度参数或缩放因子,渲染帧率会自动保持和屏幕同步(通常60fps)。

内容的提问来源于stack exchange,提问作者PiotrZadka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:00:23