这是我参与8月更文挑战的第2天,活动详情查看: 8月更文挑战
介绍
Lottie是一个适用于Android,iOS,Web和Windows的库,它在AE中使用Bodymovin插件将动画导出为JSON格式的文件,可以在移动端和web端原生支持。详见:官网
而且你可以通过Lottie的全局方法控制动画的帧率,方向,销毁等等。
在这里可以看到Lottie的一些作品集 -- codepen
使用
installation
npm install --save react-lottie
这里使用的是react-lottie,其他框架可以在github上找对应的库。 下面的代码就是项目中的具体实现,效果见上面的图片。其中遇到了两个坑,下面会有介绍
//引入方式和官方文档不同,有坑
import Lottie from 'react-lottie';
// 使用到的JSON数据
import animationData from './loginAnimation/data.json'
//这里只展示了用到的代码
preventMaskClick = (e) => {
e.preventDefault();
return false;
}
render() {
//这里是页面响应式样式的添加
let clientHeight = document.documentElement.clientHeight
let clientWidth = document.documentElement.clientWidth
let scalew = clientWidth / 1920
let scaleh = clientHeight / 1080
let marginTop = clientHeight * (1 - scaleh) / -2
let marginleft = clientWidth * (1 - scalew) / -2
let lottieStyle = {
position: 'absolute',
margin: `${marginTop}px auto auto ${marginleft}px`,
transform: `scale(${scalew}, ${scaleh})`
}
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animationData
};
return (
<div className={styles.login}>
<Lottie
options={defaultOptions}
width={clientWidth}
height={clientHeight}
style={{ ...lottieStyle }}
isStopped={false}
isPaused={false} />
<div style={{ position: 'absolute', margin: '0 0', width: '100%', height: '100%' }} onClick={this.preventMaskClick}></div>
</div>
}
遇到的问题
- 首先是引入方式 官网给出的代码是这样的:
import Lottie from 'react-lottie';
import * as animationData from './pinjump.json'
但是这样会报错:# lottie.js:6229 Error: <svg> attribute viewBox: Expected number, “0 0 undefined undefi…
网上找了一圈,发现了解决方法和原因,源码我还没有看,解释如下:
从源代码里发现animData的数据被封装在一个default的大对象中,所以取不到。再回去仔细观察代码,发现引入animationData时用了 “* as”,也就是把json数据导入为一个装在default的大对象中了。将 “* as”去掉,直接导入json数据,问题解决。可能是lottie升级之后数据格式要求变了,而react-lottie使用demo还没改
-
其次是在Lottie中动画图片显示不出来 打开控制台查看,发现是路径问题。这里有两种解决方法:
第一种是使用网络图片,并将JSON文件中"assets": [{"u": "images/",}]删除, 将"assets": [{"p": "",}]的值修改为网络图片路径
第二种是直接将图片数据装换成base64格式,"assets": [{"p": "",}]的值修改为对应的图片数据。
-
第三个问题是由于动画是后加上的,所以存在图片大小和页面适配问题 可以看到代码中有关于适配的代码部分,主要是需要自己计算出缩放比例,使用transform: scale进行缩放。
-
之后就是阻止Lottie动画点击事件,这个是有配置的,但是我设置了没有起到效果。所以用了div覆盖上去,然后阻止默认事件。
扩展
关于深入原理方面,可以参考腾讯VTeam技术团队的文章。 主要涉及到JSON文件的各个参数的作用和意义 # 深度剖析Lottie动画原理