Lottie Web 开源项目解读
项目信息
项目名称:Lottie Web
项目描述: 是 Airbnb 开源的 Web 端 Adobe After Effects 动画解析与原生渲染引擎,支持将 AE 设计师通过 Bodymovin 插件导出的 JSON 动画数据在浏览器中以 SVG、Canvas 或 HTML 方式高性能原生播放。
解决的核心痛点:
- 设计到开发的协作鸿沟:设计师在 After Effects 中制作的精美动画,传统做法需要工程师手工重新编码实现,费时费力且效果容易走样。lottie-web 直接解析 AE 动画 JSON 数据,使设计稿"所见即所得"地呈现在 Web 端。
- 跨平台动画一致性:通过 Bodymovin 导出标准化的 JSON 中间格式,同一份动画数据可在 Web、Android、iOS、React Native 和 Windows 多端一致渲染,极大简化了跨平台动画开发。
- 高性能实时渲染:支持 SVG 矢量渲染(无损缩放)、Canvas 2D(高性能像素渲染)和 HTML(3D 相机支持)三种渲染模式,可根据业务场景灵活选择渲染方式。
目标用户:
- 前端开发者:通过简单的
lottie.loadAnimation()API 加载和播放动画 - UI/UX 设计师:使用 After Effects 制作动画,通过 Bodymovin 插件导出 JSON 数据
- 跨平台移动开发团队:需要 Web/iOS/Android 多端动画一致性交付的团队
核心业务场景:
- 品牌动效/Logo 动画
- UI 交互反馈(加载动画、按钮点击、页面转场)
- 社交/内容类应用动画表情
- 游戏 UI 动画(Canvas 高性能渲染)
1. 项目概览
1.1 项目定位与核心价值
lottie-web 是 Airbnb 开源的 Web 端 Adobe After Effects 动画解析与原生渲染引擎,支持将 AE 设计师通过 Bodymovin 插件导出的 JSON 动画数据在浏览器中以 SVG、Canvas 或 HTML 方式高性能原生播放。
项目信息:
| 属性 | 值 |
|---|---|
| 名称 | lottie-web |
| 版本 | 5.13.0 |
| 仓库 | https://github.com/airbnb/lottie-web |
| 许可证 | MIT |
| 入口文件 | build/player/lottie.js |
| 类型定义 | index.d.ts |
| 总文件数 | 289 |
| 源代码行数 | 23,319 |
| 核心源码目录 | player/js/ (25 个子目录, 约 185 个 JS 文件) |
解决的核心痛点:
设计到开发的协作鸿沟:设计师在 After Effects 中制作的精美动画,传统做法需要工程师手工重新编码实现,费时费力且效果容易走样。lottie-web 直接解析 AE 动画 JSON 数据,使设计稿"所见即所得"地呈现在 Web 端。
跨平台动画一致性:通过 Bodymovin 导出标准化的 JSON 中间格式,同一份动画数据可在 Web、Android、iOS、React Native 和 Windows 多端一致渲染,极大简化了跨平台动画开发。
高性能实时渲染:支持 SVG 矢量渲染(无损缩放)、Canvas 2D(高性能像素渲染)和 HTML(3D 相机支持)三种渲染模式,可根据业务场景灵活选择渲染方式。
1.2 目标用户与使用场景
目标用户:
- 前端开发者:通过简单的
lottie.loadAnimation()API 加载和播放动画 - UI/UX 设计师:使用 After Effects 制作动画,通过 Bodymovin 插件导出 JSON 数据
- 跨平台移动开发团队:需要 Web/iOS/Android 多端动画一致性交付的团队
核心业务场景:
- 品牌动效/Logo 动画
- UI 交互反馈(加载动画、按钮点击、页面转场)
- 社交/内容类应用动画表情
- 游戏 UI 动画(Canvas 高性能渲染)
1.3 核心技术亮点
- 三种渲染器并存:SVG(矢量无损)、Canvas(高性能)、HTML(3D支持),按场景选择
- 完整的 AE 表达式引擎:自实现 wiggle、loopIn/Out、time、value 等 AE 内置函数
- 形状变形系统:支持 6 种形状修饰器(Trim/Pucker/Bloat/Repeater/RoundCorners/ZigZag/OffsetPath)
- SVG 滤镜系统:9 种 SVG 滤镜效果(投影/模糊/色阶/色调等)
- Web Worker 支持:支持在 Web Worker 中解析数据,不阻塞主线程
- 对象池优化:6 种对象池减少 GC 压力,提升性能
- 灵活构建:8 个构建入口,生成 20+ 种不同体积的产物
1.4 技术栈与选型对比
| 技术选择 | 替代方案 | 选择理由 |
|---|---|---|
| 纯 JavaScript (ES6+) | TypeScript | 历史原因(2015年启动),提供 .d.ts 满足 TS 用户,避免编译步骤 |
| Rollup (打包) | Webpack | 库而非应用,Rollup 天然适合库打包,tree-shaking 效果好 |
| 三种渲染器并存 | 单一 SVG | 满足不同性能/交互需求,按需加载减小体积 |
| 内联第三方依赖 | npm 依赖 | 减少依赖数量,避免版本冲突,定制化修改 |
| 自定义表达式引擎 | 不实现 | 不支持表达式会导致大量 AE 动画无法正确渲染 |
2. 整体架构设计
2.1 架构概述
lottie-web 采用分层+插件化架构。核心分为五个层次:公共 API 层(lottie 全局对象)、动画管理层(AnimationManager)、渲染器层(SVG/Canvas/Hybrid)、元素层(各类图层元素)、以及基础设施层(属性工厂、表达式引擎、形状修饰器、对象池等)。各层之间通过注册器模式和接口契约解耦,实现"轻量核心 + 按需加载功能"的设计目标。
2.2 整体架构图
+=====================================================================================+
| Lottie-Web 整体分层架构 |
+=====================================================================================+
| |
| +-------------------------------------------------------------------------------+ |
| | 公共 API 层 (Public API Layer) | |
| | lottie.loadAnimation() / play() / stop() / setSpeed() / destroy() ... | |
| | [module.js] --- 全局 lottie 对象组装, 暴露所有公共方法 | |
| +-----------------------------------+-------------------------------------------+ |
| | (调用) |
| v |
| +-------------------------------------------------------------------------------+ |
| | 动画管理层 (Animation Management Layer) | |
| | +------------------+ +--------------------+ +--------------------+ | |
| | | AnimationManager |--->| AnimationItem |--->| requestAnimation | | |
| | | (全局动画注册表) | | (单实例状态/控制) | | Frame 循环驱动 | | |
| | +------------------+ +--------------------+ +--------------------+ | |
| +-----------------------------------+-------------------------------------------+ |
| | (渲染委托) |
| v |
| +-------------------------------------------------------------------------------+ |
| | 渲染器层 (Renderer Layer) | |
| | +------------------+ +------------------+ +------------------+ | |
| | | SVGRenderer | | CanvasRenderer | | HybridRenderer | | |
| | | (SVG DOM 渲染) | | (Canvas 2D 渲染) | | (HTML+CSS 3D) | | |
| | | +SVGRendererBase| | +CanvasRenderer- | | +HybridRenderer- | | |
| | | | | Base | | Base | | |
| | +--------+---------+ +--------+---------+ +--------+---------+ | |
| | | | | | |
| | v v v | |
| | [renderersManager] -- 渲染器注册/查找 (注册器模式) | |
| +-----------------------------------+-------------------------------------------+ |
| | (创建图层) |
| v |
| +-------------------------------------------------------------------------------+ |
| | 元素层 (Element Layer) | |
| | +------------------+ +------------------+ +------------------+ | |
| | | SVG Elements | | Canvas Elements | | HTML Elements | | |
| | | - SVGCompElement | | - CVCompElement | | - HCompElement | | |
| | | - SVGShapeElement| | - CVShapeElement | | - HShapeElement | | |
| | | - SVGTextElement | | - CVTextElement | | - HTextElement | | |
| | | - SVGImageElement| | - CVImageElement | | - HImageElement | | |
| | | - SVGSolidElement| | - CVSolidElement | | - HSolidElement | | |
| | | + SVGEffects | | + CVEffects | | + HEffects | | |
| | +------------------+ +------------------+ +------------------+ | |
| | | |
| | +------------------------------------------------------------------+ | |
| | | 基础元素类 (Base Elements / Helpers) | | |
| | | BaseElement -> ShapeElement -> CompElement -> ImageElement ... | | |
| | | TransformElement, RenderableElement, HierarchyElement ... | | |
| | +------------------------------------------------------------------+ | |
| +-----------------------------------+-------------------------------------------+ |
| | (依赖) |
| v |
| +-------------------------------------------------------------------------------+ |
| | 基础设施层 (Infrastructure Layer) | |
| | +------------------+ +------------------+ +------------------+ | |
| | | PropertyFactory | | ExpressionEngine | | ShapeModifiers | | |
| | | (关键帧插值/属性) | | (AE 表达式引擎) | | (形状变形修饰器) | | |
| | +------------------+ +------------------+ +------------------+ | |
| | +------------------+ +------------------+ +------------------+ | |
| | | DataManager | | FontManager | | AssetLoader | | |
| | | (JSON 解析/LOT) | | (字体管理) | | (资源加载) | | |
| | +------------------+ +------------------+ +------------------+ | |
| | +------------------+ +------------------+ +------------------+ | |
| | | Object Pools | | Transformation | | 3rd Party Libs | | |
| | | (对象池/性能优化) | | Matrix (矩阵运算) | | (bezier/howler) | | |
| | +------------------+ +------------------+ +------------------+ | |
| +-------------------------------------------------------------------------------+ |
| |
+=====================================================================================+分层职责说明:
| 层级 | 核心职责 | 关键设计模式 |
|---|---|---|
| 公共 API 层 | 向外部暴露统一的 lottie 对象,封装所有公共方法 | Facade 模式 |
| 动画管理层 | 管理多个动画实例的生命周期、统协 RAF 循环 | 单例模式、观察者模式、享元模式 |
| 渲染器层 | 按渲染类型创建对应元素,管理图层到元素的映射 | 策略模式、注册器模式 |
| 元素层 | 每种图层类型在各渲染器下的具体实现 | 模板方法模式、组合模式 |
| 基础设施层 | 提供属性插值、表达式求值、形状变形等核心能力 | 工厂模式、装饰器模式、对象池模式 |
2.3 目录结构
lottie-web/
├── .github/ # 【配置】CI/CD 工作流 (GitHub Actions)
│ └── workflows/ # 【配置】自动化构建/发布/测试工作流
├── build/ # 【配置】构建产物目录
│ ├── extension/ # 【配置】Bodymovin AE 插件的 .zxp 扩展包
│ └── player/ # 【配置】构建后的播放器 JS 产物文件
│ ├── cjs/ # 【配置】CommonJS 格式产物
│ └── esm/ # 【配置】ES Module 格式产物
├── demo/ # 【业务模块】动画演示页面 (各类动画 demo)
│ ├── adrock/ # 【业务模块】Adrock 角色动画 demo
│ ├── banner/ # 【业务模块】Banner 动画 demo
│ ├── bodymovin/ # 【业务模块】基础功能演示 demo
│ ├── catrim/ # 【业务模块】Catrim 动画 demo
│ ├── gatin/ # 【业务模块】Gatin 动画 demo
│ ├── grunt/ # 【业务模块】Grunt 动画 demo
│ ├── happy2016/ # 【业务模块】Happy 2016 新年动画 demo
│ └── navidad/ # 【业务模块】Navidad 圣诞节动画 demo
├── docs/ # 【配置】项目文档目录 (JSON schema 等)
├── gifs/ # 【配置】README 展示用动图 (GIF 格式)
├── player/ # 【核心基建】播放器核心源代码目录
│ └── js/ # 【核心基建】JavaScript 源代码主目录
│ ├── 3rd_party/ # 【工具集】第三方内联依赖库
│ │ ├── BezierEaser.js # 【工具集】贝塞尔缓动函数计算
│ │ ├── howler.js # 【工具集】Web Audio 音频播放库 (精简版)
│ │ ├── seedrandom.js # 【工具集】伪随机数种子生成器
│ │ └── transformation-matrix.js # 【核心基建】2D/3D 变换矩阵运算库
│ ├── animation/ # 【核心基建】动画生命周期管理模块
│ │ ├── AnimationItem.js # 【核心基建】AnimationItem - 动画实例核心 (单动画状态/控制)
│ │ ├── AnimationItemWorkerOverride.js # 【核心基建】Web Worker 中动画实例覆盖
│ │ ├── AnimationManager.js # 【核心基建】AnimationManager - 全局动画管理器 (单例)
│ │ └── AnimationManagerWorkerOverride.js # 【核心基建】Web Worker 中动画管理器覆盖
│ ├── effects/ # 【业务模块】滤镜效果实现
│ │ ├── EffectsManagerPlaceholder.js # 【业务模块】Web Worker 中效果管理器占位
│ │ ├── SliderEffect.js # 【业务模块】滑块控制效果
│ │ └── TransformEffect.js # 【业务模块】变换效果
│ ├── elements/ # 【核心基建】图层元素系统
│ │ ├── canvasElements/ # 【业务模块】Canvas 2D 渲染元素实现
│ │ │ ├── CVBaseElement.js # 【核心基建】Canvas 元素基类 (2D Context 操作)
│ │ │ ├── CVCompBaseElement.js # 【核心基建】Canvas 合成元素基类
│ │ │ ├── CVCompElement.js # 【业务模块】Canvas 合成元素
│ │ │ ├── CVContextData.js # 【核心基建】Canvas Context 数据管理器 (栈式状态)
│ │ │ ├── CVEffects.js # 【业务模块】Canvas 效果注册管理器
│ │ │ ├── CVImageElement.js # 【业务模块】Canvas 图像元素
│ │ │ ├── CVMaskElement.js # 【业务模块】Canvas 遮罩元素
│ │ │ ├── CVShapeElement.js # 【业务模块】Canvas 形状元素 (521行, 复杂)
│ │ │ ├── CVSolidElement.js # 【业务模块】Canvas 纯色层元素
│ │ │ ├── CVTextElement.js # 【业务模块】Canvas 文字元素
│ │ │ └── effects/
│ │ │ └── CVTransformEffect.js # 【业务模块】Canvas 变换效果
│ │ ├── helpers/ # 【工具集】元素辅助类 (复用基类)
│ │ │ ├── FrameElement.js # 【工具集】帧元素辅助
│ │ │ ├── HierarchyElement.js # 【核心基建】层次元素 - 管理父子层级关系
│ │ │ ├── RenderableDOMElement.js # 【核心基建】可渲染 DOM 元素 - DOM 操作封装
│ │ │ ├── RenderableElement.js # 【核心基建】可渲染元素基类 - 渲染生命周期
│ │ │ ├── TransformElement.js # 【核心基建】变换元素 - transform/opacity 处理
│ │ │ └── shapes/ # 【工具集】形状渲染辅助数据结构
│ │ │ ├── CVShapeData.js # 【工具集】Canvas 形状数据
│ │ │ ├── ProcessedElement.js # 【工具集】已处理元素包装
│ │ │ ├── ShapeElement.js # 【工具集】形状元素辅助
│ │ │ ├── ShapeGroupData.js # 【工具集】形状组数据
│ │ │ ├── ShapeTransformManager.js # 【工具集】形状变换管理器
│ │ │ ├── SVGElementsRenderer.js # 【工具集】SVG 元素渲染器
│ │ │ ├── SVGFillStyleData.js # 【工具集】SVG 填充样式数据
│ │ │ ├── SVGGradientFillStyleData.js # 【工具集】SVG 渐变填充样式数据
│ │ │ ├── SVGGradientStrokeStyleData.js # 【工具集】SVG 渐变描边样式数据
│ │ │ ├── SVGNoStyleData.js # 【工具集】SVG 无样式数据
│ │ │ ├── SVGShapeData.js # 【工具集】SVG 形状数据
│ │ │ ├── SVGStrokeStyleData.js # 【工具集】SVG 描边样式数据
│ │ │ ├── SVGStyleData.js # 【工具集】SVG 样式数据基类
│ │ │ └── SVGTransformData.js # 【工具集】SVG 变换数据
│ │ ├── htmlElements/ # 【业务模块】HTML+CSS 渲染元素实现 (支持 3D)
│ │ │ ├── HBaseElement.js # 【核心基建】HTML 元素基类
│ │ │ ├── HCameraElement.js # 【业务模块】HTML 3D 相机元素
│ │ │ ├── HCompElement.js # 【业务模块】HTML 合成元素 (支持 3D transform)
│ │ │ ├── HEffects.js # 【业务模块】HTML 效果管理
│ │ │ ├── HImageElement.js # 【业务模块】HTML 图像元素
│ │ │ ├── HShapeElement.js # 【业务模块】HTML 形状元素
│ │ │ ├── HSolidElement.js # 【业务模块】HTML 纯色层元素
│ │ │ └── HTextElement.js # 【业务模块】HTML 文字元素
│ │ ├── svgElements/ # 【业务模块】SVG DOM 渲染元素实现
│ │ │ ├── SVGBaseElement.js # 【核心基建】SVG 元素基类
│ │ │ ├── SVGCompElement.js # 【业务模块】SVG 合成元素
│ │ │ ├── SVGEffects.js # 【业务模块】SVG 滤镜效果注册管理器
│ │ │ ├── SVGEffectsPlaceholder.js # 【业务模块】Worker 中 SVG 效果占位
│ │ │ ├── SVGShapeElement.js # 【业务模块】SVG 形状元素
│ │ │ ├── SVGTextElement.js # 【业务模块】SVG 文字元素
│ │ │ └── effects/ # 【业务模块】SVG 滤镜/特效实现 (9种)
│ │ │ ├── SVGComposableEffect.js # 【核心基建】SVG 组合效果基类
│ │ │ ├── SVGDropShadowEffect.js # 【业务模块】投影滤镜 (id=25)
│ │ │ ├── SVGFillFilter.js # 【业务模块】填充滤镜 (id=21)
│ │ │ ├── SVGGaussianBlurEffect.js # 【业务模块】高斯模糊滤镜 (id=29)
│ │ │ ├── SVGMatte3Effect.js # 【业务模块】Matte3 效果 (id=28)
│ │ │ ├── SVGProLevelsFilter.js # 【业务模块】色阶滤镜 (id=24)
│ │ │ ├── SVGStrokeEffect.js # 【业务模块】描边效果 (id=22)
│ │ │ ├── SVGTintEffect.js # 【业务模块】色调滤镜 (id=20)
│ │ │ ├── SVGTransformEffect.js # 【业务模块】SVG 变换效果 (id=35)
│ │ │ └── SVGTritoneFilter.js # 【业务模块】三色调滤镜 (id=23)
│ │ ├── AudioElement.js # 【业务模块】音频图层元素
│ │ ├── BaseElement.js # 【核心基建】图层元素基类 (公共接口定义)
│ │ ├── BaseTextElement.js # 【核心基建】文字元素基类
│ │ ├── CompElement.js # 【核心基建】合成元素基类
│ │ ├── FootageElement.js # 【业务模块】素材/镜头元素
│ │ ├── ImageElement.js # 【业务模块】图像元素
│ │ ├── NullElement.js # 【业务模块】空对象元素
│ │ ├── ShapeElement.js # 【核心基建】形状元素基类
│ │ ├── SolidElement.js # 【业务模块】纯色层元素
│ │ └── TextElement.js # 【业务模块】文字元素
│ ├── modules/ # 【核心基建】打包入口模块 (按功能组合)
│ │ ├── main.js # 【核心基建】核心模块入口 (导出 lottie 全局对象)
│ │ ├── full.js # 【核心基建】全功能版本入口 (所有渲染器+表达式+效果)
│ │ ├── full_worker.js # 【核心基建】全功能 Worker 版本入口
│ │ ├── svg.js # 【核心基建】SVG 版本入口 (含表达式+滤镜)
│ │ ├── svg_light.js # 【核心基建】SVG 轻量版入口 (无表达式)
│ │ ├── canvas.js # 【核心基建】Canvas 版本入口 (含表达式)
│ │ ├── canvas_light.js # 【核心基建】Canvas 轻量版入口 (无表达式)
│ │ ├── html.js # 【核心基建】HTML 版本入口 (含表达式+滤镜)
│ │ └── html_light.js # 【核心基建】HTML 轻量版入口 (无表达式)
│ ├── renderers/ # 【核心基建】渲染器系统
│ │ ├── BaseRenderer.js # 【核心基建】渲染器基类 (图层创建/管理)
│ │ ├── SVGRenderer.js # 【核心基建】SVG 渲染器 (创建 SVG DOM)
│ │ ├── SVGRendererBase.js # 【核心基建】SVG 渲染器基类
│ │ ├── CanvasRenderer.js # 【核心基建】Canvas 渲染器 (创建 Canvas 2D)
│ │ ├── CanvasRendererBase.js # 【核心基建】Canvas 渲染器基类
│ │ ├── CanvasRendererWorkerOverride.js # 【核心基建】Worker 中 Canvas 渲染器覆盖
│ │ ├── HybridRenderer.js # 【核心基建】HTML 混合渲染器 (支持 3D)
│ │ ├── HybridRendererBase.js # 【核心基建】HTML 渲染器基类
│ │ └── renderersManager.js # 【核心基建】渲染器注册管理 (注册器模式)
│ ├── utils/ # 【工具集】通用工具与核心引擎
│ │ ├── audio/ # 【业务模块】音频控制模块
│ │ │ ├── AudioController.js # 【业务模块】音频控制器
│ │ │ └── AudioElement.js # 【业务模块】音频元素
│ │ ├── expressions/ # 【核心基建】After Effects 表达式引擎
│ │ │ ├── CompInterface.js # 【核心基建】Comp 接口 - AE 合成对象代理
│ │ │ ├── EffectInterface.js # 【核心基建】Effect 接口 - 效果对象代理
│ │ │ ├── ExpressionManager.js # 【核心基建】表达式管理器 (752行, 编译/求值)
│ │ │ ├── ExpressionPropertyDecorator.js # 【核心基建】表达式属性装饰器
│ │ │ ├── ExpressionTextPropertyDecorator.js # 【核心基建】表达式文字属性装饰器
│ │ │ ├── ExpressionValue.js # 【核心基建】表达式值封装
│ │ │ ├── ExpressionValueFactory.js # 【核心基建】表达式值工厂
│ │ │ ├── Expressions.js # 【核心基建】表达式插件入口/内置函数
│ │ │ ├── FootageInterface.js # 【核心基建】Footage 接口代理
│ │ │ ├── InterfacesProvider.js # 【核心基建】接口提供器 (上下文组装)
│ │ │ ├── LayerInterface.js # 【核心基建】Layer 接口 - 图层对象代理
│ │ │ ├── MaskInterface.js # 【核心基建】Mask 接口 - 遮罩对象代理
│ │ │ ├── ProjectInterface.js # 【核心基建】Project 接口 - 项目对象代理
│ │ │ ├── PropertyGroupFactory.js # 【核心基建】属性组工厂
│ │ │ ├── PropertyInterface.js # 【核心基建】Property 接口 - 属性对象代理
│ │ │ ├── ShapeInterface.js # 【核心基建】Shape 接口 - 形状对象代理 (543行)
│ │ │ ├── TextInterface.js # 【核心基建】Text 接口 - 文字对象代理
│ │ │ ├── TextSelectorPropertyDecorator.js # 【核心基建】文字选择器装饰器
│ │ │ ├── TransformInterface.js # 【核心基建】Transform 接口 - 变换对象代理
│ │ │ ├── expressionHelpers.js # 【工具集】表达式辅助函数
│ │ │ └── shapes/
│ │ │ └── ShapePathInterface.js # 【核心基建】形状路径接口代理
│ │ ├── helpers/ # 【工具集】辅助函数/常量/数据类型
│ │ │ ├── arrays.js # 【工具集】类型化数组创建工具
│ │ │ ├── assetManager.js # 【工具集】资源管理器
│ │ │ ├── blendModes.js # 【工具集】混合模式处理
│ │ │ ├── dynamicProperties.js # 【核心基建】动态属性容器
│ │ │ ├── effectTypes.js # 【工具集】效果类型常量
│ │ │ ├── html_elements.js # 【工具集】HTML 元素创建工具 (createTag)
│ │ │ ├── propTypes.js # 【工具集】属性类型常量
│ │ │ ├── shapeEnums.js # 【工具集】形状类型枚举
│ │ │ └── svg_elements.js # 【工具集】SVG 元素创建工具 (createNS)
│ │ ├── markers/ # 【业务模块】标记/注释解析
│ │ │ └── markerParser.js # 【业务模块】AE 标记解析器
│ │ ├── pooling/ # 【工具集】对象池系统 (性能优化)
│ │ │ ├── bezier_length_pool.js # 【工具集】贝塞尔曲线长度池
│ │ │ ├── point_pool.js # 【工具集】点坐标对象池
│ │ │ ├── pool_factory.js # 【工具集】通用对象池工厂
│ │ │ ├── pooling.js # 【核心基建】对象池系统核心
│ │ │ ├── segments_length_pool.js # 【工具集】线段长度池
│ │ │ ├── shapeCollection_pool.js # 【工具集】形状集合池
│ │ │ └── shape_pool.js # 【工具集】形状对象池
│ │ ├── shapes/ # 【业务模块】形状处理与变形修饰器
│ │ │ ├── DashProperty.js # 【业务模块】虚线属性
│ │ │ ├── GradientProperty.js # 【业务模块】渐变属性
│ │ │ ├── MouseModifier.js # 【业务模块】鼠标交互修饰器
│ │ │ ├── OffsetPathModifier.js # 【业务模块】偏移路径修饰器 (op)
│ │ │ ├── PuckerAndBloatModifier.js # 【业务模块】膨胀收缩修饰器 (pb)
│ │ │ ├── RepeaterModifier.js # 【业务模块】重复器修饰器 (rp)
│ │ │ ├── RoundCornersModifier.js # 【业务模块】圆角修饰器 (rd)
│ │ │ ├── ShapeCollection.js # 【业务模块】形状集合
│ │ │ ├── ShapeModifiers.js # 【核心基建】形状修饰器注册中心与基类
│ │ │ ├── ShapePath.js # 【核心基建】形状路径
│ │ │ ├── ShapeProperty.js # 【核心基建】形状属性 (546行, 复杂)
│ │ │ ├── TrimModifier.js # 【业务模块】裁剪路径修饰器 (tm)
│ │ │ ├── ZigZagModifier.js # 【业务模块】锯齿变形修饰器 (zz)
│ │ │ └── shapePathBuilder.js # 【工具集】形状路径构建器
│ │ ├── text/ # 【业务模块】文字属性动画
│ │ │ ├── LetterProps.js # 【业务模块】字母属性
│ │ │ ├── TextAnimatorDataProperty.js # 【业务模块】文字动画数据属性
│ │ │ ├── TextAnimatorProperty.js # 【业务模块】文字动画属性 (610行, 复杂)
│ │ │ ├── TextProperty.js # 【业务模块】文字属性
│ │ │ └── TextSelectorProperty.js # 【业务模块】文字选择器属性
│ │ ├── BaseEvent.js # 【核心基建】事件系统基类
│ │ ├── DataManager.js # 【核心基建】数据管理器 (676行, JSON解析/LOT格式)
│ │ ├── DataManagerWorkerOverrides.js # 【核心基建】Worker 数据管理器覆盖
│ │ ├── EffectsManager.js # 【业务模块】效果管理器
│ │ ├── FontManager.js # 【业务模块】字体管理器
│ │ ├── FontManagerWorkerOverride.js # 【业务模块】Worker 字体管理器覆盖
│ │ ├── PolynomialBezier.js # 【工具集】多项式贝塞尔曲线计算
│ │ ├── PropertyFactory.js # 【核心基建】属性工厂 (489行, 关键帧插值引擎)
│ │ ├── SlotManager.js # 【工具集】插槽管理器
│ │ ├── TransformProperty.js # 【核心基建】变换属性
│ │ ├── animationFramePolyFill.js # 【工具集】requestAnimationFrame polyfill
│ │ ├── asset_loader.js # 【工具集】资源加载器
│ │ ├── asset_loader_worker_override.js # 【工具集】Worker 资源加载覆盖
│ │ ├── bez.js # 【工具集】贝塞尔工具函数
│ │ ├── common.js # 【核心基建】公共常量和工具函数
│ │ ├── featureSupport.js # 【工具集】浏览器特性检测
│ │ ├── filters.js # 【工具集】滤镜工具
│ │ ├── functionExtensions.js # 【工具集】原型扩展工具 (extendPrototype)
│ │ ├── getFontProperties.js # 【工具集】字体属性获取
│ │ ├── imagePreloader.js # 【工具集】图片预加载器
│ │ └── imagePreloaderWorkerOverride.js # 【工具集】Worker 图片预加载覆盖
│ ├── main.js # 【核心基建】全局核心状态 (svgNS, locationHref, webWorker)
│ ├── mask.js # 【业务模块】遮罩系统
│ ├── module.js # 【核心基建】全局 lottie 对象组装/公共 API 绑定
│ ├── EffectsManager.js # 【业务模块】效果管理器入口
│ └── worker_wrapper.js # 【核心基建】Web Worker 包装器 (1029行, 最复杂文件)
├── projects/ # 【⚠️ 待分析】可能为其他项目配置或示例
├── tasks/ # 【工具集】构建/开发辅助脚本
│ ├── build.js # 【工具集】自动化构建脚本 (773行)
│ └── build_worker.js # 【工具集】Worker 构建脚本
├── test/ # 【工具集】视觉回归测试
│ ├── index.js # 【工具集】测试入口
│ └── animations/ # 【工具集】测试用的 AE 动画 JSON 文件
├── .babelrc.json # 【配置】Babel 转译配置
├── .eslintrc.json # 【配置】ESLint 代码规范配置 (airbnb-base)
├── .gitignore # 【配置】Git 忽略规则
├── .npmignore # 【配置】NPM 发布忽略规则
├── bower.json # 【配置】Bower 包管理器配置 (已废弃)
├── CHANGELOG.md # 【配置】变更日志
├── History.md # 【配置】历史版本详细记录
├── index.d.ts # 【核心基建】TypeScript 类型定义文件 (公共 API 契约)
├── LICENSE.md # 【配置】MIT 许可证
├── package.json # 【配置】NPM 包配置 (入口: build/player/lottie.js, 类型: index.d.ts)
├── README.md # 【配置】英文项目说明文档
├── README-CN.md # 【配置】中文项目说明文档 (本次分析生成)
└── rollup.config.js # 【配置】Rollup 构建配置 (20+ 种产物组合)3. 模块依赖与调用关系
3.1 全局入口与核心路由
逻辑说明:系统有多个构建入口文件(modules/*.js),但核心入口是 module.js → modules/main.js。module.js 创建 lottie 全局对象并绑定所有公共 API 方法,modules/main.js 导出核心共享状态。不同构建版本(svg/canvas/html/full)在 modules/ 下的文件按需注册渲染器和功能模块(表达式、形状修饰器、滤镜等),最终通过 Rollup 打包成不同体积的产物。
调用拓扑:
modules/full.js (全功能构建入口)
+-- imports ---> modules/main.js (或 modules/svg.js, canvas.js, html.js)
|
+---> module.js (lottie 全局对象, 公共 API 组装)
| |
| +---> animation/AnimationManager (注册/加载/控制动画)
| +---> utils/common (全局状态: 子帧开关, 表达式插件等)
| +---> utils/PropertyFactory (属性工厂)
| +---> utils/shapes/ShapeProperty (形状属性工厂)
| +---> 3rd_party/transformation-matrix (矩阵运算)
|
+---> renderers/renderersManager (注册 SVG/Canvas/HTML 渲染器)
| +---> renderers/SVGRenderer
| +---> renderers/CanvasRenderer
| +---> renderers/HybridRenderer
|
+---> utils/shapes/ShapeModifiers (注册形状修饰器)
| +---> TrimModifier (tm: 裁剪路径)
| +---> PuckerAndBloatModifier (pb: 膨胀收缩)
| +---> RepeaterModifier (rp: 重复器)
| +---> RoundCornersModifier (rd: 圆角)
| +---> ZigZagModifier (zz: 锯齿)
| +---> OffsetPathModifier (op: 偏移路径)
|
+---> [可选] utils/expressions/Expressions (AE 表达式引擎)
+---> [可选] elements/svgElements/SVGEffects (SVG 滤镜效果)
+---> [可选] elements/canvasElements/CVEffects (Canvas 变换效果)3.2 核心业务实体与关联
实体定义:
- AnimationItem:动画实例,承载动画的所有状态(当前帧、播放速度、方向、循环模式等),是外部 API 操作的直接对象。
- Renderer (BaseRenderer):渲染器基类,负责管理图层(layers)到元素(elements)的创建和生命周期。每种渲染类型(SVG/Canvas/HTML)有独立子类。
- BaseElement:图层元素基类,每个 AE 图层(形状层、文字层、图像层等)在播放器中对应一个 Element 实例,负责该图层的逐帧渲染。
- ShapeModifier:形状修饰器,对形状路径进行动态变形(裁剪、重复、圆角等),模拟 AE 中的形状效果器。
- Property:动画属性,存储关键帧数据并提供插值计算,驱动动画的逐帧数值变化(位置、缩放、旋转、不透明度、颜色等)。
实体引用拓扑:
[lottie 全局对象] 1 -----> N [AnimationItem] (通过 AnimationManager 管理)
|
+-- 1 -----> 1 [Renderer] (渲染器, 策略模式)
| |
| +-- 1 -----> N [BaseElement] (图层元素)
| | |
| | +-- 1 -----> N [ShapeModifier] (形状修饰器)
| | |
| | +-- 1 -----> N [Property] (动画属性/关键帧)
| |
| +-- 1 -----> 1 [FontManager] (字体)
| +-- 1 -----> 1 [AssetLoader] (资源)
|
+-- 1 -----> 1 [AudioController] (音频控制)
+-- 1 -----> 1 [ImagePreloader] (图片预加载)
+-- 1 -----> 1 [ExpressionEngine] (表达式引擎, 可选)4. 核心模块详解
模块一:AnimationManager - 动画生命周期管理器
模块名称:AnimationManager(player/js/animation/AnimationManager.js)
设计说明:单例模式的全局动画管理器。维护一个
registeredAnimations[]数组存储所有动画实例。与浏览器requestAnimationFrame绑定驱动动画循环。在没有任何动画播放时自动停止循环(_stopped = true),有新动画加入时自动启动。支持 freeze/unfreeze 全局冻结。所有 lottie 全局方法(play/stop/pause/destroy)最终都委托给 AnimationManager,由其遍历所有注册的动画实例执行操作。核心设计模式:单例模式、观察者模式(动画实例通过事件通知管理器状态变化)、享元模式(全局动画循环共享一个 RAF 实例)
内部结构图 (plainText ASCII):
+------------------------------------------------------------------+
| AnimationManager |
| (单例 - 动画注册中心) |
+------------------------------------------------------------------+
| |
| +----------------------+ +----------------------------+ |
| | registeredAnimations | | 动画循环控制 | |
| | [{elem, animation}] | | _stopped / _isFrozen | |
| +-----------+----------+ +-------------+--------------+ |
| | | |
| v v |
| +----------------------+ +----------------------------+ |
| | registerAnimation() | | requestAnimationFrame | |
| | loadAnimation() | | first() -> resume() | |
| | destroy() | | freeze() -> activate() | |
| | searchAnimations() | | (自动启停循环) | |
| +-------+--------------+ +----------------------------+ |
| | |
| v |
| +-----------------------------------------+ |
| | 全局批处理方法: | |
| | play / pause / stop / setSpeed / | |
| | setDirection / goToAndStop / resize / | |
| | setVolume / mute / unmute | |
| +-----------------------------------------+ |
+------------------------------------------------------------------+模块二:Renderer 系统 - 渲染器策略层
模块名称:Renderer System(player/js/renderers/)
设计说明:采用策略模式,
BaseRenderer定义渲染器的公共接口(createItem、buildItem、checkLayers 等),三个具体渲染器(SVGRenderer、CanvasRenderer、HybridRenderer)各自实现。渲染器通过renderersManager的注册器模式注册和查找。渲染器负责:根据图层类型(ty 属性)创建对应的 Element 实例、管理元素生命周期、协调表达式求值和字体加载、处理图层父子层级关系。路由逻辑:当 AnimationItem 调用
setParams()时,根据params.renderer参数('svg'/'canvas'/'html')通过getRenderer(animType)查找对应的 Renderer 构造函数并实例化。每个渲染器有自己的createComp()方法创建对应类型的合成元素。内部结构图 (plainText ASCII):
+------------------------------------------------------------------+
| Renderer System |
| (策略模式 + 注册器) |
+------------------------------------------------------------------+
| |
| +-------------------------------------------------------------+ |
| | renderersManager | |
| | registerRenderer(key, RendererClass) | |
| | getRenderer(key) -> RendererClass | |
| | getRegisteredRenderer() -> default key | |
| +-------------------------------------------------------------+ |
| |
| +-----------------------+ +-----------------------+ |
| | SVGRenderer | | CanvasRenderer | |
| | extends SVGRenderer- | | extends CanvasRenderer-| |
| | Base | | Base | |
| | | | | |
| | svgElement + defs + | | Canvas2DContext + | |
| | layerElement (g) | | CVContextData | |
| | | | | |
| | createComp() -> | | createComp() -> | |
| | SVGCompElement | | CVCompElement | |
| +-----------------------+ +-----------------------+ |
| |
| +-------------------------------------------------------------+ |
| | HybridRenderer | |
| | extends HybridRendererBase | |
| | supports3d = true | |
| | createComp() -> HCompElement (3D) / SVGCompElement (fallback)| |
| +-------------------------------------------------------------+ |
| |
| +-------------------------------------------------------------+ |
| | BaseRenderer (基类) | |
| | checkLayers() -- 检查并创建到期图层 | |
| | createItem() -- 根据 ty 分发创建元素 (switch-case) | |
| | buildAllItems() -- 构建所有图层 | |
| | buildElementParenting() -- 处理图层父子层级 | |
| | setupGlobalData() -- 初始化 FontManager/SlotManager | |
| +-------------------------------------------------------------+ |
+------------------------------------------------------------------+模块三:ExpressionEngine - After Effects 表达式引擎
模块名称:Expression Engine(player/js/utils/expressions/)
设计说明:完整实现了 AE 表达式的解析、求值和上下文模拟系统。核心架构包括:
Expressions.js(表达式入口/注册)、ExpressionManager.js(单个表达式的编译和执行)、InterfacesProvider.js(提供 AE 对象模型接口,如 Comp/Layer/Property/Shape 等)、以及各 Interface 实现(CompInterface、LayerInterface、ShapeInterface 等)。表达式在每一帧通过ExpressionPropertyDecorator注入到属性系统中,替换或增强原有的关键帧插值逻辑。表达式执行流程:AE JSON 数据中的表达式文本 → ExpressionManager 用
new Function()编译为可执行函数 → 通过eval()在模拟的 AE 上下文中执行 → 返回计算结果作为属性值。表达式支持wiggle()、loopIn()、loopOut()、time、value等 AE 内置函数和属性。内部结构图 (plainText ASCII):
+------------------------------------------------------------------+
| Expression Engine |
| (AE 表达式模拟系统) |
+------------------------------------------------------------------+
| |
| +-------------------------------------------------------------+ |
| | Expressions.js (插件注册入口) | |
| | initExpressions() -- 注入表达式求值器到属性系统 | |
| +-------------------------------------------------------------+ |
| |
| +------------------------------+ +---------------------------+ |
| | ExpressionManager | | InterfacesProvider | |
| | (表达式编译/求值) | | (AE 对象模型提供) | |
| | | | | |
| | compileExpression() | | getInterface(element) | |
| | -> new Function() 编译 | | -> CompInterface | |
| | -> eval() 在隔离上下文中 | | -> LayerInterface | |
| | 执行 | | -> PropertyInterface | |
| | | | -> ShapeInterface | |
| | getValue() -> 返回计算结果 | | -> MaskInterface | |
| +------------------------------+ | -> TextInterface | |
| | -> EffectInterface | |
| +------------------------------+ +---------------------------+ |
| | ExpressionPropertyDecorator | |
| | (装饰器 - 注入表达式到属性) | +---------------------------+ |
| | | | 表达式辅助函数: | |
| | 代理属性的 getValue(), | | wiggle, loopIn, loopOut, | |
| | 优先使用表达式计算值, | | time, value, seedRandom, | |
| | 表达式失败则回退到关键帧插值 | | linear, ease, easeIn, | |
| +------------------------------+ | easeOut, posterizeTime... | |
| +---------------------------+ |
+------------------------------------------------------------------+模块四:PropertyFactory - 动画属性与关键帧插值系统
模块名称:PropertyFactory(player/js/utils/PropertyFactory.js)
设计说明:动画的核心引擎,将 AE JSON 中各种类型的动画属性(变换、不透明度、颜色、描边宽度等)转换为具有逐帧插值能力的 Property 对象。支持多种属性类型:
multidimensional(多维如位置 position)、scalar(标量如不透明度)、color(颜色属性)、anchor(锚点)、bezier(贝塞尔缓动)等。每种属性通过getValue()方法计算当前帧的值,采用缓存策略(lastIndex 缓存)优化逐帧查询性能。数据来源:AE JSON 中的关键帧数据来自
DataManager.js,它将 AE 原始的动画数据转换为内部格式。PropertyFactory 基于此数据创建可查询的 Property 对象。内部结构图 (plainText ASCII):
+------------------------------------------------------------------+
| PropertyFactory |
| (动画属性关键帧插值引擎) |
+------------------------------------------------------------------+
| |
| +-------------------------------------------------------------+ |
| | PropertyFactory (工厂方法) | |
| | getProp(elem, data, type, mult, container) -> Property | |
| +-------------------------------------------------------------+ |
| |
| +------------------------------+ +---------------------------+ |
| | 属性类型 (PropType): | | 缓动类型 (Easing): | |
| | | | | |
| | - multidimensional (位置) | | - linear 线性 | |
| | - scalar (不透明度/缩放) | | - bezier 贝塞尔 | |
| | - color (填充色/描边色) | | - hold 保持 (离散跳变) | |
| | - anchor (锚点) | | - smooth bezier | |
| | - dashOffset (虚线偏移) | | | |
| | - textSelector (文字选择器) | +---------------------------+ |
| | - shape (形状) | |
| +------------------------------+ +---------------------------+ |
| | | | 关键帧数据流: | |
| | 核心方法: | | | |
| | getValue(frameNum) | | DataManager -> | |
| | -> 遍历关键帧数组 | | 解析 AE JSON | |
| | -> 定位当前帧所在关键帧区间 | | -> createProperty() | |
| | -> 执行缓动插值 | | -> getValue(frameNum) | |
| | -> 返回当前帧属性值 | | -> 返回插值结果 | |
| +------------------------------+ +---------------------------+ |
+------------------------------------------------------------------+模块五:ShapeModifiers - 形状变形修饰器系统
模块名称:ShapeModifiers(player/js/utils/shapes/)
设计说明:模拟 AE 中形状图层的效果器(Shape Modifiers),对形状路径进行动态变形。所有修饰器继承自
ShapeModifier基类,通过ShapeModifiers.registerModifier()注册。AE 数据中的修饰器通过短的 type code 标识(如tm=Trim,pb=Pucker&Bloat 等)。修饰器在每一帧处理前序形状数据,生成变形后的新形状路径。修饰器之间可以链式串联,模拟 AE 中多个效果器叠加的效果。内部结构图 (plainText ASCII):
+------------------------------------------------------------------+
| Shape Modifiers System |
| (形状变形修饰器管道) |
+------------------------------------------------------------------+
| |
| +-------------------------------------------------------------+ |
| | ShapeModifiers (注册中心) | |
| | registerModifier(nm, factory) | |
| | getModifier(nm, elem, data) -> new Modifier() | |
| +-------------------------------------------------------------+ |
| |
| 注册的修饰器: |
| |
| +------------------+ +------------------+ +------------------+ |
| | TrimModifier | | PuckerAndBloat | | RepeaterModifier | |
| | (tm - 裁剪路径) | | (pb - 膨胀收缩) | | (rp - 重复器) | |
| +------------------+ +------------------+ +------------------+ |
| |
| +------------------+ +------------------+ +------------------+ |
| | RoundCorners | | ZigZagModifier | | OffsetPath | |
| | (rd - 圆角) | | (zz - 锯齿变形) | | (op - 偏移路径) | |
| +------------------+ +------------------+ +------------------+ |
| |
| +-------------------------------------------------------------+ |
| | ShapeModifier (基类) | |
| | shapes[] -- 待处理的形状数据 | |
| | addShape(data) -- 接收输入形状 | |
| | processKeys() -- 逐帧处理变形 | |
| | initModifierProperties() -- 子类实现具体变形逻辑 | |
| +-------------------------------------------------------------+ |
| |
| 数据流: Input ShapePath -> Modifier1 -> Modifier2 -> Output Path |
+------------------------------------------------------------------+5. 关键数据流程
场景一:lottie.loadAnimation() 完整生命周期
场景说明:用户调用
lottie.loadAnimation({container, path:'data.json', renderer:'svg', loop:true, autoplay:true})加载并播放动画。这是最典型的使用场景,覆盖了 JSON 数据加载、动画实例创建、渲染器初始化、首帧渲染、循环播放的完整流程。流转时序图 (Mermaid):
场景二:表达式引擎求值流程
场景说明:当 AE JSON 中包含表达式(如
wiggle(5, 10)实现抖动效果),属性值不再来自关键帧插值,而是由表达式引擎动态计算。表达式在每个渲染帧被求值一次,获取当前帧的实时属性值。流转时序图 (Mermaid):
6. 接口与契约规范
6.1 核心内部模块契约 (TypeScript)
/**
* lottie-web 核心内部模块契约定义
* 基于 index.d.ts 和源代码分析提取
*/
// ============================================================
// 渲染器系统
// ============================================================
/** 渲染器类型标识 */
export type RendererType = 'svg' | 'canvas' | 'html';
/** 渲染器注册器契约 */
export interface IRendererRegistry {
registerRenderer(key: string, RendererClass: IRendererConstructor): void;
getRenderer(key: string): IRendererConstructor | undefined;
getRegisteredRenderer(): string;
}
/** 渲染器构造函数 */
export interface IRendererConstructor {
new(animationItem: IAnimationItem, config: IRendererConfig): IRenderer;
}
/** 渲染器实例契约 */
export interface IRenderer {
animationItem: IAnimationItem;
layers: any[];
elements: IBaseElement[];
pendingElements: IBaseElement[];
globalData: IGlobalData;
renderedFrame: number;
rendererType: RendererType;
completeLayers: boolean;
checkLayers(frameNum: number): void;
createItem(layer: ILayerData): IBaseElement;
buildItem(index: number): void;
buildAllItems(): void;
initItems(): void;
setupGlobalData(animData: IAnimationData, fontsContainer?: Element): void;
setProjectInterface(pInterface: IProjectInterface): void;
buildElementParenting(element: IBaseElement, parentName: number, hierarchy: IBaseElement[]): void;
includeLayers(newLayers: ILayerData[]): void;
getElementById(ind: number): IBaseElement | null;
getElementByPath(path: (string | number)[]): IBaseElement | null;
searchExtraCompositions(assets: any[]): void;
}
// ============================================================
// 动画管理系统
// ============================================================
/** 动画实例契约 */
export interface IAnimationItem {
name: string;
isLoaded: boolean;
currentFrame: number;
currentRawFrame: number;
firstFrame: number;
totalFrames: number;
frameRate: number;
frameMult: number;
playSpeed: number;
playDirection: AnimationDirection;
playCount: number;
isPaused: boolean;
autoplay: boolean;
loop: boolean | number;
renderer: IRenderer;
animationID: string;
assetsPath: string;
timeCompleted: number;
segmentPos: number;
isSubframeEnabled: boolean;
segments: AnimationSegment | AnimationSegment[];
/** 配置动画参数 */
setParams(params: IAnimationConfig): void;
/** 设置动画数据 */
setData(element: Element, animationData?: any): void;
/** 配置动画数据 */
configAnimation(animData: IAnimationData): void;
/** 启动动画循环 */
play(name?: string): void;
/** 停止动画 */
stop(name?: string): void;
/** 暂停动画 */
pause(name?: string): void;
/** 逐帧推进 */
advanceTime(elapsedTime: number): void;
/** 销毁动画 */
destroy(name?: string): void;
/** 跳转并停止 */
goToAndStop(value: number | string, isFrame?: boolean, name?: string): void;
/** 跳转并播放 */
goToAndPlay(value: number | string, isFrame?: boolean, name?: string): void;
/** 获取动画时长 */
getDuration(inFrames?: boolean): number;
}
// ============================================================
// 元素系统
// ============================================================
/** 基础元素契约 */
export interface IBaseElement {
data: ILayerData;
globalData: IGlobalData;
renderer: IRenderer;
parentElement: IBaseElement | null;
children: IBaseElement[];
/** 渲染当前帧 */
renderFrame(): void;
/** 初始化元素 */
initElement(data: ILayerData, globalData: IGlobalData, comp: IRenderer): void;
/** 获取自身矩阵 */
getMatte(matteType: number): IBaseElement | null;
/** 获取子元素 */
getElementByPath(path: (string | number)[]): IBaseElement;
/** 设置层级 */
setHierarchy(hierarchy: IBaseElement[]): void;
/** 设置为父级 */
setAsParent(): void;
/** 销毁元素 */
destroy(): void;
}
// ============================================================
// 属性系统
// ============================================================
/** 动画属性契约 */
export interface IProperty {
propType: string;
keyframes: IKeyframe[];
pv: number[] | number; // 当前值
offsetTime: number;
lastIndex: number;
/** 获取指定帧的值(含插值计算) */
getValue(frameNum: number): number[] | number;
/** 设置是否动画 */
setAsAnimated(): void;
/** 更新当前帧 */
processKeys(frameNum: number): void;
}
/** 关键帧数据 */
export interface IKeyframe {
t: number; // 时间(帧)
s: number[]; // 起始值
e: number[]; // 结束值
h: number; // 是否 hold 关键帧
i?: { x: number; y: number }; // 入缓动控制点
o?: { x: number; y: number }; // 出缓动控制点
}
// ============================================================
// 表达式引擎
// ============================================================
/** 表达式引擎契约 */
export interface IExpressionPlugin {
initExpressions(
compInterface: Function,
expressionManager: Function
): void;
}
/** 表达式管理器契约 */
export interface IExpressionManager {
element: IBaseElement;
expression: string;
_compiledExpression?: Function;
isEnabled: boolean;
compileExpression(): Function;
getValue(frameNum: number): number[] | number;
}
// ============================================================
// 形状修饰器
// ============================================================
/** 形状修饰器契约 */
export interface IShapeModifier {
shapes: IShapeModifierShape[];
elem: IBaseElement;
closed: boolean;
frameId: number;
addShape(data: any): void;
processKeys(): void;
initModifierProperties(elem: IBaseElement, data: any): void;
addShapeToModifier(shapeData: IShapeModifierShape): void;
}
/** 形状修饰器注册中心 */
export interface IShapeModifierRegistry {
registerModifier(name: string, factory: IShapeModifierConstructor): void;
getModifier(name: string, elem: IBaseElement, data: any): IShapeModifier;
}
export interface IShapeModifierConstructor {
new(elem: IBaseElement, data: any): IShapeModifier;
}6.2 对外 API 契约 (TypeScript - 与 index.d.ts 对齐)
/**
* lottie-web 公开 API 契约
* 与 packages/index.d.ts 保持一致
*/
// 方向类型
export type AnimationDirection = 1 | -1;
// 片段类型
export type AnimationSegment = [number, number];
// 事件名称
export type AnimationEventName =
| 'drawnFrame' | 'enterFrame' | 'loopComplete' | 'complete'
| 'segmentStart' | 'destroy' | 'config_ready' | 'data_ready'
| 'DOMLoaded' | 'error' | 'data_failed' | 'loaded_images';
// 渲染器配置
export type SVGRendererConfig = {
title?: string;
description?: string;
preserveAspectRatio?: string;
progressiveLoad?: boolean;
hideOnTransparent?: boolean;
viewBoxOnly?: boolean;
viewBoxSize?: string;
focusable?: boolean;
filterSize?: FilterSizeConfig;
};
export type CanvasRendererConfig = {
clearCanvas?: boolean;
context?: CanvasRenderingContext2D;
progressiveLoad?: boolean;
preserveAspectRatio?: string;
dpr?: number;
};
export type AnimationConfig<T extends RendererType = 'svg'> = {
container: Element;
renderer?: T;
loop?: boolean | number;
autoplay?: boolean;
initialSegment?: AnimationSegment;
name?: string;
assetsPath?: string;
rendererSettings?: RendererSettingsForType<T>;
audioFactory?(assetPath: string): AudioFactory;
};
// 主要公共 API
export type LottiePlayer = {
play(name?: string): void;
pause(name?: string): void;
stop(name?: string): void;
setSpeed(speed: number, name?: string): void;
setDirection(direction: AnimationDirection, name?: string): void;
searchAnimations(animationData?: any, standalone?: boolean, renderer?: string): void;
loadAnimation<T extends RendererType = 'svg'>(
params: AnimationConfigWithPath<T> | AnimationConfigWithData<T>
): AnimationItem;
destroy(name?: string): void;
registerAnimation(element: Element, animationData?: any): void;
setQuality(quality: string | number): void;
setLocationHref(href: string): void;
setIDPrefix(prefix: string): void;
updateDocumentData(
path: (string | number)[],
documentData: TextDocumentData,
index: number
): void;
getRegisteredAnimations(): AnimationItem[];
freeze(): void;
unfreeze(): void;
setVolume(val: number, name?: string): void;
mute(name?: string): void;
unmute(name?: string): void;
inBrowser(): boolean;
setSubframeRendering(flag: boolean): void;
setIDPrefix(prefix: string): void;
installPlugin(type: string, plugin: any): void;
resize(): void;
};7. 构建系统与产物矩阵
lottie-web 的构建系统使用 Rollup,从 5 个基础模块入口(svg_light, svg, canvas, html, full)生成多达 20+ 种不同组合的产物文件:
| 入口模块 | 产物文件 | 格式 |
|---|---|---|
| modules/full.js | lottie.js / lottie.min.js | UMD |
| modules/full.js | lottie.js | ESM / CJS |
| modules/svg_light.js | lottie_light.js / .min.js | UMD / ESM / CJS |
| modules/svg.js | lottie_svg.js / .min.js | UMD / ESM / CJS |
| modules/canvas.js | lottie_canvas.js / .min.js | UMD / ESM / CJS |
| modules/canvas_light.js | lottie_light_canvas.js / .min.js | UMD / ESM / CJS |
| modules/html_light.js | lottie_light_html.js / .min.js | UMD / ESM / CJS |
| modules/html.js | lottie_html.js / .min.js | UMD / ESM / CJS |
其中 _light 版本不包含表达式引擎,体积更小。full 版本包含所有三种渲染器、表达式引擎和全部滤镜效果。
8. 快速开始
8.1 环境配置
# 安装
npm install lottie-web
# 或通过 CDN
# https://cdnjs.com/libraries/bodymovin8.2 安装与运行
<script src="js/lottie.js"></script>lottie.loadAnimation({
container: document.getElementById('animation'),
renderer: 'svg',
loop: true,
autoplay: true,
path: 'animation.json', // AE 导出的 JSON 文件
});8.3 典型用例
- Logo 动效:使用 SVG 渲染器,无损缩放
- 大量元素动画:使用 Canvas 渲染器,避开 DOM 节点开销
- 3D 效果:使用 HTML (Hybrid) 渲染器,支持 3D 相机
- 代码分割加载:使用
animationData传入 JSON 对象,配合懒加载 - 交互动画:使用 SVG 渲染器,可对内部元素添加事件监听