前言
Lottie 是一个由 Airbnb 开发的开源库,用于在 Web 和移动应用中渲染高质量的动画。Lottie 动画通常是由设计师使用 Adobe After Effects 创建,然后通过 Bodymovin 插件导出为 JSON 文件。
一般导出有两种方式,一种是将图片转为base64编译到JSON文件中,另一种是将图片抽离,json中包含对图像资源的引用。那么这些图像资源会被放置在一个单独的文件夹中,通常是images。
如下,Lottie 库可以读取这些 JSON 文件并在应用中渲染动画。
Lottie
特点
- 高质量动画:Lottie 可以渲染复杂的动画,保持高质量和流畅度。
- 跨平台:Lottie 支持多种平台,包括 Web、iOS、Android 和 React Native(部分属性存在兼容性问题,详见下文)。
- 轻量级:Lottie 动画文件通常比传统的动画文件(如 GIF 或视频)要小得多。
- 互动性:Lottie 动画可以与用户交互,响应用户的操作。
注意事项
在Lottie动画中,JSON文件中的assets部分可以指定这些图片的路径。
JSON文件的assets部分:
- "w": 宽度
- "h": 高度
- "u": "images/"表示图像资源的相对路径(相对于服务器根目录的路径)
- "p": "images1.png"表示图片名称
配置选项
export interface LottieProps {
options: {
/** 是否循环 */
loop?: boolean;
/** 是否自动播放 */
autoplay?: boolean;
/** 动画json文件 */
animationData: any;
/** 渲染设置 */
rendererSettings: {
preserveAspectRatio: string;
};
};
width?: number;
height?: number;
isStopped?: boolean;
isPaused?: boolean;
eventListeners?: Array<{
eventName: string;
callback: () => void;
}>;
}
preserveAspectRatio 是一个 SVG 属性,用于指定如何在给定的视口(viewport)中缩放和对齐 SVG 内容 用于控制动画的缩放和对齐方式
比如常见的配置 preserveAspectRatio: 'xMidYMid slice', xMidYMid 居中对齐, slice 保持纵横比缩放SVG内容,使其完全覆盖视口(可能会裁剪内容), 更多配置选项可查询以下链接:
实践中遇到的问题及其解决方案
- 如果图片过大,导出为 base64的格式编码到 json 文件里的, 可能出现以下问题:
一些浏览器或服务器对请求头的大小有严格的限制。如果base64链接过长,可能会导致请求头字段过大,从而触发 Request Header Fields Too Large 错误。
另外,Base64 编码的图片会比原始图片文件大约增加 33% 的体积。如果动画文件包含很多或很大的图片,整个 JSON 文件可能会变得非常大。(当然也可以先将图片资源进行优化压缩再转为base64)
优化手段:
- 分离图片资源:将图片资源从 JSON 文件中分离出来,可以显著减小 JSON 文件的大小。
- 优化图片资源:使用 tinypng 压缩和优化图片资源,减小文件体积,动画会更流畅。
- 分割动画:可以考虑将动画分割成多个较小的部分,分别加载和播放。
- 动画中使用到的静态图片路径
我们在打包资源的时候,通常会对图片资源进行content hash处理,防止图片资源更新,命名未更改的情况下页面图片资源不更新的问题。
public对应的是服务器的根目录,故我们可以将lottie中使用到的图片资源放在public目录下。则不会参与构建,也就没有content hash;再将json文件中 assets 下"u" 设置为对应的相对路径,即可预览效果啦~
也可以参考 gitHub issues
import * as animationData from '../assets/images/node/lottie/data.json'
animationData.assets.forEach((item, index) => {
item.u = ''
item.p = require(`@/assets/images/node/lottie/images/img_${index}.png`)
})
- 用户手动点击动画,可以使之暂停或者播放,如何解决?
lottie自带属性isStop、isPaused,尽管设置isStopped、isPaused为false,用户通过点击动画仍然可以暂停和播放动画,我们通过监听点击事件在捕获阶段来禁止。
- Lottie适配兼容性
从上图中可以看到,虽然lottie可以跨平台兼容,但实际上对某些属性存在兼容问题,故设计师在制作动画时需要考虑使用到的特性是否全平台兼容。
lottie实践
以上手指动效可以共用一个lottie,镜像对称的手指(左|右手)可以通过 transform: scaleX(-1)实现;不同角度的手指,也可以通过旋转对应角度来实现transform: rotate(xdeg)
Lottie的痛点
综上,我们发现Lottie 存在一些痛点,比如性能问题、文件大小和跨平台兼容性等。WebAssembly (Wasm)提供更接近原生的性能,可以更高效解决这些问题。
但门槛更高,需要编写c/c++/Rust等语言代码,且调试也相对更困难些。
相关参考
- Lottie官网
- LottieFiles - 一个分享和管理 Lottie 动画的平台
- react-lottie github