requestAnimationFrame 与屏幕刷新率在 Canvas 动画中的影响

20#mpdrwjwble357j31j9p

在 Web 开发中,Canvas 是实现高性能绘图和动画的主要工具,而 `requestAnimationFrame`(rAF)是 Canvas 动画中控制帧更新的标准方法。理解 rAF 与屏幕刷新率的关系,对于保证 Canvas 动画的流畅性和一致性至关重要。

1. rAF 在 Canvas 动画中的作用

当使用 Canvas 绘制物体移动时,每一帧的更新通常包含以下步骤:

  1. 清空画布(或覆盖上一帧内容)
  2. 计算物体位置
  3. 绘制物体
  4. 请求下一帧

典型代码如下:

javascript 复制代码
let x = 0;

function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    x += 2; // 移动速度
    ctx.fillRect(x, 50, 50, 50);
    requestAnimationFrame(animate);
}

requestAnimationFrame(animate);

这里 requestAnimationFrame 控制每次 Canvas 绘制的执行时机。


2. 屏幕刷新率对 Canvas 动画的影响

requestAnimationFrame 会尽量与屏幕刷新同步,因此其调用频率与显示器刷新率直接相关:

  • 60Hz 屏幕:每秒约 60 帧(每帧 ~16.7ms)
  • 120Hz 屏幕:每秒约 120 帧(每帧 ~8.3ms)

如果动画逻辑直接依赖每次 rAF 调用更新位置(例如 x += 2),则:

  • 在高刷新率屏幕上,物体移动速度会更快(每秒移动距离翻倍)
  • 在低刷新率屏幕上,物体移动速度会更慢

这会导致动画在不同设备上表现不一致。


3. 使用时间差保证动画一致性

为了保证 Canvas 物体移动在不同刷新率屏幕上速度一致,应该使用 rAF 提供的时间戳参数(timestamp)来计算每帧的时间间隔,并按时间间隔调整移动距离:

javascript 复制代码
let lastTime = 0;
let x = 0;

function animate(timestamp) {
    if (!lastTime) lastTime = timestamp;
    const delta = timestamp - lastTime; // 帧间时间差
    lastTime = timestamp;

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    x += 0.1 * delta; // 根据时间差控制速度
    ctx.fillRect(x, 50, 50, 50);

    requestAnimationFrame(animate);
}

requestAnimationFrame(animate);

这样,无论屏幕刷新率是 60Hz 还是 144Hz,物体移动速度都保持一致。


4. 其他注意事项

  1. 动画平滑性:使用 rAF 保证绘制与屏幕刷新同步,避免撕裂和跳帧。
  2. 性能优化:Canvas 动画不需要每帧重绘整个画布,可以只重绘移动区域,节省 CPU/GPU 资源。
  3. 高刷新率适配:在 120Hz 或更高刷新率屏幕上,如果仍按固定像素移动,物体可能显得移动过快,因此必须使用时间差计算。

5. 总结

在 Canvas 动画中,requestAnimationFrame 的调用频率受到屏幕刷新率影响。若不考虑时间差直接按帧更新位置,动画在不同设备上会出现快慢不一的问题。正确做法是使用 rAF 的时间戳参数,通过时间差计算物体位移,保证在各种刷新率设备上的动画表现一致,同时保持渲染与屏幕同步,实现流畅、平滑的移动效果。

参与本文讨论

请先登录 GitHub 后留言

0/500

本文留言

0

这篇文章还没有留言,来写第一条吧。

1 / 1