有个加载动画如下图所示:
这个动画可以拆分三个部分; 分别是灯笼上下跳动, 灯光闪烁以及彩旗飘动;
灯笼上下跳动和灯光闪烁部分都比较好处理, 但是彩旗那则有点麻烦;
通过 AE 的动画源文件, 可以看到彩旗飘动分为两部分:
分别是路径过渡动画和旋转动画.
麻烦的地方就在于本人对 AE 不熟, 没办法直接获得各个关键帧的路径数据(请教了下部门内的设计师, 貌似他也不能直接获得);
这时候就想到了 Lottie; 如果把彩旗飘动动画用 bodymovin 插件导出, 那么岂不是在 JSON 文件就可以看到路径数据了?
然而事情并没有想的那么简单!
在精灵图在 Lottie web 动画中的应用文章中已经知道 w 和 h 表示画布高度和宽度, 而 assets 则表示动画所涉及的图片资源;
但是并不清楚 layers 中那一堆天书一样的结构是啥意思! 更别说从中找到所需要的路径数据了!
而且使用导出的 JSON 文件实现的简单示例中彩旗没有渐变颜色!
怎么办?
重要的话只说一遍!
不要一到需要撸源码的时候就怂!
当然撸源码也是需要方法的;
首先渲染器设置为 svg, 因为如果选择 canvas 渲染器则没有办法很直观的看到结构;
其次关掉自动播放, 动画没有播放数据也就不会动态变化;
完成这两个设置之后就可以看到静态数据了, 然后调试代码找到静态数据的规则, 就不难看懂 JSON 文件了, 同时也能查出没有渐变颜色到底是代码 bug 还是数据缺失!
初始结构和数据如图;
需要着重注意图中红框部分的生成规则;
因为过程较复杂就不详细阐述调试过程了, 只列出关键点:
入口函数 loadAnimation
layers 分类处理
由此可知 layers 应该是对应 AE 中的图层, 而其 ty 属性则是图层类型的意思, 比如 4 应该是形状图层;
测试可知 2 表示图像图层.
layers 变换处理
由上图可知 layers.ks 应该就是图层的变换属性了;
各属性分别表示如下:
o 透明度; r 旋转; p 位置; a 锚点; s 缩放;
具体计算规则可以去对应的方法中查看.
shapes 图层内容分类处理
layers.shapes 对应 AE 图层中内容, 主要用于绘制图形;
gr 在 SVG 渲染器中对应 Group 元素;
layers.shapes.it 则承载 shapes 的绘制信息, 包括轮廓, 变换, 颜色等.
shapes 变换处理
shapes.it.ty 表示 shapes 绘制信息的类型, tr 表示变换信息;
其属性含义和 layers 变换基本类似;
如果某个变换类型在动画过程中会发生变化, 那么其 k 属性值是一个数组, 数组中存储了属性变化过程;
比如彩旗的旋转属性在动画过程中会发生变化;
s 表示开始值, e 表示结束值;
上述数据的意思是彩旗开始从正 10 度旋转为负 10 度, 然后又从负 10 度旋转为正 10 度等;
生成最终变换矩阵的方法为 applyToMatrix:
shapes 渐变颜色处理
gf 表示渐变颜色信息;
其 g 属性表示渐变颜色数组;
每四位表示渐变颜色数组中的一个元素, 第一位表示该颜色的位置, 比如 0 表示位置在 0%, 接着的三位分别表示该颜色的 RGB 值; 因为颜色值范围为 [0,1], 那么(1,1,1) 也就对应 (255,255,255); 同理(0,0,0) 也就对应(0,0,0);
JSON 文件中的渐变数据为从黑色渐变为白色, 因此示例动画中彩旗渐变有问题, 就不是 Lottie 的 bug, 而是数据导出异常的问题了!
至于为什么会导出异常可能是设计师使用的属性不对, 毕竟 AE 中不同效果有很多种实现方式, 某些方式不能被 Lottie 导出也很正常.
既然现在已经知道了渐变颜色和什么属性有关, 那么也没必要修改 AE 源文件了, 直接修改 JSON 文件就好了.
把对应的渐变颜色转换为 [0-1] 表示即可:
修改渐变颜色 bug 示例
shapes 形状处理处理;
sh 表示形状信息;
在 SVG 渲染器中一般会用路径表示;
如果你对 SVG 的 PATH 指令熟悉的话, 也就不难看出 buildShapeString 方法正是生成路径指令的方法了;
需要的注意的是:
此时的路径数据和原始 JSON 文件中的路径数据并不相同, 比如原始 JSON 文件起点应该是[0,0], 但是代码中的起点是[24.5,-2];
原因在于原始 JSON 文件中的路径数据为相对数据, 需要进行一定的变换;
i 和 o 分别得加上对应位置的 v.
到此为止看懂天书一般的 JSON 文件应该是不存在什么问题了!
那么看懂 JSON 文件除了解决渐变颜色缺失的问题, 还有什么其它的作用呢?
原生实现
目前看来好处说大不大, 说小也不小!
比如可以根据 JSON 文件信息, 不使用 Lottie, 直接使用原生 SVG 代码来实现动画.
特别是在某些情况下出于资源大小或者性价比角度考虑, 不能引入 Lottie 代码库;
对于上边的彩旗动画来说, 可以在源代码中输出路径信息;
然后找到关键帧所对应的路径;
然后直接使用 SVG 原生的 animate 和 animateTransform 标签就可以实现了!
原生 SVG 实现
来源: https://juejin.im/post/5c442d9a518825261b7e1eed