Hello Lottie (lottie-web)

背景

实现一些动画效果,常用的方案是 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官网:

airbnb.io/lottie/#/we...

lottie 动画

lottiefiles.com/

小程序支持:

  • 微信小程序

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占用会高一些,综合性能较好。

注意事项

  1. 需要UI会使用AE软件,并且有一些优化点是需要做动效时候注意的

  2. 在不需要 Lottie 动画时,需要及时卸载 Lottie 动画组件

  3. lottie不及时卸载、重复渲染会导致dom节点增加,cpu升高,不停的调用 requestAnimationFrame,导致动画出现异常

  4. 某个页面动画比较多的时候可以使用缓存,例如:vue中使用keep-alive

感兴趣可以深入了解下原理~

juejin.cn/post/711304...

Lottie动画Json结构:

  1. 结构层:可以读取到动画画布的宽高,帧数,背景色,时间,起始关键帧,结束帧等信息。
  2. asset:图片资源信息集合,这里放置的是 制作动画时引用的图片资源。
  3. layers:图层集合,这里可以获取到多少图层,每个图层的开始帧 结束帧等。
  4. shapes:元素集合,可以获取到每个图层都包含多个动画元素。

。。。。。。

相关推荐
周亚鑫2 分钟前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
落魄小二11 分钟前
el-table 表格索引不展示问题
javascript·vue.js·elementui
y52364812 分钟前
Javascript监控元素样式变化
开发语言·javascript·ecmascript
Justinc.18 分钟前
CSS3新增边框属性(五)
前端·css·css3
fruge26 分钟前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia34 分钟前
vue中如何关闭eslint检测?
前端·javascript·vue.js
~甲壳虫35 分钟前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
嚣张农民41 分钟前
JavaScript中Promise分别有哪些函数?
前端·javascript·面试
光影少年1 小时前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_1 小时前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习