使用requestAnimationFrame重启旋转动画时如何保持箭头停止时的位置
问题核心原因
你遇到的跳帧问题本质出在时间计算逻辑上:requestAnimationFrame 传入的timestamp是从页面加载开始计算的绝对时间,原有方案每次重启动画时都用新的时间戳减去重置的startTime,相当于完全丢弃了之前的旋转进度,才会出现位置跳变。
更优实现方案
只需要额外记录停止时的累计时长偏移量,重启时把偏移量补入时间计算逻辑,就可以无缝衔接之前的旋转位置,不需要维护大量冗余状态变量。
完整代码
JavaScript
const spinner = document.querySelector('div') let rotateCount = 0 let startTime = null let offsetTime = 0 // 存储停止时累计的旋转时长偏移 let rAF let spinning = false function draw(timestamp) { if (!startTime) startTime = timestamp // 计算角度时加上之前累计的偏移,不需要分支判断 rotateCount = ((timestamp - startTime + offsetTime) / 3) % 360 spinner.style.transform = `rotate(${rotateCount}deg)` rAF = requestAnimationFrame(draw) } document.body.addEventListener('click', () => { if (spinning) { // 停止时保存当前累计的旋转时长 offsetTime += performance.now() - startTime cancelAnimationFrame(rAF) startTime = null // 重置启动时间标记,下次启动重新取最新时间戳 } else { draw() } spinning = !spinning })
CSS
html { background-color: white; height: 100%; } body { height: inherit; background-color: #f00; margin: 0; display: flex; justify-content: center; align-items: center; } div { display: inline-block; font-size: 10rem; }
HTML
<div>↻</div>
方案优势
- 状态变量精简了一半,没有冗余的分支判断逻辑,可读性更高
- 完全适配
requestAnimationFrame的刷新率,不会出现固定间隔计算角度导致的掉帧问题 - 重启时的位置衔接没有误差,和暂停前的状态完全一致
内容的提问来源于stack exchange,提问作者hustnzj
相关产品推荐
相关产品推荐

