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插件來支持。