Skip to content

Animejs 开源项目解读

项目信息

  • 项目名称:Animejs
  • 项目描述: Animejs 一个零依赖、模块化、高性能的 JavaScript 动画引擎,通过 Clock → Timer → Animation/Timeline 的分层继承架构,提供 CSS/SVG/DOM/JS Object 的统一动画 API。
  • 项目地址:https://github.com/juliangarnier/anime
  • 官方文档:https://animejs.com

解决的核心痛点

  1. Web 动画 API 碎片化:CSS Transition/Animation、WAAPI、SVG 动画、Canvas/WebGL 各自有不同的接口和控制方式,Anime.js 提供统一 API 屏蔽底层差异
  2. 复杂动画编排困难:原生 API 缺乏时间线编排能力,Anime.js 内建 Timer → Animation → Timeline 的分层模型
  3. 高性能与代码量平衡:通过模块化 ESM 导出和零运行时依赖的设计,实现功能完备但按需加载的架构

核心架构速览

功能扩展层 (SVG / Text / WAAPI / Events / Easings / ...)

动画抽象层 (Timer → JSAnimation / Timeline / Draggable)

核心引擎层 (Clock / Engine / Render / Values)

基础设施层 (Consts / Helpers / Globals)

1. 项目概览

1.1 项目定位与核心价值

Anime.js 是一个快速、多功能、轻量级的 JavaScript 动画引擎库,提供简洁而强大的 API,支持 CSS 属性、SVG、DOM 属性和 JavaScript 对象动画。

解决的核心痛点

  1. Web 动画 API 碎片化:CSS Transition/Animation、WAAPI、SVG 动画、Canvas/WebGL 各自有不同的接口和控制方式,Anime.js 提供统一 API 屏蔽底层差异
  2. 复杂动画编排困难:原生 API 缺乏时间线编排能力,Anime.js 内建 Timer → Animation → Timeline 的分层模型
  3. 高性能与代码量平衡:通过模块化 ESM 导出和零运行时依赖的设计,实现功能完备但按需加载的架构

1.2 目标用户与使用场景

  • Web 前端开发者:需要在项目中快速添加复杂交互动画
  • 创意设计师/开发者:需要制作高视觉效果的交互动画
  • 框架无关:可在任何 Web 项目中使用 (Vanilla JS / React / Vue 等)

1.3 核心技术亮点

特性说明
零运行时依赖不依赖任何第三方库
模块化架构14 个独立可导入子模块,Tree Shaking 友好
统一动画模型CSS/DOM/SVG/JS Object 统一 API
高性能渲染rAF 主循环 + 链表遍历 + 帧节流
值系统自动识别 NUMBER/UNIT/COLOR/COMPLEX 四种类型
合成系统replace/blend/none 三种 Tween 冲突处理
Promise 支持.then() 方法支持 await 语法
丰富扩展SVG 描边/变形/路径、文本分割/乱序、拖拽、滚动驱动

1.4 技术栈与选型对比

层面技术选型权衡考量
语言JavaScript ESMTree Shaking 友好,无编译步骤
类型JSDoc + TS .d.ts保持 JS 开发体验同时提供完整类型
构建RollupESM/CJS/UMD/IIFE 多格式输出
架构分层继承 (Clock→Timer→Animation)复用时间管理逻辑,代价是降低灵活性
渲染自建 rAF 循环精确控制每帧,支持复杂编排
WAAPI可选集成模块保留高性能原生动画路径

2. 整体架构设计

2.1 架构概述

Anime.js V4 采用 分层继承架构,从底层到顶层分为四个层次:

  • 基础设施层 (Infrastructure):环境检测、浏览器 API 适配、常量定义
  • 核心引擎层 (Core Engine):Clock 时间系统、Render 渲染循环、Values 值处理系统、全局 Engine 单例
  • 动画抽象层 (Animation Abstractions):Timer 基类 → Animation(单动画)/Timeline(时间线编排)/Draggable(拖拽)
  • 功能扩展层 (Extensions):Easings 缓动、SVG 工具、Text 文本、WAAPI 桥接、Events 事件、Scope 作用域

2.2 整体架构图

text
+=======================================================================+
|                      功能扩展层 (Extensions)                           |
|  +----------+  +----------+  +----------+  +-----------+             |
|  |  SVG     |  |  Text    |  |  WAAPI   |  |  Events   |             |
|  | drawable |  | split    |  | waapi()  |  | scroll    |             |
|  | morphTo  |  | scramble |  | animate  |  | observer  |             |
|  | motion   |  |          |  |          |  |           |             |
|  +----+-----+  +----+-----+  +----+-----+  +-----+-----+             |
|       |             |             |               |                    |
|  +----+-----+  +----+-----+  +----+-----+  +-----+-----+             |
|  | Layout   |  | Easings  |  | Scope    |  | Utils     |             |
|  | animate  |  | eases    |  | scope()  |  | stagger   |             |
|  | layout   |  | spring   |  | refresh  |  | random    |             |
|  |          |  | cubic-   |  | revert   |  | chainable |             |
|  |          |  | bezier   |  |          |  |           |             |
|  +----------+  +----------+  +----------+  +-----------+             |
+=======================================================================+
                                | (import)
                                v
+=======================================================================+
|                    动画抽象层 (Animation Abstractions)                  |
|                                                                       |
|  +-----------------------------------------------------------------+ |
|  |                   Timer (继承 Clock)                              | |
|  |  - 生命周期: began/completed/paused                              | |
|  |  - 时间控制: seek/reset/restart/reverse/alternate                | |
|  |  - 子节点: _head/_tail 链表管理                                   | |
|  |  - 回调: onBegin/onUpdate/onLoop/onComplete                      | |
|  |  - Promise: .then() 支持                                         | |
|  +-------+-------------------+-------------------+-----------+------+ |
|          |                   |                   |           |         |
|          v                   v                   v           v         |
|  +---------------+  +----------------+  +----------------+  +-------+ |
|  | JSAnimation   |  | Timeline       |  | Draggable      |  | Anim- | |
|  | (Animation)   |  | (时间线编排)    |  | (拖拽交互)      |  | atable| |
|  | - _tweens链表 |  | - _children    |  | - snap/x/y     |  | (CSS) | |
|  | - tween合成   |  |   位置计算      |  | - inertia      |  +-------+ |
|  | - 值分解      |  | - add()/set()  |  | - modifiers    |           | |
|  +---------------+  +----------------+  +----------------+           | |
+=======================================================================+
                                | (继承/调用)
                                v
+=======================================================================+
|                     核心引擎层 (Core Engine)                           |
|                                                                       |
|  +------------------+  +------------------+  +--------------------+  |
|  | Clock            |  | Engine (单例)    |  | Render / tick()    |  |
|  | - _currentTime   |  | - _lastTickTime  |  | - render() 核心    |  |
|  | - _fps/_speed     |  | - reqId (rAF)   |  |   渲染循环         |  |
|  | - requestTick()  |  | - _head (链表)   |  | - tick() 子节点    |  |
|  | - deltaTime      |  | - wake()        |  |   递归遍历         |  |
|  +------------------+  +------------------+  +--------------------+  |
|                                                                       |
|  +------------------+  +------------------+  +--------------------+  |
|  | Values           |  | Styles           |  | Transforms         |  |
|  | - decomposeValue |  | - sanitizeProp   |  | - decomposeTransform| |
|  | - composeColor   |  | - revertValues   |  | - buildString      |  |
|  | - composeComplex |  |                  |  |                    |  |
|  +------------------+  +------------------+  +--------------------+  |
|                                                                       |
|  +------------------+  +------------------+  +--------------------+  |
|  | Units            |  | Colors           |  | Targets            |  |
|  | - convertUnit    |  | - parse/rgb/hsl  |  | - registerTargets  |  |
|  +------------------+  +------------------+  +--------------------+  |
+=======================================================================+
                                | (依赖)
                                v
+=======================================================================+
|                   基础设施层 (Infrastructure)                          |
|  +------------------+  +------------------+  +--------------------+  |
|  | Consts           |  | Helpers          |  | Globals            |  |
|  | - isBrowser      |  | - now()          |  | - globals.timeScale|  |
|  | - tweenTypes     |  | - addChild()     |  | - defaults配置     |  |
|  | - valueTypes     |  | - forEachChild() |  | - scope.current    |  |
|  | - tickModes      |  | - lerp/clamp     |  |                    |  |
|  +------------------+  +------------------+  +--------------------+  |
+=======================================================================+

分层职责说明

层次核心职责关键技术
基础设施层环境检测、常量枚举、工具函数、全局状态浏览器/Node 双环境适配
核心引擎层时间系统、帧调度、值解析、渲染循环rAF 主循环、链表遍历
动画抽象层Timer 基类、Animation、Timeline 编排、Draggable 交互类继承、双向链表
功能扩展层SVG 动画、文本特效、WAAPI 桥接、缓动函数可选的独立模块

2.3 目录结构

shell
anime/
├── src/                                   # 【核心基建】源代码主目录 - 61个JS文件,~37K行
   ├── index.js                           # 【核心基建】全局入口 - re-export 14个模块的所有公共API

   ├── core/                              # 【核心基建】核心引擎基础设施层 - 11个文件
   ├── clock.js                       # 【核心基建】Clock 时间基类 - 所有定时实体的父类
   ├── consts.js                      # 【核心基建】全局常量 - 环境检测、枚举(tweenTypes/valueTypes/tickModes/compositionTypes)、浏览器DOM符号
   ├── colors.js                      # 【核心基建】颜色处理 - 颜色解析与格式化
   ├── globals.js                     # 【核心基建】全局状态 - globalVersions版本数组、defaults默认参数、scope管理
   ├── helpers.js                     # 【工具集】通用工具 - now()/clamp()/lerp()/addChild()/forEachChildren()/mergeObjects()等
   ├── render.js                      # 【核心基建】渲染核心 - render()计算单帧Tween值写入目标、tick()递归处理子节点(Timeline)
   ├── styles.js                      # 【核心基建】样式处理 - sanitizePropertyName()属性名标准化(如line-height→lineHeight)、revertValues()恢复
   ├── targets.js                     # 【核心基建】目标管理 - registerTargets()、parseTargets()加载DOM元素/NodeList/对象
   ├── transforms.js                  # 【核心基建】Transform处理 - CSS Transform分解为独立属性、buildTransformString()重建
   ├── units.js                       # 【核心基建】单位处理 - convertValueUnit()单位转换(px↔rem↔vh等)
   └── values.js                      # 【核心基建】值系统 - decomposeRawValue()分解值类型、composeColorValue()/composeComplexValue()合成、getRelativeValue()相对值

   ├── timer/                             # 【核心基建】Timer模块 - 动画引擎的核心时间抽象
   ├── index.js                       # 【核心基建】导出 createTimer() 工厂函数
   └── timer.js                       # 【核心基建】Timer类(继承Clock) - 生命周期管理、seek/pause/resume/reverse/stretch、Promise支持

   ├── animation/                         # 【业务模块】Animation模块 - 属性动画实现
   ├── index.js                       # 【业务模块】导出 animate()、createAnimations()、stagger()
   ├── animation.js                   # 【业务模块】JSAnimation类(继承Timer) - Tween链表创建、值解析与写入
   ├── composition.js                 # 【核心基建】Tween合成系统 - composeTween()处理replace/blend/none、WeakMap存储target+property→Tween映射
   └── additive.js                    # 【核心基建】加法动画 - 相对值叠加(additive)、animation.add()累加

   ├── timeline/                          # 【业务模块】Timeline模块 - 多动画时间编排
   ├── index.js                       # 【业务模块】导出 createTimeline()
   ├── timeline.js                    # 【业务模块】Timeline类(继承Timer) - add()/set()/sync()/remove()、子动画链表遍历渲染
   └── position.js                    # 【工具集】位置解析 - parseTimelinePosition()处理绝对/相对/标签偏移

   ├── easings/                           # 【核心基建】缓动函数系统 - 8种缓动类型
   ├── index.js                       # 【核心基建】导出 parseEase() 统一缓动解析入口
   ├── none.js                        # 【核心基建】无缓动恒等函数
   ├── eases/                         # 【核心基建】标准Penner缓动集 - in/out/inOut × Quad/Cubic/Quart/Quint/Sine/Expo/Circ/Back/Elastic/Bounce
   ├── index.js                   # 【核心基建】预定义缓动函数导出
   └── parser.js                  # 【核心基建】缓动名称→函数解析器
   ├── linear/ ── index.js           # 【核心基建】linear()/none() 线性缓动
   ├── steps/ ── index.js            # 【核心基建】steps() 阶梯缓动
   ├── irregular/ ── index.js        # 【核心基建】irregular() 自定义关键帧缓动(如[0, 0.2, 0.8, 1])
   ├── cubic-bezier/ ── index.js     # 【核心基建】cubicBezier() CSS贝塞尔缓动
   └── spring/ ── index.js           # 【核心基建】spring() 物理弹簧缓动(mass/stiffness/damping)

   ├── engine/                            # 【核心基建】全局动画引擎
   ├── index.js                       # 【核心基建】导出 engine 全局单例
   └── engine.js                      # 【核心基建】Engine类(继承Clock) - rAF主循环、Timer链表管理、全局timeScale/pause控制

   ├── animatable/                        # 【业务模块】Animatable - CSS computed style动画
   ├── index.js                       # 【业务模块】导出 animateComputedStyle()等
   └── animatable.js                  # 【业务模块】Animatable类(继承Timer) - 驱动CSS过渡/WAAPI动画

   ├── draggable/                         # 【业务模块】Draggable - 拖拽交互
   ├── index.js                       # 【业务模块】导出 createDraggable()
   └── draggable.js                   # 【业务模块】Draggable类(继承Timer) - 鼠标/触摸拖拽、snap吸附、inertia惯性、modifiers修饰

   ├── scope/                             # 【核心基建】Scope - 动画生命周期管理
   ├── index.js                       # 【核心基建】导出 createScope()
   └── scope.js                       # 【核心基建】Scope类 - register()/refresh()/revert()/pause()批量控制

   ├── events/                            # 【业务模块】Events - 滚动驱动
   ├── index.js                       # 【业务模块】导出 createScrollObserver()
   └── scroll.js                      # 【业务模块】ScrollObserver - 滚动位置→动画时间的映射、link()/unlink()

   ├── layout/                            # 【业务模块】Layout - 布局动画
   ├── index.js                       # 【业务模块】导出 animateLayout()
   └── layout.js                      # 【业务模块】FLIP布局动画实现 - First/Last/Invert/Play

   ├── svg/                               # 【业务模块】SVG - 矢量图形动画专属
   ├── index.js                       # 【业务模块】导出 createDrawable()、createMorphTo()、createMotionPath()
   ├── drawable.js                    # 【业务模块】Drawable - SVG描边动画(stroke-dashoffset/stroke-dasharray)
   ├── helpers.js                     # 【工具集】SVG工具 - 路径解析、长度计算
   ├── morphto.js                     # 【业务模块】MorphTo - SVG path d属性形状变换
   └── motionpath.js                  # 【业务模块】MotionPath - SVG路径跟随运动

   ├── text/                              # 【业务模块】Text - 文本动画特效
   ├── index.js                       # 【业务模块】导出 splitText()、scrambleText()
   ├── split.js                       # 【业务模块】SplitText - 文本按字符/单词/行分割为独立DOM元素
   └── scramble.js                    # 【业务模块】ScrambleText - 字符乱序切换动画

   ├── waapi/                             # 【业务模块】WAAPI - Web Animations API桥接
   ├── index.js                       # 【业务模块】导出 waapi.animate()
   ├── waapi.js                       # 【业务模块】WAAPIAnimation(继承Timer) - 封装element.animate()
   └── composition.js                 # 【业务模块】WAAPI Tween合成管理

   ├── utils/                             # 【工具集】通用工具集 - 7个独立工具
   ├── index.js                       # 【工具集】导出所有工具函数
   ├── chainable.js                   # 【工具集】链式调用辅助 - 支持 obj.x(100).y(200).duration(1000) 语法
   ├── number.js                      # 【工具集】数值工具 - 数值格式化、精度处理
   ├── random.js                      # 【工具集】随机工具 - random()/randomInt() 随机值生成
   ├── stagger.js                     # 【工具集】交错延迟 - stagger()按元素索引计算延迟
   ├── target.js                      # 【工具集】目标查找 - querySelectorAll()封装、NodeList→Array
   └── time.js                        # 【工具集】时间工具 - 时间格式化转换

   └── types/                             # 【配置】JSDoc类型定义文件
       └── index.js                       # 【配置】全局@typedef类型 - TimerParams/AnimationParams/Tween/Target等,构建时提取注入bundle头部

├── dist/                                  # 【配置】构建产物
   ├── modules/                           # 【配置】ESM + CJS 模块输出 (preserveModules)
   └── bundles/                           # 【配置】UMD + ESM 打包输出 (anime.*.js)

├── examples/                              # 【配置】78个示例页面 (官方示例)
├── tests/                                 # 【质量保证】测试套件 (120个文件,Mocha + Chai)
   ├── index.html                         # 【质量保证】浏览器测试入口
   └── suites/                            # 【质量保证】测试用例目录 (浏览器 + Node.js)

├── assets/                                # 【配置】仓库静态资源 (Logo、GIF、赞助商图片)
├── .github/                               # 【配置】GitHub CI/CD配置
├── package.json                           # 【配置】NPM包配置 - v4.4.1, 18个子路径导出, 零运行时依赖
├── rollup.config.js                       # 【配置】Rollup构建配置 - ESM/CJS/UMD多格式输出
├── tsconfig.json                          # 【配置】TypeScript主配置
├── tsconfig.types.json                    # 【配置】类型声明生成配置 - 输出dist/modules/**/*.d.ts
├── CONTRIBUTING.md                        # 【配置】贡献指南
├── LICENSE.md                             # 【配置】MIT开源协议
└── README.md                              # 【配置】英文项目主文档

3. 模块依赖与调用关系

3.1 全局入口与核心路由

逻辑说明src/index.js 作为全局入口,将所有 14 个模块的子入口聚合导出。每个模块有自己的 index.js,对外暴露特定的公共 API 函数。模块内部通过 core/ 共享基础设施。Engine 是全局单例,负责驱动所有活跃的 Timer 实例。

  • 调用拓扑 (plainText)
text
src/index.js (全局入口 - 14个模块聚合)
 |
 +---> src/timer/index.js --------> createTimer() ────> new Timer(Clock)
 |
 +---> src/animation/index.js -----> animate() ────────> new JSAnimation(Timer)
 |                                   stagger()
 |                                   createAnimations()
 |
 +---> src/timeline/index.js ------> createTimeline() ─> new Timeline(Timer)
 |                                                         |
 |                                                         +--> add() -> new JSAnimation
 |                                                         +--> set() -> new JSAnimation
 |
 +---> src/draggable/index.js -----> createDraggable() ─> new Draggable(Timer)
 |
 +---> src/scope/index.js ---------> createScope() ─────> new Scope()
 |                                   scope.refresh()
 |                                   scope.revert()
 |
 +---> src/engine/index.js --------> engine (全局单例)
 |                                   engine.resume()
 |                                   engine.pause()
 |
 +---> src/events/index.js --------> createScrollObserver()
 |
 +---> src/easings/index.js -------> parseEase()
 |    ├── src/easings/eases/ ------> 预定义缓动函数集
 |    ├── src/easings/cubic-bezier/ -> cubicBezier()
 |    ├── src/easings/spring/ ------> spring()
 |    ├── src/easings/steps/ -------> steps()
 |    ├── src/easings/linear/ ------> linear()
 |    └── src/easings/irregular/ ---> irregular()
 |
 +---> src/svg/index.js -----------> createDrawable()
 |                                   createMorphTo()
 |                                   createMotionPath()
 |
 +---> src/text/index.js -----------> splitText()
 |                                   scrambleText()
 |
 +---> src/layout/index.js ---------> animateLayout()
 |
 +---> src/waapi/index.js ----------> waapi.animate()
 |
 +---> src/animatable/index.js -----> animateComputedStyle()
 |
 +---> src/utils/index.js ----------> stagger()
 |                                   random()
 |                                   chainable()
 |
 +---> src/types/index.js ----------> (JSDoc 类型定义,仅用于类型检查)

3.2 核心业务实体与关联

实体定义

实体说明在系统中的角色
Clock时间基类,管理帧率和播放速率所有可定时实体的基础
Timer动画时间控制器,继承 ClockAnimation/Timeline/Draggable 的基类
Engine全局动画引擎单例,继承 Clock驱动主循环,管理所有活跃 Timer
JSAnimation单次动画,继承 Timer操作 Tween 链表,驱动属性动画
Tween动画单元,表示单个属性的插值包含起止值、缓动、类型信息
Timeline动画时间线,继承 Timer管理多个子 Animation 的时间编排
Draggable拖拽控制器,继承 Timer封装鼠标/触摸交互到动画
Scope作用域管理器批量控制一组动画的生命周期
ScrollObserver滚动观察器将滚动位置映射为动画时间
AnimatableCSS 过渡动画控制器驱动 computed style 过渡

实体引用拓扑 (plainText)

text
[Clock]
  |
  +------ 1 -----> 1 [Engine] (全局单例)
  |
  +------ 1 -----> N [Timer]
                      |
                      +------ 1 -----> N [JSAnimation]
                      |                  |
                      |                  +-- 1 -----> N [Tween] (属性插值单元)
                      |                        |
                      |                        +-- 1 -----> 1 [Composition] (合成模式)
                      |
                      +------ 1 -----> N [Timeline]
                      |                  |
                      |                  +-- 1 -----> N [JSAnimation] (子动画)
                      |
                      +------ 1 -----> N [Draggable]
                      |
                      +------ 1 -----> N [Animatable]

[Engine] 1 -----> N [Timer] (双向链表: _head/_tail)

[Scope] 1 -----> N [Timer] (作用域内注册的动画/时间线)

[ScrollObserver] 1 -----> 1 [Timer] (linked 关联)

[Tween]
  +-- 1 -----> 1 [Target] (DOM元素或JS对象)
  +-- 1 -----> 1 [Ease] (缓动函数)
  +-- 1 -----> 0..1 [Modifier] (值修饰函数)

4. 核心模块详解

模块一:Clock - 时间基类

  • 模块名称:Clock(时间系统)

  • 设计说明:Clock 是所有时间相关实体的最底层基类。它封装了帧率控制(_fps)、播放速率(_speed)、时间计算(requestTickcomputeDeltaTime)和子节点链表管理(_head/_tail)。Clock 不负责渲染,只负责时间调度。通过 requestTick(time) 方法判断当前帧是否需要更新(基于帧率的节流),返回 tickModes.AUTOtickModes.NONE

  • 内部结构图 (plainText)

text
+--------------------------------------------------------+
|                    Clock (时间基类)                      |
|                                                         |
|  属性:                                                   |
|  +------------------------------------+                 |
|  | _currentTime: Number              | 当前绝对时间      |
|  | _startTime: Number                | 起始时间          |
|  | _lastTickTime: Number             | 上次 tick 时间    |
|  | _scheduledTime: Number            | 下次帧预定时间    |
|  | _frameDuration: Number            | 帧持续时间(ms)    |
|  | _fps: Number                      | 帧率              |
|  | _speed: Number                    | 播放速率          |
|  | _head: Tickable|null             | 子节点链表头       |
|  | _tail: Tickable|null             | 子节点链表尾       |
|  +------------------------------------+                 |
|                                                         |
|  方法:                                                   |
|  +------------------------------------+                 |
|  | requestTick(time) -> tickModes    | 帧节流判断       |
|  | computeDeltaTime(time) -> Number  | 计算帧间隔       |
|  +------------------------------------+                 |
+--------------------------------------------------------+

模块二:Timer - 动画时间基类

  • 模块名称:Timer(动画时间基类)

  • 设计说明:Timer 继承 Clock,是 Animation、Timeline、Draggable 的直接基类。它添加了完整的动画生命周期管理:began(开始)、completed(完成)、paused(暂停)。支持 delay、duration、loop(循环)、alternate(交替反向)、reversed(反向播放)。通过 seek()reset()restart()stretch() 等方法实现对时间的精确控制。内建 Promise 支持(.then() 方法),允许开发者 await 动画完成。Timer 还实现了:revert() 回到初始状态并取消、cancel() 取消并从引擎移除、complete() 立即完成。Timer 在构造函数中通过 scope.current?.register(this) 自动注册到当前作用域。

  • 内部结构图 (plainText)

text
+==================================================================+
|                      Timer (继承 Clock)                           |
|                                                                   |
|  +-----------------------------+  +-----------------------------+|
|  |    生命周期状态              |  |     循环控制               ||
|  |  - began: Boolean           |  |  - iterationCount: Number   ||
|  |  - completed: Boolean       |  |  - iterationDuration: Number||
|  |  - paused: Boolean          |  |  - _alternate: Boolean      ||
|  |  - cancelled: Boolean       |  |  - _reversed: Number        ||
|  +-----------------------------+  +-----------------------------+|
|                                                                   |
|  +-----------------------------+  +-----------------------------+|
|  |    回调函数                  |  |     时间控制               ||
|  |  - onBegin                   |  |  - _offset: Number          ||
|  |  - onBeforeUpdate            |  |  - _delay: Number           ||
|  |  - onUpdate                  |  |  - _loopDelay: Number       ||
|  |  - onLoop                    |  |  - _priority: Number        ||
|  |  - onPause                   |  |                             ||
|  |  - onComplete                |  +-----------------------------+|
|  +-----------------------------+                                  |
|                                                                   |
|  +--------------------------------------------------------------+ |
|  |  核心方法                                                     | |
|  |  init() -> this         : 初始化动画参数、fps、speed          | |
|  |  reset() -> this        : 重置到初始状态                       | |
|  |  restart() -> this      : reset + resume                      | |
|  |  seek(time) -> this     : 跳转到指定时间                       | |
|  |  pause() -> this        : 暂停动画                             | |
|  |  resume() -> this       : 恢复播放(添加到Engine链表)          | |
|  |  play() -> this         : 正向播放                             | |
|  |  reverse() -> this      : 反向播放                             | |
|  |  alternate() -> this    : 切换播放方向                         | |
|  |  stretch(newDur) -> this: 拉伸时间                             | |
|  |  cancel() -> this       : 取消动画(从Engine移除)              | |
|  |  revert() -> this       : 回退 + 取消                         | |
|  |  complete() -> this     : 立即完成                             | |
|  |  then(cb) -> Promise    : Promise 化支持 await                | |
|  +--------------------------------------------------------------+ |
+==================================================================+

模块三:Engine - 全局动画引擎

  • 模块名称:Engine(全局动画引擎单例)

  • 设计说明:Engine 是全局唯一的动画引擎实例,继承自 Clock。它使用 requestAnimationFrame(浏览器)或 setImmediate(Node.js)驱动主循环。所有活跃的 Timer 通过双向链表(_head_next/_prev)注册到 Engine 上。每帧 Engine 遍历链表,按优先级排序后调用 tick() 进行渲染。Engine 管理:全局 defaults 配置(影响所有动画)、timeScale 全局时间缩放、pauseOnDocumentHidden(页面隐藏时暂停)、_speed 全局播放速率。

  • 内部结构图 (plainText)

text
+==================================================================+
|                   Engine (全局单例, 继承 Clock)                    |
|                                                                   |
|  +-------------------------------+  +----------------------------+|
|  |  全局配置                     |  |  主循环驱动               ||
|  |  - defaults: DefaultsParams   |  |  - reqId: Number           ||
|  |  - useDefaultMainLoop: Bool   |  |  - _lastTickTime: Number   ||
|  |  - pauseOnDocumentHidden:Bool |  |  - _startTime: Number      ||
|  +-------------------------------+  |  - engineTickMethod: rAF   ||
|                                      |  - engineCancelMethod:cAF ||
|  +-------------------------------+  +----------------------------+|
|  |  链表管理                     |                                |
|  |  - _head: Timer (最高优先级)  |  +----------------------------+|
|  |  - _tail: Timer (最低优先级)  |  |  核心方法                  ||
|  |  - _hasChildren: Boolean      |  |  - requestTick(time)       ||
|  +-------------------------------+  |  - wake() : 唤醒引擎      ||
|                                      |  - pause() : 全局暂停     ||
|  +-------------------------------+  |  - resume() : 全局恢复    ||
|  |  全局时间控制                 |  +----------------------------+|
|  |  - _speed: Number             |                                |
|  |  - timeScale (globals)        |                                |
|  +-------------------------------+                                |
+==================================================================+

模块四:Render 渲染核心

  • 模块名称:Render(渲染/心跳系统)

  • 设计说明render()tick() 是 Anime.js 最核心的两个函数。render() 负责计算单个 Tickable 的当前状态(时间、迭代、方向),然后遍历其 Tweens 链表,为每个 Tween 计算当前值并写入目标(DOM style/attribute 或 JS object)。tick()render() 基础上增加了对子节点的递归处理(针对 Timeline),实现子动画的顺序或反向渲染。两个函数密切配合:Engine 的每帧调用 tick(engine, time),逐级传播到所有活跃的 Timer。

  • 内部结构图 (plainText)

text
+==================================================================+
|                    Render (核心渲染系统)                           |
|                                                                   |
|  tick(tickable, time, muteCallbacks, internalRender, tickMode)    |
|  |                                                                |
|  +-----> 1. render(tickable, time, ...)  渲染自身                 |
|  |         |                                                      |
|  |         +-- 计算: _currentTime, _iterationTime, backwards     |
|  |         +-- 触发: onBegin, onLoop, onBeforeUpdate             |
|  |         +-- 遍历 Tween 链表:                                   |
|  |         |   +-- 计算 tweenProgress (ease)                     |
|  |         |   +-- lerp fromNumber -> toNumber                  |
|  |         |   +-- composeValue: NUMBER|UNIT|COLOR|COMPLEX      |
|  |         |   +-- 写入目标: style/attribute/object            |
|  |         +-- 触发: onUpdate, onRender                         |
|  |         +-- 处理: onComplete (循环/正常结束)                 |
|  |                                                                |
|  +-----> 2. 如果有子节点 (Timeline)                               |
|            |                                                      |
|            +-- 处理循环回调 (onLoop)                              |
|            +-- 遍历子节点 (正向或反向)                            |
|            |   +-- render(child, childTime, ...)                  |
|            +-- 触发 onRender                                     |
|            +-- 处理 onComplete (所有子节点完成)                   |
+==================================================================+

模块五:Values 值处理系统

  • 模块名称:Values(值解析与合成)

  • 设计说明:Values 系统是 Anime.js 能处理多种值类型的关键。它将动画属性值分解为四种基本类型:NUMBER(纯数字)、UNIT(带单位的数字,如 100px)、COLOR(颜色,如 #ff0000rgb()hsl())、COMPLEX(复合值,如 10px 20px)。对于每种类型,系统能从原始值中提取 fromNumbertoNumber,在渲染时通过 lerp 插值后重新合成为目标格式。此外,系统还支持函数值(每帧动态计算)、相对值(+=100 形式)、以及 additive(加法动画叠加)。

  • 内部结构图 (plainText)

text
+==================================================================+
|                  Values (值处理核心)                               |
|                                                                   |
|  输入: 原始值字符串/数字 ("100px", "#ff0", "10px 20px", 42)      |
|  |                                                                |
|  v                                                                |
|  decomposeRawValue(value)                                         |
|  +-- 识别类型: NUMBER | UNIT | COLOR | COMPLEX                   |
|  +-- 提取结构: { numbers, strings, unit, type }                 |
|  |                                                                |
|  v                                                                |
|  decomposeTweenValue(tween)                                       |
|  +-- 解析 from 值 (原始值/函数值/相对值)                         |
|  +-- 解析 to 值                                                   |
|  +-- 处理 modifier (值修饰函数)                                   |
|  +-- 处理 composition (blend/replace/none)                       |
|  +-- 存储: _fromNumber, _toNumber, _unit, _valueType            |
|  |                                                                |
|  v (每帧渲染时)                                                   |
|  |                                                                |
|  lerp(fromNumber, toNumber, progress) -> 插值结果                |
|  |                                                                |
|  v                                                                |
|  合成输出:                                                        |
|  +-- NUMBER: 直接返回值                                          |
|  +-- UNIT: number + unit → "100px"                              |
|  +-- COLOR: composeColorValue() → "rgb(128,255,0)"               |
|  +-- COMPLEX: composeComplexValue() → "10px 20px"               |
+==================================================================+

5. 关键数据流程

场景一:动画从创建到完成的生命周期

  • 场景说明:用户调用 animate() 创建一个动画。动画参数被解析为 Tweens 链表,通过 Engine 注册到主循环。每帧 Engine 唤醒后遍历活跃的 Timer,调用 tick()render() 计算当前帧的 Tween 值并写入目标。当动画到达 duration 时触发 onComplete,从 Engine 链表中移除。这是 Anime.js 最核心的数据流,贯穿所有动画类型。

  • 流转时序图 (Mermaid)

场景二:Timeline 时间线编排

  • 场景说明:用户创建 Timeline,通过 add() 方法添加子动画。每个子动画在 Timeline 上的位置通过位置参数(绝对/相对/标签偏移)计算。Timeline 的 _iterationTime 驱动所有子动画的 render(),子动画按 _offset 对齐到时间线的不同位置。这是实现复杂动画编排的核心机制。

  • 流转时序图 (Mermaid)

场景三:Tween 合成与冲突处理

  • 场景说明:当多个动画同时修改同一目标的同一属性时,需要进行 Tween 合成(composition)。Anime.js 支持三种合成模式:replace(覆盖旧动画)、blend(混合值)、none(独立运行)。合成系统通过 WeakMap 存储 target + property → Tween[] 的映射,在新动画创建时查找冲突并决定行为。

  • 流转时序图 (Mermaid)

6. 接口与契约规范

6.1 核心内部模块契约 (TypeScript)

typescript
// ============================================================
// Clock - 时间基类契约
// ============================================================
interface IClock {
  /** 帧间隔时间 (只读) */
  readonly deltaTime: number;
  /** 当前绝对时间 */
  _currentTime: number;
  /** 起始时间 */
  _startTime: number;
  /** 上次 tick 时间 */
  _lastTickTime: number;
  /** 预定下次帧时间 */
  _scheduledTime: number;
  /** 帧持续时间 (K/fps) */
  _frameDuration: number;
  /** 帧率 */
  _fps: number;
  /** 播放速率 */
  _speed: number;
  /** 是否有子节点 */
  _hasChildren: boolean;
  /** 子节点链表头 */
  _head: Tickable | Tween | null;
  /** 子节点链表尾 */
  _tail: Tickable | Tween | null;

  /** 帧节流: 判断是否应该渲染当前帧 */
  requestTick(time: number): TickMode;
  /** 计算帧间隔 */
  computeDeltaTime(time: number): number;
}

// ============================================================
// Timer - 动画时间基类契约
// ============================================================
interface ITimer extends IClock {
  /** 唯一标识 */
  id: string | number;
  /** 父级 Timer (Timeline) */
  parent: Timeline | null;
  /** 总持续时间 */
  duration: number;
  /** 是否反向 */
  backwards: boolean;
  /** 暂停状态 */
  paused: boolean;
  /** 已开始标志 */
  began: boolean;
  /** 已完成标志 */
  completed: boolean;
  /** 单次迭代持续时间 */
  iterationDuration: number;
  /** 总迭代次数 */
  iterationCount: number;
  /** 当前迭代索引 */
  _currentIteration: number;
  /** 当前迭代内时间 */
  _iterationTime: number;
  /** 延迟偏移 */
  _offset: number;
  /** 取消标志 */
  _cancelled: number;
  /** 自动播放/滚动联动 */
  _autoplay: boolean | ScrollObserver;

  /** 进度 0-1 (get/set) */
  progress: number;
  /** 迭代进度 0-1 (get/set) */
  iterationProgress: number;
  /** 当前时间 (get/set) */
  currentTime: number;
  /** 迭代内当前时间 (get/set) */
  iterationCurrentTime: number;
  /** 当前迭代索引 (get/set) */
  currentIteration: number;
  /** 反向标志 (get/set) */
  reversed: boolean;
  /** 播放速度 (get/set) */
  speed: number;

  // 回调
  onBegin: Callback<this>;
  onBeforeUpdate: Callback<this>;
  onUpdate: Callback<this>;
  onLoop: Callback<this>;
  onPause: Callback<this>;
  onComplete: Callback<this>;

  // 控制方法
  init(internalRender?: boolean): this;
  reset(softReset?: boolean): this;
  restart(): this;
  seek(time: number, muteCallbacks?: boolean, internalRender?: boolean): this;
  pause(): this;
  resume(): this;
  play(): this;
  reverse(): this;
  alternate(): this;
  stretch(newDuration: number): this;
  cancel(): this;
  revert(): this;
  complete(muteCallbacks?: boolean): this;
  then(callback?: Callback<ResolvedTimer>): Promise<this>;
  resetTime(): this;
}

// ============================================================
// Tween - 动画属性插值单元契约
// ============================================================
interface ITween {
  /** 目标对象 */
  target: Target;
  /** 属性名 */
  property: string;
  /** Tween 类型 */
  _tweenType: TweenType;   // OBJECT | ATTRIBUTE | CSS | TRANSFORM | CSS_VAR
  /** 值类型 */
  _valueType: ValueType;   // NUMBER | UNIT | COLOR | COMPLEX
  /** 起始数值 */
  _fromNumber: number;
  /** 结束数值 */
  _toNumber: number;
  /** CSS 单位 */
  _unit: string;
  /** 起始时间偏移 */
  _startTime: number;
  /** 变化持续时间 */
  _changeDuration: number;
  /** 更新持续时间 (含延迟) */
  _updateDuration: number;
  /** 合成模式 */
  _composition: CompositionType; // replace | none | blend
  /** 缓动函数 */
  _ease: EaseFunction;
  /** 值修饰函数 */
  _modifier: ModifierFunction;
  /** 当前时间 */
  _currentTime: number;
  /** 是否被覆盖 */
  _isOverridden: boolean;
  /** 是否被重叠 */
  _isOverlapped: boolean;
  /** 绝对起始时间 */
  _absoluteStartTime: number;
  /** 链表下一个 */
  _next: Tween | null;
  /** 链表上一个 */
  _prev: Tween | null;
}

// ============================================================
// JSAnimation - 单次动画契约
// ============================================================
interface IJSAnimation extends ITimer {
  /** Tween 链表头 */
  _head: Tween | null;
  /** Tween 链表尾 */
  _tail: Tween | null;
  /** 目标数组 */
  targets: TargetsArray;
  /** 默认参数 */
  defaults: AnimationParams;
  /** 渲染回调 */
  onRender: Callback<this>;

  /** 刷新动画值 (重新读取当前值) */
  refresh(): this;
}

// ============================================================
// Timeline - 时间线编排契约
// ============================================================
interface ITimeline extends ITimer {
  /** 默认子动画参数 */
  defaults: AnimationParams;

  /** 添加动画到时间线 */
  add(
    targets: TargetsParam,
    params: AnimationParams,
    position?: TimelinePosition
  ): this;
  /** 设置属性 (立即生效) */
  set(
    targets: TargetsParam,
    params: AnimationParams,
    position?: TimelinePosition
  ): this;
  /** 同步子动画 */
  sync(): this;
  /** 刷新所有子动画 */
  refresh(): this;
  /** 移除子动画 */
  remove(targets: TargetsParam): this;
}

// ============================================================
// Engine - 全局引擎契约
// ============================================================
interface IEngine extends IClock {
  /** 默认参数 */
  defaults: DefaultsParams;
  /** 是否使用默认主循环 */
  useDefaultMainLoop: boolean;
  /** 页面隐藏时暂停 */
  pauseOnDocumentHidden: boolean;
  /** 暂停状态 */
  paused: boolean;
  /** rAF/setImmediate ID */
  reqId: number;
  /** 上次 tick 时间 */
  _lastTickTime: number;

  /** 唤醒引擎 */
  wake(): void;
  /** 暂停引擎 */
  pause(): this;
  /** 恢复引擎 */
  resume(): this;
}

// ============================================================
// 类型枚举
// ============================================================
declare const enum TweenType {
  OBJECT = 0,
  ATTRIBUTE = 1,
  CSS = 2,
  TRANSFORM = 3,
  CSS_VAR = 4,
}

declare const enum ValueType {
  NUMBER = 0,
  UNIT = 1,
  COLOR = 2,
  COMPLEX = 3,
}

declare const enum TickMode {
  NONE = 0,
  AUTO = 1,
  FORCE = 2,
}

declare const enum CompositionType {
  replace = 0,
  none = 1,
  blend = 2,
}

6.2 对外公共 API 契约 (函数签名)

typescript
// ============================================================
// 核心动画 API
// ============================================================

/**
 * 创建单次动画
 * @param targets - CSS选择器/DOM元素/NodeList/JS对象/数组
 * @param parameters - 动画参数配置
 * @returns JSAnimation 实例
 */
export function animate(
  targets: TargetsParam,
  parameters: AnimationParams
): JSAnimation;

/**
 * 创建批量动画 (为每个目标创建独立动画)
 * @param targets - 目标数组
 * @param parameters - 动画参数
 * @returns JSAnimation[]
 */
export function createAnimations(
  targets: TargetsParam,
  parameters: AnimationParams
): JSAnimation[];

// ============================================================
// 时间线 API
// ============================================================

/**
 * 创建动画时间线
 * @param parameters - Timeline 参数 (可选)
 * @returns Timeline 实例
 */
export function createTimeline(
  parameters?: TimelineParams
): Timeline;

// ============================================================
// 缓动函数 API
// ============================================================

/**
 * 解析缓动函数 (字符串 → 函数)
 * @param ease - 缓动名称字符串或函数
 * @returns 缓动函数 (t: number) => number
 */
export function parseEase(
  ease: string | EaseFunction
): EaseFunction;

/**
 * 创建三次贝塞尔缓动
 * @param x1, y1, x2, y2 - 贝塞尔控制点
 * @returns 缓动函数
 */
export function cubicBezier(
  x1: number, y1: number,
  x2: number, y2: number
): EaseFunction;

/**
 * 创建弹簧缓动
 * @param parameters - 弹簧参数 (mass, stiffness, damping, velocity)
 * @returns 缓动函数
 */
export function spring(
  parameters?: SpringParams
): EaseFunction;

// ============================================================
// 工具 API
// ============================================================

/**
 * 创建交错延迟
 * @param value - 每个元素的延迟时间
 * @param options - 交错选项 (from: 'start'|'center'|'end'|number)
 * @returns StaggerFunction
 */
export function stagger(
  value: number | StaggerFunction,
  options?: { from?: 'start' | 'center' | 'end' | number }
): StaggerFunction;

// ============================================================
// 作用域 API
// ============================================================

/**
 * 创建作用域
 * @param parameters - 作用域配置
 * @returns Scope 实例
 */
export function createScope(
  parameters?: ScopeParams
): Scope;

7. 构建与包结构

text
rollup.config.js
 |
 +-- 开发构建 (默认):
 |     输入: src/**/index.js (从 package.json exports 自动提取)
 |     输出: dist/modules/ (ESM + CJS, preserveModules)
 |
 +-- 生产构建 (build=true):
       输入: src/index.js
       输出: dist/bundles/anime.esm.js (ESM)
             dist/bundles/anime.umd.js (UMD)
             dist/bundles/anime.esm.min.js (ESM minified)
             dist/bundles/anime.umd.min.js (UMD minified)
       + TypeScript: tsconfig.types.json → dist/modules/**/*.d.ts

8. 快速开始

8.1 安装

bash
npm install animejs

8.2 基本用法

javascript
import { animate, stagger } from 'animejs';

animate('.square', {
  x: 320,
  rotate: { from: -180 },
  duration: 1250,
  delay: stagger(65, { from: 'center' }),
  ease: 'inOutQuint',
  loop: true,
  alternate: true
});

8.3 开发环境

bash
npm i                    # 安装依赖
npm run dev              # 开发模式 (监听 src/ 变化)
npm run build            # 构建所有格式
npm run test:browser     # 浏览器测试
npm run test:node        # Node.js 测试
npm run open:examples    # 浏览示例

8.4 模块化导入

javascript
// 按需导入 (Tree Shaking 友好)
import { animate } from 'animejs';
import { createTimeline } from 'animejs/timeline';
import { spring } from 'animejs/easings/spring';
import { createDraggable } from 'animejs/draggable';
import { splitText } from 'animejs/text';