精准微动效解决之道-Lottie

微动效在项目中出现的频率越来越多,而且多数是非常复杂的,沟通、耗时、还原度等问题已成为开发人员的痛点,我们需要思考更高效的实现方式。

设计针对企鹅电竞App做了多种场景的微动效,包括icon、数字、按压态、滑动等效果,而现在主要谈谈icon在多终端上的效果实现。

设计效果

下面以logo动效作为本文主要说明案例,通常要实现这种效果都有哪些方式呢?

常见方式

  • 动态图片方式最典型的动图格式就要属GIF了,除了GIF之外还有很多格式,比如webp、apng等,但这两种图片格式需要特定的解码器,在解码耗时、体积、性能上还不是很理想,如果帧数较多的情况下在某些低端机下会出现掉帧的现象。
  • 逐帧动画方式帧动画的原理就是把动效导出为一套序列帧,然后通过脚本来控制每一张图片的播放,这种方式在各端都有广泛的应用,没有兼容性问题,但它的体积比起动态图片方式要大的多,另外这种方式也很耗内存,动画播放中前后两张替换的图片在很多元素并没有变化,重复的内容浪费了空间。
  • flash转canvas方式这种方式可以通过Flash CC与公司内部的工具Fanvas来转换,但这要求设计师必须制作flash动画,而目前AE已经是设计师的标配了,要转换成flash成本也挺高,所以这种方式也不可取。

难道就没有没有更好的实现方式了吗?

当然有,我们还有svg,svg也是动效制作的常见方案,它是基于矢量的,能够很好的处理图形大小的改变,多用于线条方面的动画,很适合这种场景,目前设计一般在AI中制作好素材,然后导入到AE中制作特效,那有没有办法将AE中做好的动效快速应到到移动端上呢?还真有,那就是最近比较火的Lottie框架。

Lottie介绍

Lottie 是Airbnb开源的一个动画框架,它提供了一套完整的跨平台动画实现流程,对IOS、Android、ReactNative三端提供支持,如下图所示,主要通过AE上的Bodymovin插件将制作好的动画导出成一个json文件,json文件中记录了每个元素的动画执行路径和执行时间,最后交由Lottie解析和渲染。

下面将分别介绍bodymovin插件的安装使用web端的应用以及Lottie在IOS与Android使用中遇到的问题

bodymovin插件安装使用

bodymovin的主要功能是将 AE 导出的动画在 Web 端执行,而Lottie的主要作用是将动画在移动端运行。

1.下载地址: https://github.com/bodymovin/bodymovin/releases

2.安装 ZXP Installer ( mac下需要注意将ZXP Installer 放到应用程序中才能生效 )

3.解压后找到 build/extension/中的bodymovin.zxp 拖拽到ZXP Installer中安装,成功后打开AE,勾选 首选项/常规/允许脚本写入文件和访问网络。

4.在AE/窗口/扩展中打开bodymovin,在bodymovin面板中设置好导出目录,然后点击Render按钮一键导出json文件以及相关的图片。

此外还可以在Settings中选择导出的形式,如选中Demo,会生成一个web页面,方便查看导出后的效果。

导出后的文件如图所示

web端应用

bodymovin插件本身是用于网页上呈现各种AE效果的一个开源库,在它的开源项目中包含了bodymovin.js,240kb,通过这个js文件读取json文件然后就可以在网页中渲染出动画了

另外项目作者给出了一个轻量版的js库(bodymovin_light.min.js)压缩后约130kb左右,效果也是一样的,在build/player中可以找到。

同时该js库也提供了丰富的API接口,更多API请参考 bodymovin Usage

  • anim.stop()
  • anim.pause()
  • anim.setSpeed(speed)
  • anim.goToAndStop(value, isFrame)
  • anim.goToAndPlay(value, isFrame)
  • anim.setDirection(direction)
  • anim.playSegments(segments, forceFlag)
  • anim.destroy()

利用这些接口基本能满足web端的效果实现,这里做了个demo,项目结构如下

  1. ├── bodymovin_light.min.js
  2. ├── data.json
  3. ├── images
  4. ├── img_0.png
  5. ├── img_1.png
  6. └── img_2.png
  7. └── index.html
  • 实现代码
  1. <div id="container"></div>
  2. <div id="btn-play" class="btn">播放</div>
  3. <div id="btn-pause" class="btn">暂停</div>
  4. <div id="btn-restart" class="btn">重新播放</div>
  5. <script src="./bodymovin_light.min.js"></script>
  6. <script>// <![CDATA[
  7. var container= document.getElementById('container');
  8. var animData = {
  9. container: container,
  10. autoplay:false,
  11. renderer: 'svg',//可设置为canvas
  12. loop: false,
  13. path: './data.json'
  14. };
  15. var anim = bodymovin.loadAnimation(animData);
  16. //播放
  17. var btnPlay = document.getElementById('btn-play');
  18. btnPlay.addEventListener('click', function(){
  19. anim.play();
  20. })
  21. //暂停
  22. var btnPause = document.getElementById('btn-pause');
  23. btnPause.addEventListener('click', function(){
  24. anim.pause();
  25. })
  26. //重新播放
  27. var btnRestart = document.getElementById('btn-restart');
  28. btnRestart.addEventListener('click', function(){
  29. anim.goToAndStop(0,0);
  30. anim.play();
  31. })
  32. // ]]></script>
  • 效果预览

IOS & Android上的应用

前面web端的实现还是比较顺利的,那Android和IOS上是否也是如此呢?这里以 IOS 作为实例说明,Lottie-ios 整个框架大概200多K,可以忽略增量问题。它的使用方式也很简单

  1. LOTAnimationView *lottieLogo = [LOTAnimationView animationNamed:@"data"];
  2. [self.view addSubview:lottieLogo];
  3. //play
  4. lottieLogo.animationProgress = 0;
  5. [lottieLogo play];
  6. //pause
  7. [lottieLogo pause];

但动画在IOS上显示却出问题了:

  1. 填充色覆盖了整个动画区域
  2. 中间的翅膀缩放动画消失了,整个动画的时间缩短了
  3. “企鹅电竞” 文字显示问题

解决方案

经过网上查询以及反复的摸索后,发现Lottie并不是完全支持AE中的某些属性,只能对AE源文件进行修改

1、不支持路径合成,把一些合成的路径关闭,如图“组1”中的路径1和路径2合成导致了填充色问题

2、尽量不使用预合成图层,需要将预合成中的所有图层都复制到主面板中,否则预合成中的动画可能会丢失。

修改前:

修改后:

3、文字显示问题,这个问题困扰了很久,无论是将文字转为路径或者蒙层的形式都不行,主要是lottie对文本的支持不好,最终是将文字在AI中制作好,然后导入到AE中解决。

修改前:

修改后:

最终效果

虽然现目前Lottie的项目文档中列举了所不支持的部分属性,设计师在制作动画时还需避免使用这些属性,不过Lottie项目的更新速度还是挺快的,比如之前是不支持位图的,现在也支持了,相信后面这些问题都能够逐一解决。

目前Lottie-ios还不支持的After Effects 特性

  • 形状图层填充规则(奇偶/非零缠绕)
  • 合并形状
  • 裁切路径中的个别裁切形状功能
  • 表达式
  • 3D图层
  • 图层样式渐变
  • 多边形形状
  • 反相Alpha蒙板

还需注意的问题

  1. 目前在使用bodymovin插件中,仍然有一些特效无法导出,如蒙层、粒子、光影特效,而Lottie也有一些AE属性未能支持,在AE效果制作中应尽量规避
  2. 如果AE中有AI文件,则会导出相应的位图,如果复杂度不是特别高,应尽量在AE中实现。
  3. 插件提供的bodymovin_light.min.js 还是比较大的,压缩后仍有130k+
  4. 目前Lottie支持安卓4.1、ios8以上,如果对系统兼容有特殊要求的,如ios7,建议放弃使用。

写在最后

在项目中如果需要在多终端实现这种复杂动画,bodymovin+lottie无疑是一种高效的实现方案,虽然有一些问题存在,但还是很值得在项目中推荐使用,但如果我们真碰上了插件无法导出又或者是放弃一些属性导致动画不完美的场景,该如何处理呢?下一篇“透明视频方案”将给出你答案。

3 Responses

发表评论