一种动画框架Lottie的解析(三)—— 框架结构

版本记录

版本号 时间
V1.0 2017.09.16

前言

app中好的炫的动画可以让用户耳目一新,为产品增色不少,关于动画的实现我们可以用基本动画、关键帧动画、序列帧动画以及基于CoreGraphic的动画等等,接下来这几篇我不介绍系统给的这几种动画绘制方法,给大家介绍的是一种动画框架。感兴趣的可以看我上面几篇。
1. 一种动画框架Lottie的解析(一)—— 基本介绍(一)
2. 一种动画框架Lottie的解析(二)—— 基本介绍(二)

框架架构

下面我们看一下框架架构。


框架类详述

1. CAAnimationGroup+LOTAnimatableGroup

看一下接口

@interface CAAnimationGroup (LOTAnimatableGroup)

+ (nullable CAAnimationGroup *)LOT_animationGroupForAnimatablePropertiesWithKeyPaths:(nonnull NSDictionary> *)properties;

@end

它是CAAnimationGroup的一个分类,名字是LOTAnimatableGroup

2. CADisplayLink

看一下接口

#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
#import 

@interface CADisplayLink : NSObject

+ (CADisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)sel;
- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode;
- (void)invalidate;

@end
#endif

它继承自NSObject。

3. CALayer+Compat

看接口

#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
#import 
#import 

@interface CALayer (Compat)

@property (nonatomic, assign) BOOL allowsEdgeAntialiasing;

@end

#endif

它是CALayer的分类,名字是Compat。

4. CGGeometry+LOTAdditions

该类与图形的几何特征,Core Graphics Geometry Additions

5. LOTAnimatableBoundsValue

看一下接口

@interface LOTAnimatableBoundsValue : NSObject 

- (instancetype)initWithSizeValues:(NSDictionary *)sizeValue frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) CGRect initialBounds;

@end

6. LOTAnimatableColorValue

看接口

@interface LOTAnimatableColorValue : NSObject 

- (instancetype)initWithColorValues:(NSDictionary *)colorValues frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) UIColor *initialColor;

@end

7. LOTAnimatableLayer

看一下接口

@interface LOTAnimatableLayer : CALayer

- (instancetype)initWithLayerDuration:(NSTimeInterval)duration NS_DESIGNATED_INITIALIZER;

@property (nonatomic, readonly) NSTimeInterval layerDuration;

@end

8. LOTAnimatableNumberValue

看接口

@interface LOTAnimatableNumberValue : NSObject 

- (instancetype)initWithNumberValues:(NSDictionary *)numberValues frameRate:(NSNumber *)frameRate;
- (void)remapValuesFromMin:(NSNumber *)fromMin
                   fromMax:(NSNumber *)fromMax
                     toMin:(NSNumber *)toMin
                     toMax:(NSNumber *)toMax;

- (void)remapValueWithBlock:(CGFloat (^)(CGFloat inValue))remapBlock;

@property (nonatomic, readonly) NSNumber *initialValue;

@end

9. LOTAnimatablePointValue

看接口

@interface LOTAnimatablePointValue : NSObject 

- (instancetype)initWithPointValues:(NSDictionary *)pointValues frameRate:(NSNumber *)frameRate;
- (void)remapPointsFromBounds:(CGRect)frombounds toBounds:(CGRect)toBounds;

@property (nonatomic, readonly) CGPoint initialPoint;
@property (nonatomic, assign) BOOL usePathAnimation;

@end

10. LOTAnimatableScaleValue

看接口

@interface LOTAnimatableScaleValue : NSObject 

- (instancetype)initWithScaleValues:(NSDictionary *)scaleValues frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) CATransform3D initialScale;

@end

11. LOTAnimatableShapeValue

看接口

@interface LOTAnimatableShapeValue : NSObject 

- (instancetype)initWithShapeValues:(NSDictionary *)shapeValues frameRate:(NSNumber *)frameRate closed:(BOOL)closed;

@property (nonatomic, readonly) UIBezierPath *initialShape;

@end

12. LOTAnimatableValue

这个是一个协议

@protocol LOTAnimatableValue 

- (CAKeyframeAnimation *)animationForKeyPath:(NSString *)keypath;
- (BOOL)hasAnimation;

@end

13. LOTAnimationCache

看接口

#import 

@class LOTComposition;

@interface LOTAnimationCache : NSObject

+ (instancetype)sharedCache;

- (void)addAnimation:(LOTComposition *)animation forKey:(NSString *)key;
- (LOTComposition *)animationForKey:(NSString *)key;

@end

14. LOTAnimationTransitionController

看接口

#import 
#import 

/** LOTAnimationTransitionController
 *
 *  This class creates a custom UIViewController transisiton animation
 *  using a Lottie animation to transition between two view controllers
 *  The transition can use custom defined layers in After Effects for to/from
 * 
 *  When referencing After Effects layers the animator masks the to/from viewController
 *  with the referenced layer.
 *
 */

@interface LOTAnimationTransitionController : NSObject 

/**
 The initializer to create a new transition animation.
 
 @param animation The name of the Lottie Animation to load for the transition
 
 @param fromLayer The name of the custom layer to mask the fromVC screenshot with. 
 If no layer is specified then the screenshot is added behind the Lottie Animation
 
 @param toLayer The name of the custom layer to mask the toVC screenshot with.
 If no layer is specified then the screenshot is added behind the Lottie Animation
 and a fade transition is performed along with the Lottie animation.

 */
- (instancetype)initWithAnimationNamed:(NSString *)animation
                        fromLayerNamed:(NSString *)fromLayer
                          toLayerNamed:(NSString *)toLayer;

@end

#endif

15. LOTAnimationView

看接口

@interface LOTAnimationView : LOTView

+ (instancetype)animationNamed:(NSString *)animationName NS_SWIFT_NAME(init(name:));
+ (instancetype)animationNamed:(NSString *)animationName inBundle:(NSBundle *)bundle NS_SWIFT_NAME(init(name:bundle:));
+ (instancetype)animationFromJSON:(NSDictionary *)animationJSON NS_SWIFT_NAME(init(json:));

...    ...

@end

16. LOTAnimationView_Compat

#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR

#import 
@compatibility_alias LOTView UIView;

#else

#import 
@compatibility_alias LOTView NSView;

typedef NS_ENUM(NSInteger, LOTViewContentMode) {
    LOTViewContentModeScaleToFill,
    LOTViewContentModeScaleAspectFit,
    LOTViewContentModeScaleAspectFill,
    LOTViewContentModeRedraw,
    LOTViewContentModeCenter,
    LOTViewContentModeTop,
    LOTViewContentModeBottom,
    LOTViewContentModeLeft,
    LOTViewContentModeRight,
    LOTViewContentModeTopLeft,
    LOTViewContentModeTopRight,
    LOTViewContentModeBottomLeft,
    LOTViewContentModeBottomRight,
};

#endif

17. LOTAnimationView_Internal

看接口

#import "LOTAnimationView.h"

typedef enum : NSUInteger {
  LOTConstraintTypeAlignToBounds,
  LOTConstraintTypeAlignToLayer,
  LOTConstraintTypeNone
} LOTConstraintType;

@interface LOTAnimationState : NSObject

- (instancetype _Nonnull)initWithDuration:(CGFloat)duration layer:(CALayer * _Nullable)layer frameRate:(NSNumber * _Nullable)framerate;

- (void)setAnimationIsPlaying:(BOOL)animationIsPlaying;
- (void)setAnimationDoesLoop:(BOOL)loopAnimation;
- (void)setAnimatedProgress:(CGFloat)progress;
- (void)setAnimationSpeed:(CGFloat)speed;

@property (nonatomic, readonly) BOOL loopAnimation;
@property (nonatomic, readonly) BOOL animationIsPlaying;

// Model Properties
@property (nonatomic, readonly) CGFloat animatedProgress;
@property (nonatomic, readonly) CGFloat animationDuration;
@property (nonatomic, readonly) CGFloat animationSpeed;

@property (nonatomic, readonly) CALayer * _Nullable layer;

@end

@interface LOTAnimationView ()

@property (nonatomic, readonly) LOTComposition * _Nonnull sceneModel;
@property (nonatomic, strong) LOTAnimationState *_Nonnull animationState;
@property (nonatomic, copy, nullable) LOTAnimationCompletionBlock completionBlock;

@end

18. LOTAsset

看接口

#import 
#import 

NS_ASSUME_NONNULL_BEGIN

@class LOTLayerGroup;
@class LOTLayer;
@class LOTAssetGroup;

@interface LOTAsset : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary
                  withBounds:(CGRect)bounds
               withFramerate:(NSNumber * _Nullable)framerate
              withAssetGroup:(LOTAssetGroup * _Nullable)assetGroup;

@property (nonatomic, readonly, nullable) NSString *referenceID;
@property (nonatomic, readonly, nullable) NSNumber *assetWidth;
@property (nonatomic, readonly, nullable) NSNumber *assetHeight;

@property (nonatomic, readonly, nullable) NSString *imageName;
@property (nonatomic, readonly, nullable) NSString *imageDirectory;

@property (nonatomic, readonly, nullable) LOTLayerGroup *layerGroup;

@end

NS_ASSUME_NONNULL_END

19. LOTAssetGroup

看接口

#import 
#import 

@class LOTAsset;
@class LOTLayerGroup;
@interface LOTAssetGroup : NSObject

- (instancetype _Nonnull)initWithJSON:(NSArray * _Nonnull)jsonArray;

- (void)buildAssetNamed:(NSString * _Nonnull)refID
             withBounds:(CGRect)bounds
           andFramerate:(NSNumber * _Nullable)framerate;

- (void)finalizeInitialization;

- (LOTAsset * _Nullable)assetModelForID:(NSString * _Nonnull)assetID;

@end

20. LOTComposition

看一下接口

#import 
#import 

@class LOTLayerGroup;
@class LOTLayer;
@class LOTAssetGroup;

@interface LOTComposition : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;

@property (nonatomic, readonly) CGRect compBounds;
@property (nonatomic, readonly) NSNumber *startFrame;
@property (nonatomic, readonly) NSNumber *endFrame;
@property (nonatomic, readonly) NSNumber *framerate;
@property (nonatomic, readonly) NSTimeInterval timeDuration;
@property (nonatomic, readonly) LOTLayerGroup *layerGroup;
@property (nonatomic, readonly) LOTAssetGroup *assetGroup;

@end

21. LOTCompositionLayer

看一下接口

#import 
#import "LOTAnimationView_Compat.h"

@class LOTLayerGroup;
@class LOTAssetGroup;

@interface LOTCompositionLayer : CALayer

- (instancetype)initWithLayerGroup:(LOTLayerGroup *)layerGroup
                    withAssetGroup:(LOTAssetGroup *)assetGroup
                        withBounds:(CGRect)bounds;

- (void)addSublayer:(LOTView *)view
       toLayerNamed:(NSString *)layer;

- (void)layoutCustomChildLayers;

@end

22. LOTEllipseShapeLayer

看接口

#import "LOTAnimatableLayer.h"
#import "LOTModels.h"

@interface LOTEllipseShapeLayer : LOTAnimatableLayer

- (instancetype)initWithEllipseShape:(LOTShapeCircle *)circleShape
                                fill:(LOTShapeFill *)fill
                              stroke:(LOTShapeStroke *)stroke
                                trim:(LOTShapeTrimPath *)trim
                           transform:(LOTShapeTransform *)transform
                        withLayerDuration:(NSTimeInterval)duration;

@end

23. LOTGroupLayerView

看接口

#import 
#import "LOTAnimatableLayer.h"

@class LOTShapeGroup;
@class LOTShapeTransform;
@class LOTShapeFill;
@class LOTShapeStroke;
@class LOTShapeTrimPath;

@interface LOTGroupLayerView : LOTAnimatableLayer

- (instancetype)initWithShapeGroup:(LOTShapeGroup *)shapeGroup
                         transform:(LOTShapeTransform *)previousTransform
                              fill:(LOTShapeFill *)previousFill
                            stroke:(LOTShapeStroke *)previousStroke
                          trimPath:(LOTShapeTrimPath *)previousTrimPath
                      withLayerDuration:(NSTimeInterval)duration;

@property (nonatomic, readonly) LOTShapeGroup *shapeGroup;
@property (nonatomic, readonly) LOTShapeTransform *shapeTransform;
@property (nonatomic, assign) BOOL debugModeOn;

@end

24. LOTHelpers.h

#ifndef LOTHelpers_h
#define LOTHelpers_h

#import "UIColor+Expanded.h"
#import "CGGeometry+LOTAdditions.h"

#endif /* LOTHelpers_h */

25. LOTLayer

看一下接口

@interface LOTLayer : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary
              withCompBounds:(CGRect)compBounds
               withFramerate:(NSNumber *)framerate
              withAssetGroup:(LOTAssetGroup *)assetGroup;

@property (nonatomic, readonly) NSString *layerName;
@property (nonatomic, readonly) NSString *referenceID;

...   ...

@end

26. LOTLayerGroup

看一下接口

#import 
#import 

NS_ASSUME_NONNULL_BEGIN

@class LOTLayer;
@class LOTAssetGroup;

@interface LOTLayerGroup : NSObject

- (instancetype)initWithLayerJSON:(NSArray *)layersJSON
                       withBounds:(CGRect)bounds
                    withFramerate:(NSNumber * _Nullable)framerate
                   withAssetGroup:(LOTAssetGroup * _Nullable)assetGroup;

@property (nonatomic, readonly) NSArray  *layers;

- (LOTLayer *)layerModelForID:(NSNumber *)layerID;
- (LOTLayer *)layerForReferenceID:(NSString *)referenceID;

@end

NS_ASSUME_NONNULL_END

27. LOTLayerView

看接口

#import "LOTPlatformCompat.h"
#import "LOTAnimatableLayer.h"

#import "LOTModels.h"

@interface LOTLayerView : LOTAnimatableLayer

- (instancetype)initWithModel:(LOTLayer *)model inLayerGroup:(LOTLayerGroup *)layerGroup;

- (void)LOT_addChildLayer:(CALayer *)childLayer;

@property (nonatomic, readonly) LOTLayer *layerModel;
@property (nonatomic, assign) BOOL debugModeOn;

@end

28. LOTMask

看接口

@interface LOTMask : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) BOOL closed;
@property (nonatomic, readonly) BOOL inverted;
@property (nonatomic, readonly) LOTMaskMode maskMode;
@property (nonatomic, readonly) LOTAnimatableShapeValue *maskPath;
@property (nonatomic, readonly) LOTAnimatableNumberValue *opacity;

@end

29. LOTMaskLayer

看接口

@interface LOTMaskLayer : LOTAnimatableLayer

- (instancetype)initWithMasks:(NSArray *)masks inLayer:(LOTLayer *)layer;

@property (nonatomic, readonly) NSArray *masks;


@end

30. LOTModels.h

#ifndef LOTModels_h
#define LOTModels_h

#import "CAAnimationGroup+LOTAnimatableGroup.h"
#import "LOTAnimatableBoundsValue.h"
#import "LOTAnimatableColorValue.h"
#import "LOTAnimatableNumberValue.h"
#import "LOTAnimatablePointValue.h"
#import "LOTAnimatableScaleValue.h"
#import "LOTAnimatableShapeValue.h"
#import "LOTAnimatableValue.h"
#import "LOTComposition.h"
#import "LOTLayer.h"
#import "LOTMask.h"
#import "LOTShapeCircle.h"
#import "LOTShapeFill.h"
#import "LOTShapeGroup.h"
#import "LOTShapePath.h"
#import "LOTShapeRectangle.h"
#import "LOTShapeStroke.h"
#import "LOTShapeTransform.h"
#import "LOTShapeTrimPath.h"
#import "LOTLayerGroup.h"
#import "LOTAsset.h"

#endif /* LOTModels_h */

31. LOTPlatformCompat.h

#ifndef LOTPlatformCompat_h
#define LOTPlatformCompat_h

#import "TargetConditionals.h"

#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR

#import 

#else

#import 
#import "UIColor.h"
#import "UIBezierPath.h"
#import "CADisplayLink.h"
#import "CALayer+Compat.h"
#import "NSValue+Compat.h"

NS_INLINE NSString *NSStringFromCGRect(CGRect rect) {
    return NSStringFromRect(rect);
}

NS_INLINE NSString *NSStringFromCGPoint(CGPoint point) {
    return NSStringFromPoint(point);
}

typedef NSEdgeInsets UIEdgeInsets;

#endif
#endif

32. LOTRectShapeLayer

看接口

@interface LOTRectShapeLayer : LOTAnimatableLayer

- (instancetype)initWithRectShape:(LOTShapeRectangle *)rectShape
                             fill:(LOTShapeFill *)fill
                           stroke:(LOTShapeStroke *)stroke
                             trim:(LOTShapeTrimPath *)trim
                        transform:(LOTShapeTransform *)transform
                     withLayerDuration:(NSTimeInterval)duration;

@end

33. LOTShapeCircle

看接口

@interface LOTShapeCircle : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) LOTAnimatablePointValue *position;
@property (nonatomic, readonly) LOTAnimatablePointValue *size;

@end

34. LOTShapeFill

@interface LOTShapeFill : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) BOOL fillEnabled;
@property (nonatomic, readonly) LOTAnimatableColorValue *color;
@property (nonatomic, readonly) LOTAnimatableNumberValue *opacity;

@end

35. LOTShapeGroup

@interface LOTShapeGroup : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate compBounds:(CGRect)compBounds;

@property (nonatomic, readonly) NSArray *items;

+ (id)shapeItemWithJSON:(NSDictionary *)itemJSON frameRate:(NSNumber *)frameRate compBounds:(CGRect)compBounds;

@end

36. LOTShapeLayerView

@interface LOTShapeLayerView : LOTAnimatableLayer

- (instancetype)initWithShape:(LOTShapePath *)shape
                         fill:(LOTShapeFill *)fill
                       stroke:(LOTShapeStroke *)stroke
                         trim:(LOTShapeTrimPath *)trim
                    transform:(LOTShapeTransform *)transform
                 withLayerDuration:(NSTimeInterval)duration;

@end

37. LOTShapePath

@interface LOTShapePath : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) BOOL closed;
@property (nonatomic, readonly) NSNumber *index;
@property (nonatomic, readonly) LOTAnimatableShapeValue *shapePath;

@end

38. LOTShapeRectangle

@interface LOTShapeRectangle : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) LOTAnimatablePointValue *position;
@property (nonatomic, readonly) LOTAnimatablePointValue *size;
@property (nonatomic, readonly) LOTAnimatableNumberValue *cornerRadius;

@end

39. LOTShapeStroke

@interface LOTShapeStroke : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) BOOL fillEnabled;
@property (nonatomic, readonly) LOTAnimatableColorValue *color;
@property (nonatomic, readonly) LOTAnimatableNumberValue *opacity;
@property (nonatomic, readonly) LOTAnimatableNumberValue *width;
@property (nonatomic, readonly) LOTLineCapType capType;
@property (nonatomic, readonly) LOTLineJoinType joinType;

@property (nonatomic, readonly) NSArray *lineDashPattern;

@end

40. LOTShapeTransform

@interface LOTShapeTransform : NSObject

+ (instancetype)transformIdentityWithCompBounds:(CGRect)compBounds;

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate compBounds:(CGRect)compBounds;

@property (nonatomic, readonly) CGRect compBounds;
@property (nonatomic, readonly) LOTAnimatablePointValue *position;
@property (nonatomic, readonly) LOTAnimatablePointValue *anchor;
@property (nonatomic, readonly) LOTAnimatableScaleValue *scale;
@property (nonatomic, readonly) LOTAnimatableNumberValue *rotation;
@property (nonatomic, readonly) LOTAnimatableNumberValue *opacity;

@end

41. LOTShapeTrimPath

@interface LOTShapeTrimPath : NSObject

- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;

@property (nonatomic, readonly) LOTAnimatableNumberValue *start;
@property (nonatomic, readonly) LOTAnimatableNumberValue *end;
@property (nonatomic, readonly) LOTAnimatableNumberValue *offset;
@end

42. LOTStrokeShapeLayer

@interface LOTStrokeShapeLayer : CAShapeLayer

@property CGFloat trimStart;
@property CGFloat trimEnd;
@property CGFloat trimOffset;

@end

43. Lottie.h

@import Foundation;
#ifndef Lottie_h
#define Lottie_h

//! Project version number for Lottie.
FOUNDATION_EXPORT double LottieVersionNumber;

//! Project version string for Lottie.
FOUNDATION_EXPORT const unsigned char LottieVersionString[];

#import "LOTAnimationTransitionController.h"
#import "LOTAnimationView.h"

#endif /* Lottie_h */

44. NSValue+Compat

NSValue的一个分类

#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
#import 

@interface NSValue (Compat)

+ (NSValue *)valueWithCGRect:(CGRect)rect;
+ (NSValue *)valueWithCGPoint:(CGPoint)point;

@property (nonatomic, readonly) CGRect CGRectValue;
@property(nonatomic, readonly) CGPoint CGPointValue;

@end

#endif

45. UIBezierPath

@interface UIBezierPath : NSObject 

+ (UIBezierPath *)bezierPath;
+ (UIBezierPath *)bezierPathWithRect:(CGRect)rect;

...  ...

@end

46. UIColor

@interface UIColor : NSObject 

+ (UIColor *)colorWithWhite:(CGFloat)white alpha:(CGFloat)alpha;

...  ...

@end

47. UIColor+Expanded

UIColor的一个分类

@interface UIColor (UIColor_Expanded)
@property (nonatomic, readonly) CGColorSpaceModel colorSpaceModel;
@property (nonatomic, readonly) BOOL canProvideRGBComponents;

...  ...

@end

后记

未完,待续~~~

你可能感兴趣的:(一种动画框架Lottie的解析(三)—— 框架结构)