animation worklet 中的 animate() 是继承自 workletanimation 的类必须实现的实例方法,用于合成线程每帧计算并调用 effect.setkeyframes() 更新可合成属性。

animate() 方法根本不在 Animation Worklet 里
你找不到 animate() 方法,因为它压根不是 Animation Worklet 的 API。Animation Worklet 中的类必须继承自 WorkletAnimation(或旧版 Animator),并实现一个名为 animate(currentTime, effect) 的实例方法——注意:这是 worklet 模块内部类的方法,不是 DOM 元素上的 element.animate()。
常见错误是把主线程的 element.animate() 和 worklet 类里的 animate() 混为一谈。前者是触发动画的入口,后者是每帧被合成线程调用的纯计算函数,二者运行环境、参数、用途完全不同。
-
element.animate()在主线程调用,返回Animation实例,仅用于绑定 timeline 和 effect - worklet 类中的
animate()在合成线程执行,无法访问 DOM,只能读currentTime和写effect.setKeyframes() - 如果你在 worklet 文件里写了
element.animate(...),会直接报ReferenceError: element is not defined
真正能跑在合成线程的 animate() 长什么样
它是一个无副作用、只读输入、只写输出的纯函数。下面这个最小可运行示例展示了标准结构:
registerAnimator('spin', class {
animate(currentTime, effect) {
const t = (currentTime % 2000) / 2000; // 归一化时间,防浮点累积
const deg = t * 360;
effect.setKeyframes([{
transform: `rotate(${deg}deg)`
}]);
}
});
关键点:
- 必须用
effect.setKeyframes()替换整个关键帧数组,不能修改原 keyframes 对象 - 只支持
transform、opacity、filter等可合成属性;写left或width无效且不报错 - 不能调用
console.log、Date.now()、Math.random()(部分浏览器禁用)等非确定性操作 - 所有数学运算建议用整数或预计算查表,避免每帧重复开方、sin/cos
为什么 animate() 没生效?检查这三件事
即使代码语法正确,animate() 也极可能静默失败。90% 的问题出在这三个环节:
- 没调用
CSS.animationWorklet.addModule('./animator.js')—— 缺少这句,registerAnimator完全不会注册,也不会报错 - 主线程创建
Animation时没传timeline——animate()依赖 timeline 提供时间信号,传{}或省略会导致它永不调用 - 绑定的
KeyframeEffect初始 keyframes 是空对象{},但 worklet 内又没调用setKeyframes()—— 合成器无目标属性可更新,动画“存在但不可见”
典型安全写法:
const effect = new KeyframeEffect(
elem,
{}, // 空对象,由 worklet 动态填充
{ duration: Infinity, fill: 'forwards' }
);
const anim = new Animation(effect, scrollTimeline); // 必须带 timeline
anim.play();
别指望用 animate() 更新自定义 CSS 属性
你想通过 effect.setKeyframes([{ '--my-attr': 0.5 }]) 来驱动 @property 动画?不行。Animation Worklet 不支持写入自定义属性,只认硬编码的可合成 CSS 属性名。
如果需要基于自定义属性做插值逻辑,唯一合法路径是:
- 主线程用
CSS.registerProperty()注册--my-attr - 用标准
element.animate([{ '--my-attr': 0 }, { '--my-attr': 1 }], ...)触发 Web Animations API 动画 - 把插值计算逻辑放在
onupdate回调里(主线程),或用calc()+@keyframes表达式(CSS 层)
Animation Worklet 的 animate() 方法只干一件事:在合成线程里算出下一帧的 transform 值,然后喂给合成器。它不是通用 JS 执行沙盒,也不是 CSS 属性代理器。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











