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

CSS Web Animations API动画切换卡顿问题求助

WAAPI动画反向切换卡顿问题修复

问题说明

使用CSS Web Animations API(WAAPI)实现元素动画切换:点击按钮触发正向播放,再次点击触发反向播放,循环往复。首次动画运行正常,但从第二次切换开始出现卡顿、画面不流畅的问题。需求包括:

  • 元素保留动画结束时的样式
  • 快速点击按钮时,动画能立即从当前状态反向切换,无延迟或视觉异常

问题根源

原代码复用单个动画实例时,直接调用play()和reverse()无法正确处理动画在播放中或完成后的状态同步,尤其是快速切换时,浏览器无法及时衔接动画状态,导致卡顿。

解决方案

通过控制动画的playbackRate(播放速率)来实现实时反转,无论动画当前处于播放中还是暂停状态,都能立即从当前位置切换方向,同时保留fill: 'both'的样式保留效果。

修改后的代码

const keyframes = [
  { border: '2px solid red', width: '200px', backgroundColor: 'blue', offset: 0 },
  { border: '6px solid green', width: '250px', backgroundColor: 'purple', offset: 1 }
];

const options = {
  duration: 200,
  easing: 'ease-in',
  fill: 'both'
};

// 初始化动画并暂停
const animation = box.animate(keyframes, options);
animation.pause();

button.addEventListener('click', () => {
  // 如果动画正在播放,直接反转播放速率
  if (animation.playState === 'running') {
    animation.playbackRate *= -1;
  } else {
    // 动画已暂停时,根据当前位置判断播放方向
    if (animation.currentTime === 0) {
      // 当前在起始位置,正向播放
      animation.playbackRate = 1;
      animation.play();
    } else if (animation.currentTime === animation.effect.getTiming().duration) {
      // 当前在结束位置,反向播放
      animation.playbackRate = -1;
      animation.play();
    } else {
      // 当前在中间位置,反转速率继续播放
      animation.playbackRate *= -1;
      animation.play();
    }
  }
});

方案优势

  1. 实时响应:快速点击时,动画立即从当前状态反向切换,无延迟
  2. 状态衔接流畅:通过播放速率反转,避免了动画实例重置或状态不同步导致的卡顿
  3. 保留结束样式:fill: 'both'配置确保动画结束后元素保持最终样式

备选方案(重新创建动画实例)

如果更倾向于每次切换都创建新动画实例,可通过取消旧动画并根据方向创建新动画,同样能解决卡顿问题:

const keyframes = [
  { border: '2px solid red', width: '200px', backgroundColor: 'blue', offset: 0 },
  { border: '6px solid green', width: '250px', backgroundColor: 'purple', offset: 1 }
];

const baseOptions = {
  duration: 200,
  easing: 'ease-in',
  fill: 'both'
};

let isForward = true;
let animation = box.animate(keyframes, baseOptions);
animation.pause();

button.addEventListener('click', () => {
  // 取消当前动画(保留fill状态)
  animation.cancel();
  // 根据方向创建新动画
  animation = box.animate(keyframes, {
    ...baseOptions,
    direction: isForward ? 'normal' : 'reverse'
  });
  isForward = !isForward;
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 01:43:17