第十一章:Web Animations API——掌控动画的终极武器
当 CSS 动画无法满足复杂交互需求时,Web Animations API(WAAPI) 就是你的答案。
它结合了 CSS 动画的性能优势与 JavaScript 的强大控制力,让你能精确操控每一帧动画,实现以往需要 jQuery 或第三方库才能完成的效果。
本章将带你从零掌握 WAAPI,并构建一个动态加载指示器实战案例。
1. Web Animations API 的核心优势
| 对比项 | CSS 动画 | Web Animations API |
|---|---|---|
| 控制力 | 有限(依赖类名切换) | ✅ 极强(play, pause, reverse, currentTime) |
| 性能 | 好(GPU 加速) | ✅ 更好(直接操作渲染层) |
| 逻辑集成 | 弱(需 JS 驱动类名) | ✅ 强(动画即代码) |
| 动态性 | 静态关键帧 | ✅ 可运行时生成动画 |
| 浏览器支持 | 所有现代浏览器 | 现代浏览器(> Chrome 36, Firefox 48) |
✅ 适用场景:
- 游戏、数据可视化
- 复杂交互动画序列
- 需要实时控制的动画(如拖拽反馈)
2. 使用 JavaScript 控制 CSS 动画的局限
传统方式通过添加/移除类名来触发动画:
javascript
element.classList.add('fade-in');问题:
- 无法精确控制播放状态
- 难以同步多个动画
- 无法动态修改动画参数
而 WAAPI 直接在 JavaScript 中定义和控制动画,彻底解决这些问题。
3. 基本用法:创建与控制动画
① 创建动画实例:new Animation()
javascript
const animation = new Animation(
// 关键帧(Keyframes)
[
{ transform: 'translateX(0px)', opacity: 1 },
{ transform: 'translateX(100px)', opacity: 0 }
],
// 动画选项(AnimationEffectTiming)
{
duration: 1000, // 持续时间(ms)
easing: 'ease-in-out', // 缓动函数
iterations: Infinity, // 循环次数(infinite)
delay: 200 // 延迟
}
);② 绑定到元素并控制播放
javascript
// 将动画绑定到 DOM 元素
animation.effect.target = document.querySelector('.box');
// 控制动画
animation.play(); // 播放
animation.pause(); // 暂停
animation.reverse(); // 反向播放
// 高级控制
animation.currentTime = 500; // 跳转到 500ms
animation.playbackRate = 2; // 2倍速播放③ 监听动画事件
javascript
animation.addEventListener('finish', () => {
console.log('动画结束!');
});
animation.addEventListener('cancel', () => {
console.log('动画被取消');
});4. 实战案例:构建一个动态加载指示器
需求
- 三个圆点依次脉冲放大
- 可随时暂停/恢复
- 支持速度调节
HTML 结构
html
<div class="loader">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
<button id="toggle">暂停/播放</button>
<input type="range" id="speed" min="0.5" max="3" step="0.5" value="1">JavaScript 实现
javascript
const dots = document.querySelectorAll('.dot');
const toggleBtn = document.getElementById('toggle');
const speedControl = document.getElementById('speed');
// 存储所有动画实例
const animations = [];
// 为每个圆点创建脉冲动画
dots.forEach((dot, index) => {
const pulse = new KeyframeEffect(
dot,
[
{ transform: 'scale(1)', opacity: 0.5 },
{ transform: 'scale(1.5)', opacity: 1 },
{ transform: 'scale(1)', opacity: 0.5 }
],
{
duration: 800,
delay: index * 200, // 错开播放
iterations: Infinity,
easing: 'cubic-bezier(0.4, 0, 0.6, 1)'
}
);
const animation = new Animation(pulse);
animations.push(animation);
animation.play(); // 立即开始
});
// 控制播放/暂停
toggleBtn.addEventListener('click', () => {
const running = animations[0].playState === 'running';
animations.forEach(anim => {
running ? anim.pause() : anim.play();
});
});
// 调节速度
speedControl.addEventListener('input', (e) => {
const rate = parseFloat(e.target.value);
animations.forEach(anim => {
anim.playbackRate = rate;
});
});CSS 样式(仅基础样式)
css
.loader {
display: flex;
gap: 10px;
align-items: center;
}
.dot {
width: 12px;
height: 12px;
background: #007bff;
border-radius: 50%;
}5. 性能与兼容性
- 性能:WAAPI 直接与浏览器渲染引擎通信,避免了 CSSOM 的开销,性能优于
classList操作。 - 兼容性:
- 现代浏览器支持良好
- 老旧浏览器可使用 polyfill
结语:动画的未来在 JavaScript
Web Animations API 让你从“声明式”动画迈向“编程式”动画。
它不仅是 CSS 动画的替代品,更是构建复杂交互应用的基石。
当你需要:
- 精确控制动画时间线
- 动态生成动画
- 与用户输入实时同步
WAAPI 就是你最强大的工具。
下一章,我们将进入“响应式设计进阶:容器查询(Container Queries)与视口单位”。