HTML5动画怎样暂停与恢复_HTML5动画状态控制技巧【状态教程】

13次阅读

requestanimationFrame 实现暂停/恢复需手动管理时间戳:暂停时保存 lastTime 和 elapsed,恢复时用新帧时间减暂停起始时间补时长;css 的 animation-play-state 仅适用于纯 CSS 动画,对 canvas/webgl/Three.js/svg 无效;Three.js 需同时调用 clock.stop() 和 renderer.setAnimationLoop(NULL);canvas 动画暂停须冻结 velocity 等状态变量并限帧防瞬移。

HTML5动画怎样暂停与恢复_HTML5动画状态控制技巧【状态教程】

requestAnimationFrame 实现暂停/恢复必须自己管理时间戳

html5 本身没有内置的「暂停动画」API,requestAnimationFrame 一旦调用就会持续触发,靠 cancelAnimationFrame 只能终止,不能暂停。真正实现暂停/恢复,关键在于:**跳过帧计算,但保留上一帧的时间状态**。

常见错误是直接停掉 requestAnimationFrame 再重启——这会导致动画从头开始或出现跳变,因为时间差被重置了。

  • 记录进入暂停时的 lastTime 和当前 elapsed
  • 恢复时用新帧时间减去暂停起始时间,补上“被跳过的时长”
  • 避免在暂停期间仍调用 requestAnimationFrame(哪怕什么也不做)

animation-play-state 只对 CSS 动画有效,对 Canvas/WebGL 无效

如果你用的是 @keyframes + animation 的纯 CSS 动画,animation-play-state: paused 是最简方案,支持直接写在元素 style 或 class 中:

element.style.animationPlayState = 'paused'; element.style.animationPlayState = 'running';

但它对以下情况完全不起作用:

立即学习前端免费学习笔记(深入)”;

  • 中用 requestAnimationFrame 手绘的动画
  • WebGL 渲染循环(如 Three.jsrenderer.setAnimationLoop
  • SVG 元素(需用 beginElement()/endElement() 控制)

Three.js 中暂停动画要停渲染循环,而非仅停 clock

Three.js 的 Clock.getDelta() 可以暂停,但如果不同时停掉 renderer.setAnimationLoop,场景仍会不断重绘,CPU 白耗、电池白掉。

正确做法是双控:

  • 调用 clock.stop() 阻止时间推进
  • renderer.setAnimationLoop(null) 彻底停掉渲染循环
  • 恢复时先 clock.start(),再重新传入渲染函数给 setAnimationLoop

注意:clock.elapsedTimestop() 后不再更新,但值仍保留,可直接用于插值计算。

Canvas 动画暂停后恢复容易丢帧或卡顿

Canvas 动画若依赖 deltaTime 做物理模拟(比如速度 × 时间),暂停期间若没冻结所有状态变量,恢复瞬间可能因累积 delta 过大导致对象瞬移或穿模。

建议在暂停时显式冻结关键状态:

  • 保存并冻结 velocityaccelerationrotationSpeed 等运动变量
  • 不依赖全局 performance.now() 差值,改用相对暂停点的偏移量
  • 恢复时不直接加“暂停时长”,而是用 math.min(delta, 16) 限帧,防止单帧过载

复杂动画的状态分散在多个对象中时,最容易漏冻某个 isMoving 标志位,结果看起来“暂停了但还在动”。

text=ZqhQzanResources