动画引擎
相关源文件
动画引擎是 anime.js 的核心组件,负责处理时间、动画更新和渲染。它提供了管理动画、随时间计算值以及高效渲染DOM或JavaScript对象变化的底层架构。本页详细介绍了动画引擎的内部工作原理,包括其计时系统、更新周期和渲染过程。
有关值处理和插值的信息,请参阅值处理系统。
Clock 类:计时基础
Clock 类是 anime.js 中所有计时的基础。它被 Engine、Timer、Animation 和 Timeline 类继承,从而在整个库中提供一致的计时功能。
Clock 类
- 高精度跟踪时间
- 管理帧率和播放速度
- 根据配置的帧率决定何时渲染帧
- 维护内部计时状态,包括
_currentTime、_elapsedTime 和 _scheduledTime 等属性
关键方法
requestTick(time):根据经过的时间确定是否应渲染新帧
computeDeltaTime(time):计算帧之间的时间
来源:lib/anime.esm.js673-757
Engine 类:动画循环管理器
Engine 类扩展了 Clock,并作为所有动画的中心管理器。它维护一个活动动画列表并运行主动画循环。
Engine 实例
- 使用
requestAnimationFrame(在浏览器中)或 setImmediate(在 Node.js 中)控制全局动画循环
- 使用链表结构管理活动动画列表
- 计算每个动画的合适时间
- 具有暂停和恢复整个动画系统的方法
- 当浏览器标签页隐藏时自动暂停(可配置)
主要功能
- 库加载时自动创建的单例实例
- 惰性初始化——仅在需要时启动动画循环
- 自清理——自动移除已完成的动画
- 可调整的精度和时间单位(毫秒或秒)
来源:lib/anime.esm.js391-467 lib/anime.esm.js468-503
渲染系统:从时间到视觉变化
渲染系统围绕两个关键函数构建:render() 和 tick()。这些函数处理将时间值转换为视觉变化的过程。
渲染函数
render() 函数是动画系统的核心,负责处理:
- 时间计算和标准化
- 迭代(循环)的进度跟踪
- 反向和交替行为
- 确定要更新的补间动画
- 计算每个属性的插值
- 向DOM元素应用变换和样式
- 在不同动画阶段触发相应的回调
渲染过程:
- 计算动画的当前绝对时间和相对时间
- 确定动画是向前还是向后运行
- 如果指定,对时间应用缓动
- 更新内部动画状态
- 对于每个补间(属性动画)
- 计算进度(0到1)
- 在起始值和结束值之间进行插值
- 应用修饰符和缓动
- 更新目标(DOM、CSS或JavaScript对象)
- 触发适当的回调(onUpdate, onRender 等)
- 处理动画完成时的完成逻辑
来源:lib/anime.esm.js770-1042
Tick 函数
tick() 函数协调动画及其子动画的渲染
- 管理动画的父子关系(用于时间轴)
- 将适当的时间值传递给每个子动画
- 处理特殊情况,如循环和反向播放
- 汇总子动画的渲染结果
- 确定所有子动画何时完成
来源:lib/anime.esm.js1052-1124
补间系统:属性动画管理
补间系统负责对单个属性进行动画处理,是动画层次结构的最低层。
一个补间
- 表示单个属性的动画
- 存储目标对象和属性名称
- 包含起始值和结束值
- 知道如何分解复杂值(颜色、包含多个数字的字符串)
- 有自己的缓动和修改函数
- 理解不同的合成模式(替换、混合)
补间系统处理多种属性类型
- 简单数字(JavaScript对象属性)
- 带单位的CSS属性(px, em, %, 等)
- 颜色(hex, rgb, rgba, hsl, hsla)
- 包含多个数字的复杂字符串
- 变换(平移、旋转、缩放等)
- SVG属性
- CSS变量
每个补间都以双向链表结构链接,以实现高效的迭代和内存管理。
来源:lib/anime.esm.js108-158
动画引擎流程
下图展示了动画引擎从初始化到渲染的完整流程
动画引擎包含几项关键优化:
-
链表结构:动画和补间存储在链表中,可实现高效的插入、删除和迭代。
-
批处理:
- CSS变换批量处理并一起应用,以获得更好的性能
- 属性更新进行分组,以最小化DOM回流
-
帧率管理:
- 引擎遵循配置的FPS,防止不必要的更新
- 自动适应浏览器的刷新率
- 如果浏览器无法跟上,则跳过帧
-
选择性渲染:
- 只更新当前帧中需要更改的属性
- 避免对处于起始值或结束值的属性进行不必要的计算
- 使用精度控制来最小化不可见变化的计算
-
时间缩放:
- 高效处理不同速度的动画
- 支持所有动画的全局时间缩放
来源:
计时系统和模式
引擎支持不同的计时模式来处理各种动画场景
计时系统
- 根据经过的时间决定是否渲染帧
- 处理特殊情况,如快进、循环和反向
- 管理动画状态(开始、完成、暂停)
- 计算时间轴中子动画的适当时间
- 支持无限循环和交替方向
来源:
引擎初始化和生命周期
当 anime.js 加载时,它会创建一个单例 Engine 实例来管理所有动画。此实例:
- 用当前时间初始化
- 设置默认计时参数
- 注册文档可见性处理程序(用于在标签页隐藏时暂停)
- 在创建第一个动画之前保持休眠状态
- 在需要时自动唤醒,在没有活动动画时自动关闭
引擎维护自己的活动动画列表,并根据需要自动调节其活动,即使对于长时间运行的应用程序也具有内存效率。
来源:
总结
anime.js 中的动画引擎
- 通过
Clock 类层次结构提供精确的计时控制
- 使用
Engine 类高效管理动画更新
- 使用
render() 和 tick() 函数处理渲染和值计算
- 将属性动画表示为补间的链表
- 利用批量处理和选择性渲染等优化来提升性能
- 支持复杂的动画行为,包括循环、反向和交替
这种引擎架构使 anime.js 能够提供流畅、高效的动画,开销极小,同时支持广泛的动画功能。