【工具】前端动画解决方案 Lottie(Web 篇)

前端动画解决方案 Lottie(Web 篇)

前些天阿里蚂蚁设计开放出了一款动画设计平台——犸良,惊讶了一阵子之后发现它的底层实现借助了airbnb的Lottie库,再次惊讶之后感叹其伟大。
概念
Lottie是一个面向Android、iOS、Web和Windows的库,它解析导出为带有bodymovin的json的AE(Adobe After Effects)动画,并在移动和Web上以本地方式呈现这些动画。
- 官网:http://airbnb.io/lottie/
- 社区:https://lottiefiles.com/
- bodymovin是一个用于生成供Lottie使用的json文件的一个AE插件,是给设计狮使的
官方社区至今(2019.07.18)统计:下载动画量达1304264次,可见其广泛被大家所接受。
个人认为 Lottie 的最大优势是让设计师直接参与动画开发,将动效设计和实现交给专业设计团队,而不必反复指导前端开发,也无需直接使用难维护且性能较低的 GIF/MP4。这样可以解耦动效业务,让开发和设计协作得更顺畅。

安装和使用(web)
首先是根据需求引用lottie库,官方给出的下载地址:https://cdnjs.com/libraries/bodymovin
如图所示,官网地址给出了v5.5.6的所有版本:
其中:
_light:轻量级,按官网说法,以此拓展名的库将播放导出为SVG的动画。_canvas:以此拓展名的库用canvas动画形式展示。_svg:以此拓展名的库用svg动画形式展示。_html:以此拓展名的库用canvas动画形式展示。
使用
根据需求找到Lottie库后,就是该如何使用了
准备容器和动画库
首先准备渲染容器和引用Lottie库,如:
1 | <div id="app"><!-- 动画容器 --></div> |
并将AE导出的动画数据库(如lottie-1.json)保存在项目目录中,如assets/lottie-1.json

配置参数和渲染
如:
1 | <script> |
这样配置后的页面打开将循环播放一个动画。
这样就是最简单的使用实现了。
配置参数和方法
配置
Lottie的配置很简单,主要配置参数如下:
| 参数 | 说明 | 数据格式 | 默认值 |
|---|---|---|---|
| container | 渲染动画的容器元素 | DOM Element | – |
| path | 动画数据json文件的路径(和animationData参数二选一) |
string | – |
| animationData | 动画数据(和path参数二选一) |
object | – |
| renderer | 渲染方式,'svg'/'canvas'/'html'(轻量版仅svg渲染) |
string | – |
| loop | (可选)动画是否循环,为数字时即控制循环次数 | boolean/number | false |
| autoplay | (可选)动画是否自动播放 | boolean | true |
| name | (可选)自定义动画名称 | string | – |
方法
配置完动画后,我们可以拿到动画实例并通过实例方法进行控制:
play():播放动画,从当前停止帧开始stop():终止动画,回到第0帧pause():暂停动画,停止在当前帧setLocationHref(href):href作为location.href,当你在Safari中遇到不带符号的掩码问题时,它非常有用。setSpeed(speed):设置动画速度(1是正常速度)。speed参数为速度,number。goToAndStop(value, isFrame):动画跨越到某进度并停止。value为进度数值,number;isFrame定义第一个参数(value)是基于时间的值还是基于帧的(默认为false)。setDirection(direction):设置动画播放顺序(顺序播放/倒叙播放)。direction参数表明顺序,1为顺序,-1为倒叙。playSegments(segments, forceFlag):播放动画片段。segments参数可以包含两个将用作动画第一帧和最后一帧的数值,或者可以包含一系列数组,每个数组都有2个数值,array。forceFlag表示是否立即强制播放该片段,如果设置为false,它将等待当前段完成。如果为true,它将立即播放此片段,boolean。如animation.playSegments([10,20], false); // 播放完之前的片段,播放10-20帧、animation.playSegments([[0,5],[10,18]], true); // 直接播放0-5帧和10-18帧setSubframe(useSubFrames):useSubFrames参数如果为false,则将尊重原始的AE fps。如果为true,它将使用中间值在每个RequestAnimationFrame上更新。默认值为true, boolean。destory():删除该动画,移除相应的元素标签等。在unmount的时候,需要调用该方法getDuration(inFrames),获取动画持续时间。inFrames参数为true,则返回以帧为单位的持续时间;如果为false,则返回以秒为单位的持续时间。
事件
在使用中可能也需要监听一些事件:
- complete: 播放完成(循环播放下不会触发)
- loopComplete: 当前循环下播放(循环播放/非循环播放)结束时触发
- enterFrame: 每进入一帧就会触发,播放时每一帧都会触发一次,stop方法也会触发
- segmentStart: 播放指定片段时触发,playSegments、resetSegments等方法刚开始播放指定片段时会发出,如果playSegments播放多个片段,多个片段最开始都会触发。
- data_ready: 动画数据json文件加载完毕触发
- data_fail:动画数据json文件加载失败触发
- loaded_images:当所有图片加载成功/失败时触发
- DOMLoaded: 动画相关的dom已经被添加到html后触发
- destroy: 将在动画删除时触发
使用如:
1 | // 上例的animation实例 |
更多配置可见npm lottie-web
打包及框架中使用
原生js+webpack
目录:
1 | │ index.html |
其中index.html:
1 | <!-- index.html --> |
准备了一个动画容器和三个控制按钮。
安装依赖npm lottie-web
1 | npm i -D lottie-web |
引用并配置:
1 | // enter.js |
这样使用便已完成,可通过按钮控制动画。
ReactJs
目录:
1 | │ App.jsx |
安装依赖(npm react-lottie)
1 | npm i -D react-lottie |
该库将给出一个React组件,用于渲染动画,该组件props:
options:配置参数width: 容器宽度,numberheight:容器高度,numberisStopped:是否停止状态,booleanisPaused:是否暂停状态,booleaneventListeners:事件监听,array
使用及配置如下
1 | // App.jsx |
注:react-lottie底层实现也是使用了lottie-web这个库,只是将其配置和渲染进行了封装,便于开发使用。可访问github react-lottie通过源码查看其实现原理。
VueJS
目录:
1 | │ index.html |
安装依赖(npm vue-lottie)
1 | npm i -D vue-lottie |
该库将给出一个Vue组件,用于渲染动画,该组件props:
options:配置参数width: 容器宽度,numberheight:容器高度,numberanimCreated:注册事件,用于处理动画实例(源码:this.$emit('animCreated', this.anim))
使用及配置如下
1 | <!-- App.vue --> |
注:vue-lottie底层实现也是使用了lottie-web这个库,只是将其配置和渲染进行了封装,便于开发使用。可访问github vue-lottie通过源码查看其实现原理。
Angular
不细说,运用库为npm ng-lottie,底层仍然是lottie-web。
注意事项(设计狮)
下面这些效果,lottie暂不支持:
- 描边动效目前不支持,(会导致lottie性能问题,所以后来lottie去掉了对该属性的支持)。
- merge Path(合并路径)Android只支持4.4以上,iOS都不支持.
遵循下面的方案,会使json文件减小:
- 尽量减少图层个数。每个图层都会导出成相应的json数据,图层减少能从很大程度上减小json大小。
- 尽可能所有的图层都是在AE里面画出来的,而不是从其他软件引入的。如果是其他软件引入的,很可能导致描述这个图形的json部分变得很大。
并且,Lottie支持的动画效果如下:
lottie-web动画实现原理
先占个坑~
lottie.json
首先来看lottie.json中的关键字段:
- ip:起始帧
- op:结束帧
- w:宽
- h:高
- v:版本
- fr:频率/帧率
- ddd
- nm
- tiny
- fonts:字体
- list
- fontConfig
- list
- asset:资源
- assetConfig
- id
- w:宽
- h:高
- u:路径
- p:名称
- e
- assetConfig
- layers:图层
- layerConfig
- st:开始帧
- ip:起始帧
- op:结束帧
- nm:名字
- ind:图层id
- ty:图层类型
- ks:动画
- shapes:图形
- layerConfig
Author
My name is Micheal Wayne and this is my blog.
I am a front-end software engineer.
Contact: michealwayne@163.com