7.2 Web Animations API
Web Animations API(简称 WAAPI)是 W3C 标准化的原生 JavaScript 动画接口,它将 CSS 动画、SVG 动画的底层能力统一暴露给 JavaScript,既保留了 CSS 动画的 GPU 加速、合成线程渲染的性能优势,又具备 JavaScript 的动态性与可控性。
它弥补了 CSS 动画难以动态传参、无法实时控制播放流程的不足,是复杂交互动画、动态业务动效的标准实现方案。
7.2.1 element.animate() 基础用法
element.animate()是 WAAPI 的核心入口方法,用于在 DOM 元素上快速创建并播放动画,直接传入关键帧与配置参数即可生成动画实例,无需预定义 CSS 规则。
一、核心语法
const animation = element.animate(keyframes, options);
- 参数1:keyframes:动画关键帧集合,定义动画各阶段的样式状态
- 参数2:options:动画配置参数,控制时长、次数、缓动等全局行为
- 返回值:
Animation实例对象,用于后续的播放控制与状态监听
二、关键帧的两种写法
1. 数组形式(多帧完整写法)
数组中每个对象对应一个关键帧,浏览器自动均匀分配帧的时间位置,适合 2 帧以上的复杂动画。
const keyframes = [ { opacity: 0, transform: 'translateY(30px)' }, // 起始帧(0%) { opacity: 1, transform: 'translateY(0)' } // 结束帧(100%) ];也支持通过offset属性手动指定帧的百分比位置:
const keyframes = [ { opacity: 0, offset: 0 }, { opacity: 0.5, offset: 0.3 }, { opacity: 1, offset: 1 } ];2. 对象形式(两帧简写)
仅需起始与结束两个状态时,可直接传入对象,浏览器自动解析为两帧动画,写法更简洁。
const keyframes = { opacity: [0, 1], transform: ['translateY(30px)', 'translateY(0)'] };三、核心配置选项
options为动画全局配置,完整对应 CSS 动画的能力,同时支持更精细的时序控制。
配置项 | 类型 | 说明 | 对应 CSS 属性 |
| number | 单次动画时长,单位毫秒 |
|
| number | 动画延迟播放时间,单位毫秒 |
|
| string | 动画缓动函数 |
|
| number | 播放次数, |
|
| string | 播放方向: |
|
| string | 填充模式: |
|
| number | 动画结束后的延迟时间,单位毫秒 | 无对应 CSS 属性 |
四、基础示例
const box = document.querySelector('.box'); // 创建并播放淡入上移动画 const fadeInAnim = box.animate( [ { opacity: 0, transform: 'translateY(20px)' }, { opacity: 1, transform: 'translateY(0)' } ], { duration: 500, easing: 'ease-out', fill: 'forwards' } );7.2.2 动画控制:暂停、恢复、取消、反转
animate()返回的Animation实例提供了完整的播放控制方法,支持对动画进行实时的暂停、恢复、跳转、反转等操作,这是 WAAPI 相比 CSS 动画最核心的优势。
一、核心控制方法
方法 | 作用 | 说明 |
| 播放动画 | 从当前暂停位置继续播放,或从头开始播放已取消的动画 |
| 暂停动画 | 冻结在当前帧,保留当前播放进度 |
| 取消动画 | 终止动画并重置到初始状态,元素样式恢复到动画前 |
| 反转播放 | 从当前位置反向播放,播放方向翻转 |
| 结束动画 | 直接跳转到动画结束状态,触发 |
二、播放状态属性
通过animation.playState可实时读取动画的当前状态,返回枚举值:
running:正在播放paused:已暂停finished:已完成idle:空闲未播放
三、控制示例
const anim = box.animate([/* 关键帧 */], { duration: 1000 }); // 暂停播放 document.querySelector('#pauseBtn').addEventListener('click', () => { anim.pause(); console.log(anim.playState); // 'paused' }); // 恢复播放 document.querySelector('#playBtn').addEventListener('click', () => { anim.play(); }); // 反转播放 document.querySelector('#reverseBtn').addEventListener('click', () => { anim.reverse(); }); // 取消动画 document.querySelector('#cancelBtn').addEventListener('click', () => { anim.cancel(); });四、finish 与 cancel 的核心区别
finish():直接跳到动画结束帧,保留动画结束后的样式(受 fill 影响),触发finish事件,属于正常结束。cancel():直接终止动画,元素样式恢复到动画开始前的状态,触发cancel事件,属于强制中断。
7.2.3 动画时序与缓动控制
WAAPI 提供了比 CSS 动画更精细的时序控制能力与更灵活的缓动配置,支持精准到毫秒的进度跳转、单帧独立缓动等高级能力。
一、精准时序控制
1. 当前时间读写
通过animation.currentTime可以直接读取或设置动画的当前播放时间(单位毫秒),实现任意进度跳转、进度拖拽等交互,这是 CSS 动画无法实现的能力。
// 获取当前播放进度时间 console.log(anim.currentTime); // 250 // 直接跳转到 500ms 位置 anim.currentTime = 500;2. 首尾延迟控制
除了常规的开始延迟delay,还支持endDelay结束延迟,在动画结束后、触发完成事件前插入等待时间,用于多动画序列的时间对齐。
element.animate(keyframes, { duration: 300, delay: 100, // 开始前延迟100ms endDelay: 200 // 结束后延迟200ms再触发完成事件 });3. 迭代起始点
通过iterationStart可以设置动画从第几次迭代的什么位置开始播放,支持非整数次迭代,适合中途入场的循环动画。
// 无限循环动画,从第2.5次迭代开始播放 element.animate(keyframes, { iterations: Infinity, iterationStart: 2.5 });二、缓动控制
1. 全局缓动
在 options 中配置easing,作用于整个动画的所有关键帧之间,与 CSS 缓动完全兼容。
{ easing: 'cubic-bezier(0.4, 0, 0.2, 1)' // 自定义贝塞尔曲线 }支持所有 CSS 缓动关键字:linear、ease、ease-in、ease-out、ease-in-out,以及steps()阶跃函数。
2. 单帧独立缓动
WAAPI 支持给单个关键帧设置easing,缓动作用于当前帧到下一帧之间,实现同一段动画中不同阶段不同的运动曲线,灵活性远超 CSS 动画。
const keyframes = [ { transform: 'translateX(0)', easing: 'ease-in' }, // 0%-50% 加速 { transform: 'translateX(100px)', easing: 'ease-out' }, // 50%-100% 减速 { transform: 'translateX(200px)' } ];三、动画事件
WAAPI 提供 Promise 化的事件与传统事件两种方式,监听动画生命周期节点:
// Promise 方式:动画完成回调 anim.finished.then(() => { console.log('动画播放完成'); }); // 传统事件方式 anim.addEventListener('finish', () => { console.log('动画结束'); }); anim.addEventListener('cancel', () => { console.log('动画被取消'); });四、适用场景
- 需要动态控制播放、暂停、进度的交互动画
- 参数动态计算的业务动效,如根据数据决定动画幅度
- 多动画序列编排、精准时间对齐的复杂动效
- 无法通过 CSS 类切换实现的动态生成动画