共计 2754 个字符,预计需要花费 7 分钟才能阅读完成。
问题背景
有一天我们的 UI 设计师找到我说,要把页面中我自己用程序写的动画,换成他们给的 json 动画,原因是有的动画很复杂,自己写起来达不到他们的预期效果(写到这里我突然想到一个问题,这么复杂的动画为什么不使用 gif。。。。坐我对面的安卓开发小哥答因为 gif 播放的时候可能质量不高不流畅,好吧我信了)我:????客户端可以加 json 动画,H5 页面没听说过可以读 json 动画哎设计师一脸肯定,说可以的,有 web 版本。写到这里,我真的要好好夸一波我们的设计师妹子了,几乎很多蛮好的解决方法都是在他们的“逼迫”之下找到的(哦,她们还会写 H5 页面。。。要我有何用系列那问题来了,怎么在 H5 页面里面使用 json 动画呢
如何在 H5 页面内使用 json 动画
这时候设计师甩了一个链接给我,看这里 lottie-web;我点进去了解了一下,是 Airbnb 开源的一个动画库,该库可以完成很多酷炫动画,使用起来也很简单,设计师只需要通过 AE 做成的动画导出 JSON 文件,然后前端使用 Lottie 直接加载 JSON 文件生成动画,既不需要设计师切 N 多 gif,也不需要前端去进行复杂绘制了,一举两得,并且,Lottie 全平台可用,ios、Android、web、React Native 都可以,且占用内存少,加载流畅。(这么个神仙东西我为什么现在才发现。。
说了这么多,那怎么在 H5 页面里面使用呢?很简单了,设计师生成的文件夹发给你 (设计师那边只用在 AE 中加个 lottie 插件,导出就行了),打开之后应该是这样子的,打开 demo.html 就知道是怎么用的了(所以我还在这里写什么技术文章玩笑归玩笑,其实在使用中还是碰到了很多坑的,这里记录几个使用时注意的地方
1.demo.html 里面有很多内联的东西,使用时堆积在页面内不好看
仔细看一下,其实 demo.html 把 js 和 json 都放进去了,这时候我们可以把 js 和 json 单独分出来,js 的话可以使用 cdn 上提供的地址
<script type=”text/javascript” src=”https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.4.3/lottie.min.js”></script>
动画需要的 json 数据放在 data.json 文件里面,但是给出的 json 文件里面的数据格式是这样的(太长了 截不完那如果你要在单独的一个 html 里面使用 script 的方式引入 json 文件的话,会报错,所以需要修改 json 文件,在前面加上变量,赋值。如下图:这样你可以通过像引入 js 文件的方式一样的引入该 json
<script type=”text/javascript” src=”./data.json”></script>
这样可用的 demo.html 就缩减成了下面这样
<html xmlns=”http://www.w3.org/1999/xhtml”>
<meta charset=”UTF-8″>
<head>
<style>
body{
background-color:black;
margin: 0px;
height: 100%;
overflow: hidden;
}
#lottie{
background-color:#fff;
width:100%;
height:100%;
display:block;
overflow: hidden;
transform: translate3d(0,0,0);
text-align: center;
opacity: 1;
}
</style>
</head>
<body>
<div id=”lottie”></div>
<script type=”text/javascript” src=”https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.4.3/lottie.min.js”></script>
<script type=”text/javascript” src=”./data.json”></script>
<script>
var params = {
container: document.getElementById(‘lottie’),
renderer: ‘svg’,
loop: true,
autoplay: true,
animationData: animationData
};
var anim;
anim = lottie.loadAnimation(params);
</script>
</body>
</html>
当然,你如果使用的是 js 模块化编程的话,可以不用更改 data.json,直接 import 进来就行了,如下:
import animationData from ‘./data.json’
使动画适配移动端
之所以觉得这是个坑是因为,设计师给我的动画是全屏且非透明底的,然后她要求我将这个动画以宽度 100% 高度垂直居中截取的方式定位,我在浏览器里面试了下,360*640 屏幕下,宽度 100%,表现形式是这样的(看上去是高度 100% 宽度适配居中 两边漏出了黑色的背景色,见下图蓝色框起来的部分)换成 iPhone X 的屏幕下,相反,表现出来是宽度 100% 高度适配居中,上下漏出黑色背景色,见下图蓝色框起来的部分(究其原因是因为 iphonex 屏幕较长这个布局好熟悉哇,跟 img 的 object-fit 属性取值为 contain 的时候表现一致(object-fit 也是宝藏,有兴趣的同学可以去研究一下,非常好用)
我这里解决设计师的需求主要增加下面的代码:
js 部分:
setTimeout(function() {
document.getElementsByTagName(‘svg’)[0].style.height = ‘auto’;
}, 50);
css 部分:(给 lottie 增加 flex 布局)
#lottie {
width:100%;
height:100%;
transform: translate3d(0,0,0);
text-align: center;
opacity: 1;
position: absolute;
top: 0;
left: 0;
z-index: 3;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
最终效果:
总结
以上图片截图都是静态的,实际是有一个动态效果的,我不知道怎么添加动图就没弄了,感兴趣的可以试一下。适用范围:我感觉一般全屏的或者局部很复杂的动画可以使用这个方法一试,比 gif 要流畅,兼容性也做得不错,一些安卓产品比较酷炫的开屏就是使用的这个方法,H5 页面的话,简单动画一般自己程序实现就可以,还可以避免踩坑。
参考链接:lottie 官网