lottie
是什么?
- 是airbnb出产的一款动效插件,现在支持开发侧的web/RN/Android/ios/Mac os,以及设计侧的AE。
web端的文档地址:Web - Lottie Docs
为什么要用?
web端动效的方式有几种:
- 给静图(jpg/jpeg/png/svg),通过设计口述或者作出动图,开发手写css/canvas来实现。
- 优势:灵活,所有动效都尽在开发的掌握。
- 劣势:开发时间长,沟通成本大,设计同学很难空口描述出想要的动效,也受开发的水平限制比较大。
- 给gif,开发用图片的形式嵌入。
- 优势:开发成本低,沟通成本小。
- 劣势:gif一般都比较大,比较小的噪点又过于明显,性能的性价比不高;只能循环播放,较为死板。
- 雪碧图序列帧,给一个合成的雪碧图(静图),开发通过序列帧的方式进行动效操作。
- 优势:开发成本中等,沟通成本小。
- 劣势:合成的雪碧图文件大,且在不同屏幕分辨率下可能会失真。
- 使用lottie,设计同学给出json文件和图片文件夹,开发同学引入lottie插件,对json进行解析。
- 优势:开发成本中等,效果不受开发同学水平限制,只要设计画的出,开发就能实现出来;灵活,基点元素可以作为一个普通的dom节点进行定位,整个动画可以任意播放停止甚至倒放以及从某一帧开始播放(具体能实现的参见api文档),灵活度非常高。
- 劣势:在开发层面和设计层面看到的帧节点以及播放速度不同,需要持续进行沟通联调,沟通成本大;lottie插件打包前400+kb,打包后也有200+kb,会显著增加项目的大小。
- 使用svga,设计同学给出.svga文件,开发引入svga插件,对其进行解析。
- 优势:理论上来说同lottie
- 劣势:实际引入中,该插件已5个月没有更新代码,并且现存版本存在“无故清除canvas画布”的问题,不稳定性极高,不建议使用。
- 给静图(jpg/jpeg/png/svg),通过设计口述或者作出动图,开发手写css/canvas来实现。
- 几相对比下来,对于放在“主交互游戏”类活动页里的动效,lottie目前是最好的方案。
怎么用?
(建议使用npm引入,减少基础组件对网络的依赖)
// 项目目录运行
cnpm install lottie-web --save-dev
// 引入lottie
import lottie from 'lottie-web'
Vue.prototype.$lottie = lottie
// 加载动画(遵从vue声明周期,这个调用需在dom节点加载出来,也即是mount之后)
// 此处以扭蛋的 加载机器日常状态动画 为例
let machineNormal = document.querySelector('#machineNormal')
this.normalAni = this.$lottie.loadAnimation({
container: machineNormal, // the dom element
renderer: 'canvas',
loop: true,
autoplay: true,
path: 'static/machine_normal.json', // the animation data
})
使用lottie的过程中,需要注意什么?
引入过程中
- lottie动画加载需要一个dom节点,这个dom节点可被任意操纵位置,动画加载完毕后整个dom的宽高会被填充为动画的宽高,也即是设计给出的动画过程中最宽、最高的那个数值。
- 同样因为lottie动画加载需要一个dom节点,所以加载动画的方法需在mount周期或者之后调用。
- 如果使用path参数引入json文件:
文件放在本地:
1. 图片也需放在本地,通过修改.json文件的assets里面每一项的u属性,可以自定义图片文件夹的名字。
例如:
{
"v": "5.5.8",
"fr": 24,
"ip": 1,
"op": 53,
"w": 662,
"h": 827,
"nm": "",
"ddd": 0,
"assets": [
{
"id": "image_0",
"w": 662,
"h": 827,
"u": "machine_img/", /* 这个就是文件夹的名字 */
"p": "img_0.png",
"e": 0
},
]
}
ii. 建议使用static文件夹存放,不受到打包的影响。
update如果使用的是vue-cli 3,那么放在public文件夹下,并且path直接写想要的文件名,例如:
this.lottie = this.$lottie.loadAnimation({
container: document.querySelector('#BindDom'), // the dom element that will contain the animation
renderer: 'svg',
loop: true,
autoplay: true,
path: 'data.json' // the path to the animation json
})
文件放在cdn:**
注意图片的文件夹应该与json文件放在同一目录下,例如:
/twist_egg/btn_gain.json
/twist_egg/btn_gain_img/img_0.png
动画运行过程中
- 在动画初始化的时候,lottie提供生命周期以感知动画的加载状态,主要提供以下几种:
- complete
- loopComplete
- enterFrame
- segmentStart
- config_ready (when initial config is done)
- data_ready (when all parts of the animation have been loaded)
- DOMLoaded (when elements have been added to the DOM)
- destroy
其中DOMLoaded理论上是最晚能感知到的周期,也即是“动画加载完成”。但实际使用下来,只有使用canvas形式加载动效的时候,这个事件才是所有图片全部加载完成;其余情况(svg,html),都只是“开始拉取图片”,还是会展示给用户图片加载的整个过程。
并且,即使使用canvas加载,如果json文件与对应的图片文件夹都是云端也就是cdn的形式拉取的话,依旧无法感知到所有图片加载的过程。所以如果有强需求,需要用户完全不感知图片加载,建议将文件放在本地并以canvas形式加载。
- lottie提供destroy的api以清空画布,但是在destroy旧动画 -> load新动画这个过程中,会有非常明显的全屏闪动,这是由于画布重新生成需要时间造成的,建议使用dom的显隐切换而不是画布的destroy来切换同一块动效的不同状态。
- 可任意使用onComplete的事件监听,不会发生事件的重新绑定。
- lottie不提供原生的缓停事件,但是可以通过提供的setSpeed方法进行多段调整速度,已达到缓停的效果。