Lottie 是一个很好的动画库,不同于FaceBook 的 POP,Lottie 主要是重现由AE(Adobe After Effects)实现的动画,具体方法是AE 导出一个json,Lottie 读取json 进行较为炫酷的动画。
lottie 动画
动画原理
一个完整动画View由很多个子Layer 组成,每个子Layer中主要通过shapes(形状),masks(蒙版),transform三大部分进行动画。
通过读取Json文件 可以获取到每个子Layer 的shapes,masks,以及出现时间,消失时间,Transform 各个属性的关键帧数组
动画通过给CompositionLayer (所有的子layer都添加在这个Layer 上)的 “CurrentFrame” 属性添加一个CABaseAnimation 来实现
所有的子Layer根据CurrentFrame 属性的变化,根据Json中的关键帧数组计算出自己的当前状态进行显示。(下面有介绍计算方法)
动画原理图
动画原理图
为方便理解,做了一个草图。图片的右侧部分代表layer 的层级结构,左侧代表动画的进行过程。
从加载Json到展示动画的流程
Json 转 Model
Json 的第一个入口为 LOTComposition,以下是核心代码
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary
withAssetBundle:(NSBundle *)bundle {
NSNumber *width = jsonDictionary[@"w"];
NSNumber *height = jsonDictionary[@"h"];
if (width && height) {
CGRect bounds = CGRectMake(0, 0, width.floatValue, height.floatValue);
_compBounds = bounds;
}
//整体关键帧 信息
_startFrame = [jsonDictionary[@"ip"] copy];
_endFrame = [jsonDictionary[@"op"] copy];
_framerate = [jsonDictionary[@"fr"] copy];
if (_startFrame && _endFrame && _framerate) {
NSInteger frameDuration = (_endFrame.integerValue - _startFrame.integerValue) - 1;
NSTimeInterval timeDuration = frameDuration / _framerate.floatValue;
_timeDuration = timeDuration;
}
//图片信息
NSArray *assetArray = jsonDictionary[@"assets"];
if (assetArray.count) {
_assetGroup = [[LOTAssetGroup alloc] initWithJSON:assetArray withAssetBundle:bundle withFramerate:_framerate];
}