菜单

动画引擎

相关源文件

动画引擎是 anime.js 的核心组件,负责处理时间、动画更新和渲染。它提供了管理动画、随时间计算值以及高效渲染DOM或JavaScript对象变化的底层架构。本页详细介绍了动画引擎的内部工作原理,包括其计时系统、更新周期和渲染过程。

有关值处理和插值的信息,请参阅值处理系统

Clock 类:计时基础

Clock 类是 anime.js 中所有计时的基础。它被 EngineTimerAnimationTimeline 类继承,从而在整个库中提供一致的计时功能。

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元素应用变换和样式
  • 在不同动画阶段触发相应的回调

渲染过程:

  1. 计算动画的当前绝对时间和相对时间
  2. 确定动画是向前还是向后运行
  3. 如果指定,对时间应用缓动
  4. 更新内部动画状态
  5. 对于每个补间(属性动画)
    • 计算进度(0到1)
    • 在起始值和结束值之间进行插值
    • 应用修饰符和缓动
    • 更新目标(DOM、CSS或JavaScript对象)
  6. 触发适当的回调(onUpdate, onRender 等)
  7. 处理动画完成时的完成逻辑

来源: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 769-995

动画引擎流程

下图展示了动画引擎从初始化到渲染的完整流程

性能优化

动画引擎包含几项关键优化:

  1. 链表结构:动画和补间存储在链表中,可实现高效的插入、删除和迭代。

  2. 批处理:

    • CSS变换批量处理并一起应用,以获得更好的性能
    • 属性更新进行分组,以最小化DOM回流
  3. 帧率管理:

    • 引擎遵循配置的FPS,防止不必要的更新
    • 自动适应浏览器的刷新率
    • 如果浏览器无法跟上,则跳过帧
  4. 选择性渲染:

    • 只更新当前帧中需要更改的属性
    • 避免对处于起始值或结束值的属性进行不必要的计算
    • 使用精度控制来最小化不可见变化的计算
  5. 时间缩放:

    • 高效处理不同速度的动画
    • 支持所有动画的全局时间缩放

来源:730-745 984-991

计时系统和模式

引擎支持不同的计时模式来处理各种动画场景

计时系统

  • 根据经过的时间决定是否渲染帧
  • 处理特殊情况,如快进、循环和反向
  • 管理动画状态(开始、完成、暂停)
  • 计算时间轴中子动画的适当时间
  • 支持无限循环和交替方向

来源:329-333 742-756

引擎初始化和生命周期

当 anime.js 加载时,它会创建一个单例 Engine 实例来管理所有动画。此实例:

  1. 用当前时间初始化
  2. 设置默认计时参数
  3. 注册文档可见性处理程序(用于在标签页隐藏时暂停)
  4. 在创建第一个动画之前保持休眠状态
  5. 在需要时自动唤醒,在没有活动动画时自动关闭

引擎维护自己的活动动画列表,并根据需要自动调节其活动,即使对于长时间运行的应用程序也具有内存效率。

来源:457-467 475-477

总结

anime.js 中的动画引擎

  1. 通过 Clock 类层次结构提供精确的计时控制
  2. 使用 Engine 类高效管理动画更新
  3. 使用 render()tick() 函数处理渲染和值计算
  4. 将属性动画表示为补间的链表
  5. 利用批量处理和选择性渲染等优化来提升性能
  6. 支持复杂的动画行为,包括循环、反向和交替

这种引擎架构使 anime.js 能够提供流畅、高效的动画,开销极小,同时支持广泛的动画功能。