Lottie是什么?
用影片制作软件adobe after effects cc可以设计一个在app上显示的动画效果,安装bodymovin插件后可以用其导出一份该动画的json。Lottie实现了Android/iOS/React Native 三个平台对该 json 文件的解析和渲染。
通过插件导出的文件如下
<img src="http://upload-images.jianshu.io/upload_images/1840221-759f1c1aee3ebc0a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width=400>
- demo.html可以直接运行看到动画效果
- images和templateCards.json直接放到bundle里供lottie调用显示动画
性能
1. 内存
方法:找了两个动画json作为测试对象,一个是球形下拉动画,一个是多张图片变换成字母A的动画。分别查看结束时的内存情况。
结果:从图片上看内存占用分别是,21k左右和43k左右,内存占用还是非常小的。
2. 帧率
方法:进入目标工程内,待内存和帧率平稳后播放动画,查看帧率。
结果:帧率保持在59和60
从以上两个动画的json效果看,lottie的性能表现非常好。
查看了一下官方说明,在以下情况下会对性能有影响
- 如果没有mask和mattes,那么性能和内存非常好,没有bitmap创建,大部分操作都是简单的cavas绘制。
- 如果存在mattes,将会创建2~3个bitmap。bitmap在动画加载到window时被创建,被window删除时回收。所以不宜在RecyclerView中使用包涵mattes或者mask的动画,否则会引起bitmap抖动。除了内存抖动,mattes和mask中必要的bitmap.eraseColor()和canvas.drawBitmap()也会降低动画性能。对于简单的动画,在实际使用时性能不太明显。
- 如果在列表中使用动画,推荐使用缓存LottieAnimationView.setAnimation(String, CacheStrategy) 。
功能支持
动画效果的支持范围,对业务有比较大的意义,查看发现一般的功能都可以满足。目前虽然支持图片图层,但不支持远程图片下载,在使用时这个功能是肯定要做进去的。渐变色也是很常用的,但目前尚未支持。
目前支持的AE特性
Keyframe Interpolation 关键帧插值
Linear Interpolation 线性(关键帧)插值
Bezier Interpolation 贝塞尔插值
Hold Interpolation 定格插值
Rove Across Time 漂浮插值(漂浮穿梭时间 )
Spatial Bezier 空间插值Solids 固态层
Transform Anchor Point 描点变换
Transform Position 位置变换
Transform Scale 缩放变换
Transform Rotation 旋转变换
Transform Opacity 透明度变换Masks 蒙版
Path 路径
Opacity 透明度
Multiple Masks (additive) 多个蒙版(叠加模式)Track Mattes 遮罩模式
Alpha Matte 带alaha通道的遮罩Parenting 父子关系
Multiple Parenting 多级父子层
Nulls 空对象Shape Layers 形状层
Anchor Point 描点
Position 位置
Scale 缩放
Rotation 旋转
Opacity 透明度
Path 路径
Group Transforms (Anchor point, position, scale etc) 组变换
Rectangle (All properties) 矩形路径(所有属性)
Ellipse (All properties) 椭圆路径(所有属性)
Multiple paths in one group 一个组里的多个路径Stroke (shape layer) 描边(形状层)
Stroke Color 描边颜色
Stroke Opacity 描边透明度
Stroke Width 描边宽度
Line Cap 描边端点(圆头,平头)
Dashes 描边断点Fill (shape layer) 填充(形状层)
Fill Color 填充颜色
Fill Opacity 填充透明度Trim Paths (shape layer) 修剪路径(形状层)
Trim Paths Start 修剪路径起点
Trim Paths End 修剪路径终点
Trim Paths Offset 修剪路径偏移Layer Features图层特征
Precomps 预合成(几个图层打包在一起控制)
Image Layers 图片层
Shape Layers 形状层
Null Layers 空层
Solid Layers 固态层
Parenting Layers 父子层
Alpha Matte Layers 带alaha通道的遮罩层
未来计划支持的AE特性
- Even-Odd winding paths 判断点在图形内的一种算法
- Merge Shapes 合并图层
- Trim Shapes Individually feature of Trim Paths 修剪路径
- Expressions 表达式
- 3d Layer support 3d层
- Gradients 渐变
- Polystar shapes (Can convert to vector path as a workaround) 多边形
- Alpha inverted mask 反相alpha蒙版
配置分析
- assetes 资源
- layers
- ip 开始帧
- op 结束帧
- fr 帧速率(ip,op,fr计算出动画时间)
- w 宽度
- h 高度
- layer
| 名称 | 定义 |
| ------| ------ | ------ |
| nm | layer的名称,唯一|
| ind | layer的Id,唯一 |
| ty | layer的类型,可以是数字从0开始代表percomp、solid、image、null等在LOTLayer有定义 |
| refId | 和素材资源有关 |
| parentID | 父层的id |
| ip | inframe |
| op | outframe |
| h,w | 搞和宽,嵌套层有使用 |
| sw,sh | 固态层的宽高 |
| sc | 固态层颜色 |
| tt | 遮罩类型 |
| masksProperties | 蒙版的数组 |
| shapes | 形状数组,有gr(形状),st(描边),fl(填充),tr(固态变换),sh(路径),等等 在LOTShapeGroup内可以找到,和支持的功能项意义对应 |
不难发现,json的结构和支持功能是意义对应的,推测在对应实现的layer上也是一一对应的。
原理分析
实现基于QuartzCore对layer的绘图,通过在一个根layer上遍历配置数据添加子layer来实现动画的合并。用Core Animation做矢量动画实现。
- 读取json配置,创建LOTAnimationView
- 分析json,生成LOTComposition类型的model
- 分析model内的子动画model,生成对应的LOTCompositionLayer类型layer
- 同时按照层级关系添加layer到根layer上
- 播放动画
以前我们要在各个端实现一遍动画,使用lottie可以很大程度提高开发效率,并增加app支持动态下发动效的能力。iOS基于layer实现,对性能消耗很小,在存储上json文件占用的空间也不多。但接入后仍需要做一些事情,比如不支持渐变、文字、在移动端无法编辑,这些都需要我们修改bodymuvin插件来支持。