背景
实现一些动画效果,常用的方案是 Gif 动画 / 视频 /svg、canvas 动画/ 手写animation/序列帧。
Gif :文件一般较大,且呈现的大小是固定的,无法缩放以匹配大屏幕和高密度屏幕,容易有锯齿,不能控制动画。
序列帧:合成的雪碧图文件大,且在不同屏幕分辨率下可能会失真
Css animation:对于复杂效果,实现起来成本高
SVG canvas 动画: 实现成本高,容易出现动画还原度低的情况
- 实现、维护成本高
- 复杂度过高会减慢渲染速度
视频:
-
占用空间大
-
没有交互(只能等视频播放完毕才能交互)
-
在播放时占用CPU内存较大
-
体验不好
如果需要一种更加简单、高效、性能好、还原度高的动画方案, Lottie 动画是一种可行性较高的方案。
-
能够100% 还原设计师给出的各种复杂动画效果;
-
json 文件的大小比 gif 文件小很多;
-
能够非常方便的控制动画播放,如:速率、范围;
-
当涉及到图形颜色的真实表示时,Lottie文件不会因压缩而损失质量。GIF文件通常使用过时的压缩方法(如抖动)来减少再现图形所需的颜色数量。
Lottie 不适用的场景:
- 给 View 本身添加动画(如:从右下角到移动到页面中,并逐渐放大的过渡效果)
- 动画中有动态内容(如:需要显示一个远程获取的动态数据)
- 动画中需要复杂的蒙板、遮罩,对动画性能会有较大影响
简介
Lottie是 airbnb 开源的可应用于Android,iOS,Web,React Native和Windows动画库, 本质上是一套跨平台的动画解决方案。它提供了一套完整的从 AE 到各个终端的工具流,设计师通过 AE 的 Bodymovin 插件将做的动画导出成一套定义好的 json 文件,之后再通过 Lottie 各端的库就可以实现动画效果,动画还原度 100%。
lottie-web官网:
lottie 动画 :
小程序支持:
- 微信小程序
developers.weixin.qq.com/miniprogram...
- 支付宝小程序
opendocs.alipay.com/mini/compon...
lottie-web支持特性最多,可以实现较为复杂的动画,控制动画的播放,监听动画各个阶段的事件。
lottie-web的使用方法, 有三种渲染方式 svg, canvas, html, 一般常用 svg, canvas
安装
npm install lottie-web
导入
javascript
import lottie from 'lottie-web'
使用
调用lottie.loadAnimation()来启动动画。它将一个对象作为唯一参数:
- AnimationData:包含导出的动画数据的对象。
- path:动画对象的相对路径。(animationData和path是互斥的)
- loop:true/false
- autoplay: true / false 自动播放
- name:动画名称以供将来参考
- renderer: 'svg' / 'canvas' / 'html' 设置渲染器
- container:渲染动画的 dom 元素
rust
let anim = lottie.loadAnimation({
container: element,// the dom element that will contain the animation
renderer: 'svg',
loop: true,
autoplay: true,
path: 'data.json' // the path to the animation json
// animationData: jsonAnim
});
控制动画播放的方法:
ini
anim.play();
...
名称 | 描述 |
---|---|
animation.play | 播放该动画,从目前停止的帧开始播放 |
stop | 停止播放该动画,回到第 0 帧 |
pause | 暂停该动画,在当前帧停止并保持 |
goToAndStop | animation.goToAndStop(value, isFrame);跳到某个时刻/帧并停止。isFrame(默认 false)指示 value 表示帧还是时间(毫秒) |
goToAndPlay | animation.goToAndPlay(value, isFrame);跳到某个时刻/帧并进行播放 |
goToAndStop | animation.goToAndStop(30, true);跳转到第 30 帧并停止 |
playSegments | animation.playSegments(arr, forceFlag);arr 可以包含两个数字或者两个数字组成的数组,forceFlag 表示是否立即强制播放该片段 animation.playSegments([10,20], false);播放完之前的片段,播放 10-20 帧 animation.playSegments([[0,5],[10,18]], true);直接播放 0-5 帧和 10-18 帧 |
setSpeed | animation.setSpeed(speed);设置播放速度,speed 为 1 表示正常速度 |
setDirection | animation.setDirection(direction);设置播放方向,1 表示正向播放,-1 表示反向播放 |
destroy | animation.destroy();删除该动画,移除相应的元素标签等。在 unmount 的时候,需要调用该方法 |
监听事件:
javascript
anim.addEventListener('data_ready', () => {
// 网络json加载完成
console.log(`🚀🚀🚀 ~ data_ready:`)
})
anim.addEventListener('complete', () => {
// 动画播放完成 loop设置false时触发
console.log(`🚀🚀🚀 ~ complete:`)
})
...
名称 | 描述 |
---|---|
data_ready | 加载完 json 动画 |
complete | 播放完成(循环播放下不会触发) |
loopComplete | 当前循环下播放(循环播放/非循环播放)结束时触发 |
enterFrame | 每进入一帧就会触发,播放时每一帧都会触发一次,stop 方法也会触发 |
segmentStart | 每进入一帧就会触发,播放时每一帧都会触发一次,stop 方法也会触发 |
DOMLoaded | 动画相关的 dom 已经被添加到 html 后触发 |
destroy | 将在动画删除时触发 |
Lottie 动画性能测试
方案 | 大小 | FPS | CPU 占用率 | GPU 占用 | 内存 | DOM Nodes |
---|---|---|---|---|---|---|
Gif 动画 | 769.58KB(尺寸150*136) | 60fps | 2.7% | 12.5MB | 37M | 435 |
Lottie 动画 | 272KB(尺寸440*400) | 60fps | 11.8% | 7.3MB | 37.8M | 1188 |
GIF
Lottie
通过以上数据分析,可知 Lottie 动画的配置文件较小,帧率到达60fps,GPU 占用低,内存与 Gif 动画相差不大,lottie动画会调用 requestAnimationFrame,cpu占用会高一些,综合性能较好。
注意事项
-
需要UI会使用AE软件,并且有一些优化点是需要做动效时候注意的
-
在不需要 Lottie 动画时,需要及时卸载 Lottie 动画组件
-
lottie不及时卸载、重复渲染会导致dom节点增加,cpu升高,不停的调用 requestAnimationFrame,导致动画出现异常
-
某个页面动画比较多的时候可以使用缓存,例如:vue中使用keep-alive
感兴趣可以深入了解下原理~
Lottie动画Json结构:
结构层
:可以读取到动画画布的宽高,帧数,背景色,时间,起始关键帧,结束帧等信息。asset
:图片资源信息集合,这里放置的是 制作动画时引用的图片资源。layers
:图层集合,这里可以获取到多少图层,每个图层的开始帧 结束帧等。shapes
:元素集合,可以获取到每个图层都包含多个动画元素。
。。。。。。