├── XAnimation
├── Assets
│ └── .gitkeep
└── Classes
│ ├── .gitkeep
│ ├── XAimationExtends
│ ├── LOTAnimationView+XALOTProAnimationView.h
│ ├── PublicHeaders
│ │ ├── XALOTBindControllerDataSource.h
│ │ ├── XALOTProAnimationViewDataSource.h
│ │ ├── XALOTProAnimationView.h
│ │ ├── XALOTProAnimationViewDelegate.h
│ │ ├── XALOTBindControllerDelegate.h
│ │ ├── UIView+XALottie.h
│ │ ├── CALayer+XALottie.h
│ │ └── XABindLottieController.h
│ ├── XALottieLocalLib.h
│ ├── Test
│ │ ├── XABindLottieHomeViewController.h
│ │ ├── XABindLottieDebugWindowRootViewController.h
│ │ ├── XABindLottieDebugWindow.h
│ │ ├── XABindLottieDebugWindowRootViewController.m
│ │ └── XABindLottieDebugWindow.m
│ ├── XABindLOTAnimationViewLayer.h
│ ├── XABindLOTAnimationView.h
│ ├── XABindLottieMiddleWare.h
│ ├── XALOTProAnimationView.m
│ ├── XALottieLocalLib.m
│ ├── XALOTProAnimationViewLayer.h
│ ├── XALOTProAnimationViewLayer.m
│ ├── XABindLOTAnimationView.m
│ ├── CALayer+XALottie.m
│ ├── UIView+XALottie.m
│ └── XABindLOTAnimationViewLayer.m
│ ├── RenderSystem
│ ├── LOTRenderNode.h
│ ├── AnimatorNodes
│ │ ├── LOTPathAnimator.h
│ │ ├── LOTPolygonAnimator.h
│ │ ├── LOTPolystarAnimator.h
│ │ ├── LOTCircleAnimator.h
│ │ ├── LOTRoundedRectAnimator.h
│ │ ├── LOTPathAnimator.m
│ │ └── LOTCircleAnimator.m
│ ├── InterpolatorNodes
│ │ ├── LOTArrayInterpolator.h
│ │ ├── LOTSizeInterpolator.h
│ │ ├── LOTPointInterpolator.h
│ │ ├── LOTColorInterpolator.h
│ │ ├── LOTNumberInterpolator.h
│ │ ├── LOTPathInterpolator.h
│ │ ├── LOTValueInterpolator.h
│ │ ├── LOTArrayInterpolator.m
│ │ ├── LOTNumberInterpolator.m
│ │ ├── LOTColorInterpolator.m
│ │ ├── LOTSizeInterpolator.m
│ │ ├── LOTPointInterpolator.m
│ │ ├── LOTTransformInterpolator.h
│ │ └── LOTPathInterpolator.m
│ ├── RenderNodes
│ │ ├── LOTFillRenderer.h
│ │ ├── LOTStrokeRenderer.h
│ │ ├── LOTRepeaterRenderer.h
│ │ ├── LOTGradientFillRender.h
│ │ ├── LOTRenderGroup.h
│ │ └── LOTFillRenderer.m
│ ├── ManipulatorNodes
│ │ ├── LOTTrimPathNode.h
│ │ └── LOTTrimPathNode.m
│ ├── LOTRenderNode.m
│ └── LOTAnimatorNode.h
│ ├── Private
│ ├── LOTCacheProvider.m
│ ├── LOTAnimationView_Internal.h
│ ├── LOTAnimationCache.m
│ ├── LOTInterpolatorCallback.m
│ ├── LOTValueCallback.m
│ └── LOTBlockCallback.m
│ ├── MacCompatibility
│ ├── CALayer+Compat.h
│ ├── CALayer+Compat.m
│ ├── NSValue+Compat.h
│ ├── NSValue+Compat.m
│ ├── LOTPlatformCompat.h
│ ├── UIColor.h
│ └── UIColor.m
│ ├── AnimatableLayers
│ ├── LOTMaskContainer.h
│ ├── LOTLayerContainer.h
│ ├── LOTCompositionContainer.h
│ └── LOTMaskContainer.m
│ ├── Extensions
│ ├── LOTHelpers.h
│ ├── LOTRadialGradientLayer.h
│ ├── LOTBezierPath.h
│ ├── UIColor+Expanded.h
│ └── LOTRadialGradientLayer.m
│ ├── Models
│ ├── LOTShapePath.h
│ ├── LOTShapeGroup.h
│ ├── LOTShapeTrimPath.h
│ ├── LOTShapeCircle.h
│ ├── LOTShapeRectangle.h
│ ├── LOTModels.h
│ ├── LOTShapeFill.h
│ ├── LOTLayerGroup.h
│ ├── LOTShapeTransform.h
│ ├── LOTShapePath.m
│ ├── LOTMask.h
│ ├── LOTAssetGroup.h
│ ├── LOTShapeCircle.m
│ ├── LOTShapeGradientFill.h
│ ├── LOTShapeRepeater.h
│ ├── LOTShapeTrimPath.m
│ ├── LOTShapeStar.h
│ ├── LOTAsset.h
│ ├── LOTShapeStroke.h
│ ├── LOTShapeRectangle.m
│ ├── LOTShapeFill.m
│ ├── LOTAsset.m
│ ├── LOTMask.m
│ ├── LOTLayerGroup.m
│ ├── LOTShapeGradientFill.m
│ ├── LOTShapeStar.m
│ ├── LOTShapeStroke.m
│ ├── LOTAssetGroup.m
│ ├── LOTShapeRepeater.m
│ ├── LOTShapeTransform.m
│ ├── LOTLayer.h
│ └── LOTShapeGroup.m
│ ├── AnimatableProperties
│ ├── LOTBezierData.h
│ ├── LOTKeyframe.h
│ └── LOTBezierData.m
│ └── PublicHeaders
│ ├── LOTAnimatedControl.h
│ ├── LOTCacheProvider.h
│ ├── LOTAnimationCache.h
│ ├── LOTAnimationView_Compat.h
│ ├── Lottie.h
│ ├── LOTAnimatedSwitch.h
│ ├── LOTComposition.h
│ ├── LOTInterpolatorCallback.h
│ ├── LOTValueCallback.h
│ ├── LOTAnimationTransitionController.h
│ └── LOTKeypath.h
├── _Pods.xcodeproj
├── Example
├── Tests
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── Tests-Prefix.pch
│ ├── Tests-Info.plist
│ └── Tests.m
├── XAnimation
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── Images.xcassets
│ │ ├── Contents.json
│ │ ├── paizi.imageset
│ │ │ ├── paizi.png
│ │ │ └── Contents.json
│ │ ├── chinalogo.imageset
│ │ │ ├── icons8-china-96.png
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── XAViewController.h
│ ├── XAAppDelegate.h
│ ├── classes
│ │ ├── BindLottieDemo
│ │ │ ├── TestBind0.h
│ │ │ ├── TestBind1.h
│ │ │ ├── TestBind2.h
│ │ │ ├── TestBind3.h
│ │ │ ├── TestBind4.h
│ │ │ ├── TestBind5.h
│ │ │ ├── TestBindLottieRootViewController.h
│ │ │ ├── TestBindLottieRootViewController.m
│ │ │ └── TestBind2.m
│ │ └── Resource
│ │ │ ├── qinkai2.json
│ │ │ └── qinkai_alpha.json
│ ├── XAnimation-Prefix.pch
│ ├── main.m
│ ├── XAViewController.m
│ ├── XAnimation-Info.plist
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── XAAppDelegate.m
├── Podfile
└── XAnimation.xcworkspace
│ └── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── .travis.yml
├── .gitignore
├── NOTICE THIRD PARTY
└── XAnimation.podspec
/XAnimation/Assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/XAnimation/Classes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_Pods.xcodeproj:
--------------------------------------------------------------------------------
1 | Example/Pods/Pods.xcodeproj
--------------------------------------------------------------------------------
/Example/Tests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/XAnimation/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/XAnimation/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/XAnimation/Images.xcassets/paizi.imageset/paizi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jd-opensource/XAnimation/HEAD/Example/XAnimation/Images.xcassets/paizi.imageset/paizi.png
--------------------------------------------------------------------------------
/Example/Tests/Tests-Prefix.pch:
--------------------------------------------------------------------------------
1 | // The contents of this file are implicitly included at the beginning of every test case source file.
2 |
3 | #ifdef __OBJC__
4 |
5 |
6 |
7 | #endif
8 |
--------------------------------------------------------------------------------
/Example/XAnimation/Images.xcassets/chinalogo.imageset/icons8-china-96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jd-opensource/XAnimation/HEAD/Example/XAnimation/Images.xcassets/chinalogo.imageset/icons8-china-96.png
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | use_frameworks!
2 |
3 | platform :ios, '10.0'
4 |
5 | target 'XAnimation_Example' do
6 | pod 'XAnimation', :path => '../'
7 |
8 | target 'XAnimation_Tests' do
9 | inherit! :search_paths
10 |
11 |
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/Example/XAnimation/XAViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // XAViewController.h
3 | // XAnimation
4 | //
5 | // Created by wangxiyuan on 09/14/2022.
6 | // Copyright (c) 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface XAViewController : UINavigationController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/XAnimation.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/XAnimation/XAAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // XAAppDelegate.h
3 | // XAnimation
4 | //
5 | // Created by wangxiyuan on 09/14/2022.
6 | // Copyright (c) 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface XAAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/LOTAnimationView+XALOTProAnimationView.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimationView+XALOTProAnimationView.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/29.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface LOTAnimationView ()
13 |
14 | @end
15 |
16 | NS_ASSUME_NONNULL_END
17 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/PublicHeaders/XALOTBindControllerDataSource.h:
--------------------------------------------------------------------------------
1 | //
2 | // XALOTBindControllerDataSource.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/4/11.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @protocol XALOTBindControllerDataSource
13 |
14 | @end
15 |
16 | NS_ASSUME_NONNULL_END
17 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/BindLottieDemo/TestBind0.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestBind0.h
3 | // XAnimation_Example
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | // Copyright © 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TestBind0 : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/BindLottieDemo/TestBind1.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestBind1.h
3 | // XAnimation_Example
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | // Copyright © 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TestBind1 : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/BindLottieDemo/TestBind2.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestBind2.h
3 | // XAnimation_Example
4 | //
5 | // Created by xiyuan wang on 2022/3/25.
6 | // Copyright © 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TestBind2 : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/BindLottieDemo/TestBind3.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestBind3.h
3 | // XAnimation_Example
4 | //
5 | // Created by xiyuan wang on 2022/3/31.
6 | // Copyright © 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TestBind3 : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/BindLottieDemo/TestBind4.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestBind4.h
3 | // XAnimation_Example
4 | //
5 | // Created by xiyuan wang on 2022/4/11.
6 | // Copyright © 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TestBind4 : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/BindLottieDemo/TestBind5.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestBind5.h
3 | // XAnimation_Example
4 | //
5 | // Created by xiyuan wang on 2022/4/13.
6 | // Copyright © 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TestBind5 : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/PublicHeaders/XALOTProAnimationViewDataSource.h:
--------------------------------------------------------------------------------
1 | //
2 | // XALOTProAnimationViewDataSource.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/31.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @protocol XALOTProAnimationViewDataSource
13 |
14 | @end
15 |
16 | NS_ASSUME_NONNULL_END
17 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XALottieLocalLib.h:
--------------------------------------------------------------------------------
1 | //
2 | // XALottieLocalLib.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface XALottieLocalLib : NSObject
13 |
14 | + (NSString *)filePathForLocalLibWithName:(NSString *)lottieName;
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/LOTRenderNode.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTRenderNode.h
3 | // Pods
4 | //
5 | // Created by brandon_withrow on 6/27/17.
6 | //
7 | //
8 |
9 | #import "LOTAnimatorNode.h"
10 |
11 | @interface LOTRenderNode : LOTAnimatorNode
12 |
13 | @property (nonatomic, readonly, strong) CAShapeLayer * _Nonnull outputLayer;
14 |
15 | - (NSDictionary * _Nonnull)actionsForRenderLayer;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Example/XAnimation/XAnimation-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | @import UIKit;
15 | @import Foundation;
16 | #endif
17 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/Test/XABindLottieHomeViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLottieHomeViewController.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | //
7 |
8 | #ifdef XABindLottieDebug
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface XABindLottieHomeViewController : UIViewController
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/Example/XAnimation/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // XAnimation
4 | //
5 | // Created by wangxiyuan on 09/14/2022.
6 | // Copyright (c) 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 | #import "XAAppDelegate.h"
11 |
12 | int main(int argc, char * argv[])
13 | {
14 | @autoreleasepool {
15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([XAAppDelegate class]));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Example/XAnimation/Images.xcassets/paizi.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "paizi.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/BindLottieDemo/TestBindLottieRootViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestBindLottieRootViewController.h
3 | // XAnimation_Example
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | // Copyright © 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface TestBindLottieRootViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/Test/XABindLottieDebugWindowRootViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLottieDebugWindowRootViewController.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | //
7 |
8 | #ifdef XABindLottieDebug
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface XABindLottieDebugWindowRootViewController : UINavigationController
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XABindLOTAnimationViewLayer.h:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLOTAnimationViewLayer.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/20.
6 | //
7 |
8 | #import
9 | #import "XABindLOTAnimationView.h"
10 | #import "XALOTProAnimationViewLayer.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface XABindLOTAnimationViewLayer : XALOTProAnimationViewLayer
15 |
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/Example/XAnimation/Images.xcassets/chinalogo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "icons8-china-96.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Private/LOTCacheProvider.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTCacheProvider.m
3 | // Lottie
4 | //
5 | // Created by punmy on 2017/7/8.
6 | //
7 | //
8 |
9 | #import "LOTCacheProvider.h"
10 |
11 | @implementation LOTCacheProvider
12 |
13 | static id _imageCache;
14 |
15 | + (id)imageCache {
16 | return _imageCache;
17 | }
18 |
19 | + (void)setImageCache:(id)cache {
20 | _imageCache = cache;
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XABindLOTAnimationView.h:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLOTAnimationView.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/20.
6 | //
7 |
8 | #import "XALOTProAnimationView.h"
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface XABindLOTAnimationView : XALOTProAnimationView
13 |
14 | @property (nonatomic, weak) UIView *hostView;
15 | @property (nonatomic, weak) CALayer *hostLayer;
16 |
17 |
18 | @end
19 |
20 | NS_ASSUME_NONNULL_END
21 |
--------------------------------------------------------------------------------
/XAnimation/Classes/MacCompatibility/CALayer+Compat.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Oleksii Pavlovskyi on 2/2/17.
3 | // Copyright (c) 2017 Airbnb. All rights reserved.
4 | //
5 |
6 | #include
7 |
8 | #if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
9 | #import
10 | #import
11 |
12 | @interface CALayer (Compat)
13 |
14 | @property (nonatomic, assign) BOOL allowsEdgeAntialiasing;
15 |
16 | @end
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/AnimatorNodes/LOTPathAnimator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTPathAnimator.h
3 | // Pods
4 | //
5 | // Created by brandon_withrow on 6/27/17.
6 | //
7 | //
8 |
9 | #import "LOTAnimatorNode.h"
10 | #import "LOTShapePath.h"
11 |
12 | @interface LOTPathAnimator : LOTAnimatorNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | shapePath:(LOTShapePath *_Nonnull)shapePath;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTArrayInterpolator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTArrayInterpolator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTValueInterpolator.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LOTArrayInterpolator : LOTValueInterpolator
14 |
15 | - (NSArray *)numberArrayForFrame:(NSNumber *)frame;
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/XAnimation/Classes/MacCompatibility/CALayer+Compat.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Oleksii Pavlovskyi on 2/2/17.
3 | // Copyright (c) 2017 Airbnb. All rights reserved.
4 | //
5 |
6 | #include
7 |
8 | #if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
9 | #import "CALayer+Compat.h"
10 |
11 | @implementation CALayer (Compat)
12 |
13 | - (BOOL)allowsEdgeAntialiasing { return NO; }
14 | - (void)setAllowsEdgeAntialiasing:(BOOL)allowsEdgeAntialiasing { }
15 |
16 | @end
17 |
18 | #endif
19 |
--------------------------------------------------------------------------------
/XAnimation/Classes/AnimatableLayers/LOTMaskContainer.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTMaskContainer.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/19/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTMask.h"
11 |
12 | @interface LOTMaskContainer : CALayer
13 |
14 | - (instancetype _Nonnull)initWithMasks:(NSArray * _Nonnull)masks;
15 |
16 | @property (nonatomic, strong, nullable) NSNumber *currentFrame;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/RenderNodes/LOTFillRenderer.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTFillRenderer.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 6/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTRenderNode.h"
10 | #import "LOTShapeFill.h"
11 |
12 | @interface LOTFillRenderer : LOTRenderNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | shapeFill:(LOTShapeFill *_Nonnull)fill;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/Resource/qinkai2.json:
--------------------------------------------------------------------------------
1 | {"v":"5.8.1","fr":30,"ip":0,"op":50,"w":192,"h":192,"nm":"logo192","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"logo192.png","cl":"png","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":-8,"s":[0],"e":[100]},{"t":49}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[96,96,0],"ix":2,"l":2},"a":{"a":0,"k":[96,96,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":-8,"op":51,"st":-8,"bm":0}],"markers":[]}
--------------------------------------------------------------------------------
/Example/XAnimation/classes/Resource/qinkai_alpha.json:
--------------------------------------------------------------------------------
1 | {"v":"5.8.1","fr":30,"ip":0,"op":30,"w":10,"h":10,"nm":"合成 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"logo512.png","cl":"png","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0],"e":[100]},{"t":29}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[5,5,0],"ix":2,"l":2},"a":{"a":0,"k":[256,256,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":30,"st":0,"bm":0}],"markers":[]}
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/AnimatorNodes/LOTPolygonAnimator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTPolygonAnimator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTAnimatorNode.h"
10 | #import "LOTShapeStar.h"
11 |
12 | @interface LOTPolygonAnimator : LOTAnimatorNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | shapePolygon:(LOTShapeStar *_Nonnull)shapeStar;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/AnimatorNodes/LOTPolystarAnimator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTPolystarAnimator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTAnimatorNode.h"
10 | #import "LOTShapeStar.h"
11 |
12 | @interface LOTPolystarAnimator : LOTAnimatorNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | shapeStar:(LOTShapeStar *_Nonnull)shapeStar;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/RenderNodes/LOTStrokeRenderer.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTStrokeRenderer.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/17/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTRenderNode.h"
10 | #import "LOTShapeStroke.h"
11 |
12 | @interface LOTStrokeRenderer : LOTRenderNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | shapeStroke:(LOTShapeStroke *_Nonnull)stroke;
16 |
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/ManipulatorNodes/LOTTrimPathNode.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTTrimPathNode.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/21/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTAnimatorNode.h"
10 | #import "LOTShapeTrimPath.h"
11 |
12 | @interface LOTTrimPathNode : LOTAnimatorNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | trimPath:(LOTShapeTrimPath *_Nonnull)trimPath;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/AnimatorNodes/LOTCircleAnimator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTCircleAnimator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/19/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTAnimatorNode.h"
10 | #import "LOTShapeCircle.h"
11 |
12 | @interface LOTCircleAnimator : LOTAnimatorNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | shapeCircle:(LOTShapeCircle *_Nonnull)shapeCircle;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/RenderNodes/LOTRepeaterRenderer.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTRepeaterRenderer.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/28/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTRenderNode.h"
10 | #import "LOTShapeRepeater.h"
11 |
12 | @interface LOTRepeaterRenderer : LOTRenderNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | shapeRepeater:(LOTShapeRepeater *_Nonnull)repeater;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/RenderNodes/LOTGradientFillRender.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTGradientFillRender.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTRenderNode.h"
10 | #import "LOTShapeGradientFill.h"
11 |
12 | @interface LOTGradientFillRender : LOTRenderNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | shapeGradientFill:(LOTShapeGradientFill *_Nonnull)fill;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/AnimatorNodes/LOTRoundedRectAnimator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTRoundedRectAnimator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/19/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTAnimatorNode.h"
10 | #import "LOTShapeRectangle.h"
11 |
12 | @interface LOTRoundedRectAnimator : LOTAnimatorNode
13 |
14 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
15 | shapeRectangle:(LOTShapeRectangle *_Nonnull)shapeRectangle;
16 |
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTSizeInterpolator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTSizeInterpolator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/13/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTValueInterpolator.h"
10 | #import "LOTValueDelegate.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface LOTSizeInterpolator : LOTValueInterpolator
15 |
16 | - (CGSize)sizeValueForFrame:(NSNumber *)frame;
17 |
18 | @property (nonatomic, weak, nullable) id delegate;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTPointInterpolator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTPointInterpolator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/12/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTValueInterpolator.h"
10 | #import "LOTValueDelegate.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface LOTPointInterpolator : LOTValueInterpolator
15 |
16 | - (CGPoint)pointValueForFrame:(NSNumber *)frame;
17 |
18 | @property (nonatomic, weak, nullable) id delegate;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # references:
2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/
3 | # * https://github.com/supermarin/xcpretty#usage
4 |
5 | osx_image: xcode7.3
6 | language: objective-c
7 | # cache: cocoapods
8 | # podfile: Example/Podfile
9 | # before_install:
10 | # - gem install cocoapods # Since Travis is not always on latest version
11 | # - pod install --project-directory=Example
12 | script:
13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/XAnimation.xcworkspace -scheme XAnimation-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty
14 | - pod lib lint
15 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Extensions/LOTHelpers.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTHelpers.h
3 | // Lottie
4 | //
5 | // Created by Brandon Withrow on 7/28/16.
6 | // Copyright © 2016 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #ifndef LOTHelpers_h
10 | #define LOTHelpers_h
11 |
12 | #import "UIColor+Expanded.h"
13 | #import "CGGeometry+LOTAdditions.h"
14 | #import "LOTBezierPath.h"
15 |
16 | #define ENABLE_DEBUG_LOGGING NO
17 | #define ENABLE_DEBUG_SHAPES NO
18 |
19 | #endif /* LOTHelpers_h */
20 |
21 | // TODO Feature Phase
22 | /*
23 | - Trim Path individually
24 | - Image Cache Support
25 | - Skew transform
26 | */
27 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Extensions/LOTRadialGradientLayer.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimationView
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/14/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 | #import
9 | #import
10 |
11 | @interface LOTRadialGradientLayer : CALayer
12 |
13 | @property CGPoint startPoint;
14 | @property CGPoint endPoint;
15 |
16 | @property (nonatomic, copy) NSArray *colors;
17 | @property (nonatomic, copy) NSArray *locations;
18 | @property (nonatomic, assign) BOOL isRadial;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/Test/XABindLottieDebugWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLottieDebugWindow.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | //
7 |
8 | #define XABindLottieDebug 1
9 |
10 | #ifdef XABindLottieDebug
11 |
12 | #import
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 |
17 | @interface XABindLottieDebugWindow : UIWindow
18 |
19 | @property (nonatomic, strong) UIWindow *appMainWindow;
20 |
21 | + (XABindLottieDebugWindow *)sharedInstance;
22 |
23 | + (double)screenWidth;
24 | + (double)screenHeight;
25 |
26 | @end
27 |
28 | NS_ASSUME_NONNULL_END
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/PublicHeaders/XALOTProAnimationView.h:
--------------------------------------------------------------------------------
1 | //
2 | // XALOTProAnimationView.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/29.
6 | //
7 |
8 | #import
9 | #import "XALOTProAnimationViewDataSource.h"
10 | #import "XALOTProAnimationViewDelegate.h"
11 |
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface XALOTProAnimationView : LOTAnimationView
16 |
17 | @property (nonatomic, weak) id dataSource;
18 | @property (nonatomic, weak) id delegate;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTColorInterpolator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTColorInterpolator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/13/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTValueInterpolator.h"
10 | #import "LOTPlatformCompat.h"
11 | #import "LOTValueDelegate.h"
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface LOTColorInterpolator : LOTValueInterpolator
16 |
17 | - (CGColorRef)colorForFrame:(NSNumber *)frame;
18 |
19 | @property (nonatomic, weak, nullable) id delegate;
20 |
21 | @end
22 |
23 | NS_ASSUME_NONNULL_END
24 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTNumberInterpolator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTNumberInterpolator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/11/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTValueInterpolator.h"
11 | #import "LOTValueDelegate.h"
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 | @interface LOTNumberInterpolator : LOTValueInterpolator
15 |
16 | - (CGFloat)floatValueForFrame:(NSNumber *)frame;
17 |
18 | @property (nonatomic, weak, nullable) id delegate;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapePath.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapePath.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | @interface LOTShapePath : NSObject
13 |
14 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
15 |
16 | @property (nonatomic, readonly) NSString *keyname;
17 | @property (nonatomic, readonly) BOOL closed;
18 | @property (nonatomic, readonly) NSNumber *index;
19 | @property (nonatomic, readonly) LOTKeyframeGroup *shapePath;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Private/LOTAnimationView_Internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimationView_Internal.h
3 | // Lottie
4 | //
5 | // Created by Brandon Withrow on 12/7/16.
6 | // Copyright © 2016 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef enum : NSUInteger {
12 | LOTConstraintTypeAlignToBounds,
13 | LOTConstraintTypeAlignToLayer,
14 | LOTConstraintTypeNone
15 | } LOTConstraintType;
16 |
17 | @interface LOTAnimationView ()
18 |
19 | - (CALayer * _Nullable)layerForKey:(NSString * _Nonnull)keyname;
20 | - (NSArray * _Nonnull)compositionLayers;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/XAnimation/Classes/MacCompatibility/NSValue+Compat.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Oleksii Pavlovskyi on 2/2/17.
3 | // Copyright (c) 2017 Airbnb. All rights reserved.
4 | //
5 |
6 | #include
7 |
8 | #if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
9 | #import
10 |
11 | @interface NSValue (Compat)
12 |
13 | + (NSValue *)valueWithCGRect:(CGRect)rect;
14 | + (NSValue *)valueWithCGPoint:(CGPoint)point;
15 |
16 | @property (nonatomic, readonly) CGRect CGRectValue;
17 | @property(nonatomic, readonly) CGPoint CGPointValue;
18 | @property (nonatomic, readonly) CGSize CGSizeValue;
19 |
20 | @end
21 |
22 | #endif
23 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeGroup.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShape.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/14/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface LOTShapeGroup : NSObject
13 |
14 | - (instancetype _Nonnull)initWithJSON:(NSDictionary *_Nonnull)jsonDictionary;
15 |
16 | @property (nonatomic, readonly, nonnull) NSString *keyname;
17 | @property (nonatomic, readonly, nonnull) NSArray *items;
18 |
19 | + (id _Nullable)shapeItemWithJSON:(NSDictionary * _Nonnull)itemJSON;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XABindLottieMiddleWare.h:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLottieMiddleWare.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/20.
6 | //
7 |
8 | #import
9 | #import "LOTLayerContainer.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface XABindLottieMiddleWare : NSObject
14 |
15 | //+ (void)didUpdateLayer:(LOTLayerContainer *)layer opacity:(float)opacity transform3D:(CATransform3D)transform3D;
16 |
17 | + (void)didUpdateLayer:(LOTLayerContainer *)layer frame:(NSNumber *)frame opacity:(CGFloat)opacity transform3DInfo:(NSDictionary *)transform3DInfo ;
18 |
19 | @end
20 |
21 | NS_ASSUME_NONNULL_END
22 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/RenderNodes/LOTRenderGroup.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTRenderGroup.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 6/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTRenderNode.h"
10 |
11 | @interface LOTRenderGroup : LOTRenderNode
12 |
13 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode * _Nullable)inputNode
14 | contents:(NSArray * _Nonnull)contents
15 | keyname:(NSString * _Nullable)keyname;
16 |
17 | @property (nonatomic, strong, readonly) CALayer * _Nonnull containerLayer;
18 |
19 | @end
20 |
21 |
22 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeTrimPath.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeTrimPath.h
3 | // LottieAnimator
4 | //
5 | // Created by brandon_withrow on 7/26/16.
6 | // Copyright © 2016 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | @interface LOTShapeTrimPath : NSObject
13 |
14 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
15 |
16 | @property (nonatomic, readonly) NSString *keyname;
17 | @property (nonatomic, readonly) LOTKeyframeGroup *start;
18 | @property (nonatomic, readonly) LOTKeyframeGroup *end;
19 | @property (nonatomic, readonly) LOTKeyframeGroup *offset;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTPathInterpolator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTPathInterpolator.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/13/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTValueInterpolator.h"
10 | #import "LOTPlatformCompat.h"
11 | #import "LOTBezierPath.h"
12 | #import "LOTValueDelegate.h"
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | @interface LOTPathInterpolator : LOTValueInterpolator
17 |
18 | - (LOTBezierPath *)pathForFrame:(NSNumber *)frame cacheLengths:(BOOL)cacheLengths;
19 |
20 | @property (nonatomic, weak, nullable) id delegate;
21 |
22 | @end
23 |
24 | NS_ASSUME_NONNULL_END
25 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/PublicHeaders/XALOTProAnimationViewDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // XALOTProAnimationViewDelegate.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/31.
6 | //
7 |
8 | #import
9 | @class XALOTProAnimationView;
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @protocol XALOTProAnimationViewDelegate
14 |
15 | - (void)animView:(XALOTProAnimationView *)animView didUpdateProgress:(CGFloat)progress;
16 |
17 | - (void)animView:(XALOTProAnimationView *)animView layerEnterForName:(NSString *)layerName;
18 | - (void)animView:(XALOTProAnimationView *)animView layerOutForName:(NSString *)layerName;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeCircle.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeCircle.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface LOTShapeCircle : NSObject
15 |
16 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
17 |
18 | @property (nonatomic, readonly) NSString *keyname;
19 | @property (nonatomic, readonly) LOTKeyframeGroup *position;
20 | @property (nonatomic, readonly) LOTKeyframeGroup *size;
21 | @property (nonatomic, readonly) BOOL reversed;
22 |
23 | @end
24 |
25 | NS_ASSUME_NONNULL_END
26 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeRectangle.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeRectangle.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | @interface LOTShapeRectangle : NSObject
13 |
14 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
15 |
16 | @property (nonatomic, readonly) NSString *keyname;
17 | @property (nonatomic, readonly) LOTKeyframeGroup *position;
18 | @property (nonatomic, readonly) LOTKeyframeGroup *size;
19 | @property (nonatomic, readonly) LOTKeyframeGroup *cornerRadius;
20 | @property (nonatomic, readonly) BOOL reversed;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/PublicHeaders/XALOTBindControllerDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // XALOTBindControllerDelegate.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/4/11.
6 | //
7 |
8 | #import
9 |
10 | @class XABindLottieController;
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @protocol XALOTBindControllerDelegate
15 |
16 | - (void)bindController:(XABindLottieController *)bindController didUpdateProgress:(CGFloat)progress;
17 | - (void)bindController:(XABindLottieController *)bindController layerEnterForName:(NSString *)layerName;
18 | - (void)bindController:(XABindLottieController *)bindController layerOutForName:(NSString *)layerName;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/XAnimation/Classes/AnimatableProperties/LOTBezierData.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTBezierData.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/10/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface LOTBezierData : NSObject
15 |
16 | - (instancetype)initWithData:(NSDictionary *)bezierData;
17 |
18 | @property (nonatomic, readonly) NSInteger count;
19 | @property (nonatomic, readonly) BOOL closed;
20 |
21 | - (CGPoint)vertexAtIndex:(NSInteger)index;
22 | - (CGPoint)inTangentAtIndex:(NSInteger)index;
23 | - (CGPoint)outTangentAtIndex:(NSInteger)index;
24 |
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTModels.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTModels.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #ifndef LOTModels_h
10 | #define LOTModels_h
11 |
12 | #import "LOTKeyframe.h"
13 | #import "LOTComposition.h"
14 | #import "LOTLayer.h"
15 | #import "LOTMask.h"
16 | #import "LOTShapeCircle.h"
17 | #import "LOTShapeFill.h"
18 | #import "LOTShapeGroup.h"
19 | #import "LOTShapePath.h"
20 | #import "LOTShapeRectangle.h"
21 | #import "LOTShapeStroke.h"
22 | #import "LOTShapeTransform.h"
23 | #import "LOTShapeTrimPath.h"
24 | #import "LOTLayerGroup.h"
25 | #import "LOTAsset.h"
26 | #import "LOTShapeGradientFill.h"
27 |
28 | #endif /* LOTModels_h */
29 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XALOTProAnimationView.m:
--------------------------------------------------------------------------------
1 | //
2 | // XALOTProAnimationView.m
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/29.
6 | //
7 |
8 | #import "XALOTProAnimationView.h"
9 | #import "XALOTProAnimationViewLayer.h"
10 |
11 | @implementation XALOTProAnimationView
12 |
13 | - (instancetype)initWithFrame:(CGRect)frame{
14 | self = [super initWithFrame:frame];
15 | if (self) {
16 | XALOTProAnimationViewLayer *layer = (XALOTProAnimationViewLayer *)self.layer;
17 | if ([layer isKindOfClass:[XALOTProAnimationViewLayer class]]) {
18 | layer.lotView = self;
19 | }
20 | }
21 | return self;
22 | }
23 |
24 | + (Class)layerClass{
25 | return [XALOTProAnimationViewLayer class];
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XALottieLocalLib.m:
--------------------------------------------------------------------------------
1 | //
2 | // XALottieLocalLib.m
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | //
7 |
8 | #import "XALottieLocalLib.h"
9 |
10 | @implementation XALottieLocalLib
11 |
12 | + (NSString *)filePathForLocalLibWithName:(NSString *)lottieName{
13 | NSURL *mockBundleURL = [[NSBundle mainBundle] URLForResource:@"XALottieResource" withExtension:@"bundle"]; //TODO
14 | if (mockBundleURL) {
15 | NSBundle *bundle = [NSBundle bundleWithURL:mockBundleURL]; //为nil会崩溃
16 | if (bundle) {
17 | NSString *filePath = [bundle pathForResource:lottieName ofType:@"json" inDirectory:@"lotlib"];
18 | return filePath;
19 | }
20 | }
21 | return nil;
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeFill.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeFill.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface LOTShapeFill : NSObject
15 |
16 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
17 |
18 | @property (nonatomic, readonly) NSString *keyname;
19 | @property (nonatomic, readonly) BOOL fillEnabled;
20 | @property (nonatomic, readonly) LOTKeyframeGroup *color;
21 | @property (nonatomic, readonly) LOTKeyframeGroup *opacity;
22 | @property (nonatomic, readonly) BOOL evenOddFillRule;
23 |
24 | @end
25 |
26 | NS_ASSUME_NONNULL_END
27 |
--------------------------------------------------------------------------------
/Example/Tests/Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Example/Tests/Tests.m:
--------------------------------------------------------------------------------
1 | //
2 | // XAnimationTests.m
3 | // XAnimationTests
4 | //
5 | // Created by wangxiyuan on 09/14/2022.
6 | // Copyright (c) 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | @import XCTest;
10 |
11 | @interface Tests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation Tests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
36 |
--------------------------------------------------------------------------------
/Example/XAnimation/XAViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // XAViewController.m
3 | // XAnimation
4 | //
5 | // Created by wangxiyuan on 09/14/2022.
6 | // Copyright (c) 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import "XAViewController.h"
10 | #import "TestBindLottieRootViewController.h"
11 |
12 | @interface XAViewController ()
13 |
14 | @end
15 |
16 | @implementation XAViewController
17 |
18 | - (void)viewDidLoad
19 | {
20 | [super viewDidLoad];
21 | TestBindLottieRootViewController *navRoot = [[TestBindLottieRootViewController alloc] init];
22 | [self pushViewController:navRoot animated:NO];
23 | }
24 |
25 | - (void)didReceiveMemoryWarning
26 | {
27 | [super didReceiveMemoryWarning];
28 | // Dispose of any resources that can be recreated.
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/XAnimation/Classes/MacCompatibility/NSValue+Compat.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Oleksii Pavlovskyi on 2/2/17.
3 | // Copyright (c) 2017 Airbnb. All rights reserved.
4 | //
5 |
6 | #include
7 |
8 | #if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
9 | #import "NSValue+Compat.h"
10 |
11 | @implementation NSValue (Compat)
12 |
13 | + (NSValue *)valueWithCGRect:(CGRect)rect {
14 | return [self valueWithRect:rect];
15 | }
16 |
17 | + (NSValue *)valueWithCGPoint:(CGPoint)point {
18 | return [self valueWithPoint:point];
19 | }
20 |
21 | - (CGRect)CGRectValue {
22 | return self.rectValue;
23 | }
24 |
25 | - (CGPoint)CGPointValue {
26 | return self.pointValue;
27 | }
28 |
29 | - (CGSize)CGSizeValue {
30 | return self.sizeValue;
31 | }
32 |
33 | @end
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTLayerGroup.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTLayerGroup.h
3 | // Pods
4 | //
5 | // Created by Brandon Withrow on 2/16/17.
6 | //
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @class LOTLayer;
15 | @class LOTAssetGroup;
16 |
17 | @interface LOTLayerGroup : NSObject
18 |
19 | - (instancetype)initWithLayerJSON:(NSArray *)layersJSON
20 | withAssetGroup:(LOTAssetGroup * _Nullable)assetGroup
21 | withFramerate:(NSNumber *)framerate;
22 |
23 | @property (nonatomic, readonly) NSArray *layers;
24 |
25 | - (LOTLayer *)layerModelForID:(NSNumber *)layerID;
26 | - (LOTLayer *)layerForReferenceID:(NSString *)referenceID;
27 |
28 | @end
29 |
30 | NS_ASSUME_NONNULL_END
31 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XALOTProAnimationViewLayer.h:
--------------------------------------------------------------------------------
1 | //
2 | // XALOTProAnimationViewLayer.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/4/1.
6 | //
7 |
8 | #import
9 | @class XALOTProAnimationView;
10 |
11 | typedef enum : NSUInteger {
12 | XALottieLayerStateUnStart = 0,
13 | XALottieLayerStateStart = 1,
14 | XALottieLayerStatePlaying = 2,
15 | XALottieLayerStateDone = 3,
16 | } XALottieLayerState;
17 |
18 | NS_ASSUME_NONNULL_BEGIN
19 |
20 | @interface XALOTProAnimationViewLayer : CALayer
21 |
22 | @property (nonatomic, weak) XALOTProAnimationView *lotView;
23 |
24 | - (XALottieLayerState)getStateForLayerID:(NSNumber *)layerID;
25 | - (void)setStateForLayerID:(NSNumber *)layerID state:(XALottieLayerState)state;
26 | - (void)cleanAllStates;
27 |
28 | @end
29 |
30 | NS_ASSUME_NONNULL_END
31 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTAnimatedControl.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimatedControl.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 8/25/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class LOTAnimationView;
12 | @class LOTComposition;
13 |
14 | @interface LOTAnimatedControl : UIControl
15 |
16 | // This class is a base class that is intended to be subclassed
17 |
18 | /**
19 | * Map a specific animation layer to a control state.
20 | * When the state is set all layers will be hidden except the specified layer.
21 | **/
22 |
23 | - (void)setLayerName:(NSString * _Nonnull)layerName forState:(UIControlState)state;
24 |
25 | @property (nonatomic, strong, readonly, nonnull) LOTAnimationView *animationView;
26 | @property (nonatomic, strong, nullable) LOTComposition *animationComp;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeTransform.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeTransform.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import "LOTKeyframe.h"
13 |
14 | @interface LOTShapeTransform : NSObject
15 |
16 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
17 |
18 | @property (nonatomic, readonly) NSString *keyname;
19 | @property (nonatomic, readonly) LOTKeyframeGroup *position;
20 | @property (nonatomic, readonly) LOTKeyframeGroup *anchor;
21 | @property (nonatomic, readonly) LOTKeyframeGroup *scale;
22 | @property (nonatomic, readonly) LOTKeyframeGroup *rotation;
23 | @property (nonatomic, readonly) LOTKeyframeGroup *opacity;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/XAnimation/Classes/MacCompatibility/LOTPlatformCompat.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTPlatformCompat.h
3 | // Lottie
4 | //
5 | // Created by Oleksii Pavlovskyi on 2/2/17.
6 | // Copyright (c) 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #ifndef LOTPlatformCompat_h
10 | #define LOTPlatformCompat_h
11 |
12 | #include
13 |
14 | #if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
15 |
16 | #import
17 |
18 | #else
19 |
20 | #import
21 | #import "UIColor.h"
22 | #import "CALayer+Compat.h"
23 | #import "NSValue+Compat.h"
24 | #import "UIBezierPath.h"
25 |
26 | NS_INLINE NSString *NSStringFromCGRect(CGRect rect) {
27 | return NSStringFromRect(rect);
28 | }
29 |
30 | NS_INLINE NSString *NSStringFromCGPoint(CGPoint point) {
31 | return NSStringFromPoint(point);
32 | }
33 |
34 | typedef NSEdgeInsets UIEdgeInsets;
35 |
36 | #endif
37 | #endif
38 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/PublicHeaders/UIView+XALottie.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+XALottie.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/20.
6 | //
7 |
8 | #import
9 | @class XABindLottieController;
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface UIView (XALottie)
13 |
14 | //init json , just root view need to bind.
15 | - (XABindLottieController *)bindLottieWithContentsOfURL:(nonnull NSURL *)url;
16 | - (XABindLottieController *)bindLottieWithAnimationNamed:(NSString *)animationNamed;
17 | - (XABindLottieController *)bindLottieWithFilePath:(NSString *)filePath;
18 |
19 | //every node view under root can bind a name of animated lottie-json-layer.
20 | - (void)bindLottieLayerName:(NSString *)lotLayerName;
21 | - (NSString *)bindLottieLayerName;
22 |
23 | - (XABindLottieController *)currentBindController;
24 |
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTValueInterpolator.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTValueInterpolator.h
3 | // Pods
4 | //
5 | // Created by brandon_withrow on 7/10/17.
6 | //
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 | #import "LOTValueDelegate.h"
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | @interface LOTValueInterpolator : NSObject
16 |
17 | - (instancetype)initWithKeyframes:(NSArray *)keyframes;
18 |
19 | @property (nonatomic, weak, nullable) LOTKeyframe *leadingKeyframe;
20 | @property (nonatomic, weak, nullable) LOTKeyframe *trailingKeyframe;
21 | @property (nonatomic, readonly) BOOL hasDelegateOverride;
22 |
23 | - (void)setValueDelegate:(id _Nonnull)delegate;
24 |
25 | - (BOOL)hasUpdateForFrame:(NSNumber *)frame;
26 | - (CGFloat)progressForFrame:(NSNumber *)frame;
27 |
28 | @end
29 |
30 | NS_ASSUME_NONNULL_END
31 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/PublicHeaders/CALayer+XALottie.h:
--------------------------------------------------------------------------------
1 | //
2 | // CALayer+XALottie.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/20.
6 | //
7 |
8 | #import
9 | @class XABindLottieController;
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface CALayer (XALottie)
13 |
14 | //init json, just root layer need to bind.
15 | - (XABindLottieController *)bindLottieWithContentsOfURL:(nonnull NSURL *)url;
16 | - (XABindLottieController *)bindLottieWithAnimationNamed:(NSString *)animationNamed;
17 | - (XABindLottieController *)bindLottieWithFilePath:(NSString *)filePath;
18 |
19 | //every node layer under root can bind a name of animated lottie-json-layer.
20 | - (void)bindLottieLayerName:(NSString *)lotLayerName;
21 | - (NSString *)bindLottieLayerName;
22 |
23 | - (XABindLottieController *)currentBindController;
24 |
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTCacheProvider.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTCacheProvider.h
3 | // Lottie
4 | //
5 | // Created by punmy on 2017/7/8.
6 | //
7 | //
8 |
9 | #import
10 |
11 | #if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
12 |
13 | #import
14 | @compatibility_alias LOTImage UIImage;
15 |
16 | @protocol LOTImageCache;
17 |
18 | #pragma mark - LOTCacheProvider
19 |
20 | @interface LOTCacheProvider : NSObject
21 |
22 | + (id)imageCache;
23 | + (void)setImageCache:(id)cache;
24 |
25 | @end
26 |
27 | #pragma mark - LOTImageCache
28 |
29 | /**
30 | This protocol represent the interface of a image cache which lottie can use.
31 | */
32 | @protocol LOTImageCache
33 |
34 | @required
35 | - (LOTImage *)imageForKey:(NSString *)key;
36 | - (void)setImage:(LOTImage *)image forKey:(NSString *)key;
37 |
38 | @end
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # macOS
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 | *.xccheckout
16 | *.moved-aside
17 | DerivedData
18 | *.hmap
19 | *.ipa
20 |
21 | # Bundler
22 | .bundle
23 |
24 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
25 | # Carthage/Checkouts
26 |
27 | Carthage/Build
28 |
29 | # We recommend against adding the Pods directory to your .gitignore. However
30 | # you should judge for yourself, the pros and cons are mentioned at:
31 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
32 | #
33 | # Note: if you ignore the Pods directory, make sure to uncomment
34 | # `pod install` in .travis.yml
35 | #
36 | # Pods/
37 |
38 | Example/Pods
39 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapePath.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapePath.m
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTShapePath.h"
10 |
11 | @implementation LOTShapePath
12 |
13 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
14 | self = [super init];
15 | if (self) {
16 | [self _mapFromJSON:jsonDictionary];
17 | }
18 | return self;
19 | }
20 |
21 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
22 |
23 | if (jsonDictionary[@"nm"] ) {
24 | _keyname = [jsonDictionary[@"nm"] copy];
25 | }
26 |
27 | _index = jsonDictionary[@"ind"];
28 | _closed = [jsonDictionary[@"closed"] boolValue];
29 | NSDictionary *shape = jsonDictionary[@"ks"];
30 | if (shape) {
31 | _shapePath = [[LOTKeyframeGroup alloc] initWithData:shape];
32 | }
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XALOTProAnimationViewLayer.m:
--------------------------------------------------------------------------------
1 | //
2 | // XALOTProAnimationViewLayer.m
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/4/1.
6 | //
7 |
8 | #import "XALOTProAnimationViewLayer.h"
9 |
10 | @interface XALOTProAnimationViewLayer ()
11 |
12 | @property (nonatomic, strong) NSMutableDictionary *stateMap;
13 |
14 | @end
15 |
16 | @implementation XALOTProAnimationViewLayer
17 |
18 | - (instancetype)init{
19 | self = [super init];
20 | if (self) {
21 | _stateMap = [NSMutableDictionary new];
22 | }
23 | return self;
24 | }
25 |
26 |
27 | - (XALottieLayerState)getStateForLayerID:(NSNumber *)layerID{
28 | XALottieLayerState state = [[_stateMap objectForKey:layerID] integerValue];
29 | return state;
30 | }
31 |
32 | - (void)setStateForLayerID:(NSNumber *)layerID state:(XALottieLayerState)state{
33 | [_stateMap setObject:@(state) forKey:layerID];
34 | }
35 |
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTMask.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTMask.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/14/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | typedef enum : NSUInteger {
13 | LOTMaskModeAdd,
14 | LOTMaskModeSubtract,
15 | LOTMaskModeIntersect,
16 | LOTMaskModeUnknown
17 | } LOTMaskMode;
18 |
19 | @interface LOTMask : NSObject
20 |
21 | - (instancetype _Nonnull)initWithJSON:(NSDictionary * _Nonnull)jsonDictionary;
22 |
23 | @property (nonatomic, readonly) BOOL closed;
24 | @property (nonatomic, readonly) BOOL inverted;
25 | @property (nonatomic, readonly) LOTMaskMode maskMode;
26 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *maskPath;
27 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *opacity;
28 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *expansion;
29 | @end
30 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTAssetGroup.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAssetGroup.h
3 | // Pods
4 | //
5 | // Created by Brandon Withrow on 2/17/17.
6 | //
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class LOTAsset;
13 | @class LOTLayerGroup;
14 | @interface LOTAssetGroup : NSObject
15 | @property (nonatomic, readwrite) NSString * _Nullable rootDirectory;
16 | @property (nonatomic, readonly, nullable) NSBundle *assetBundle;
17 |
18 | - (instancetype _Nonnull)initWithJSON:(NSArray * _Nonnull)jsonArray
19 | withAssetBundle:(NSBundle *_Nullable)bundle
20 | withFramerate:(NSNumber * _Nonnull)framerate;
21 |
22 | - (void)buildAssetNamed:(NSString * _Nonnull)refID withFramerate:(NSNumber * _Nonnull)framerate;
23 |
24 | - (void)finalizeInitializationWithFramerate:(NSNumber * _Nonnull)framerate;
25 |
26 | - (LOTAsset * _Nullable)assetModelForID:(NSString * _Nonnull)assetID;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTAnimationCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimationCache.h
3 | // Lottie
4 | //
5 | // Created by Brandon Withrow on 1/9/17.
6 | // Copyright © 2017 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @class LOTComposition;
14 |
15 | @interface LOTAnimationCache : NSObject
16 |
17 | /// Global Cache
18 | + (instancetype)sharedCache;
19 |
20 | /// Adds animation to the cache
21 | - (void)addAnimation:(LOTComposition *)animation forKey:(NSString *)key;
22 |
23 | /// Returns animation from cache.
24 | - (LOTComposition * _Nullable)animationForKey:(NSString *)key;
25 |
26 | /// Removes a specific animation from the cache
27 | - (void)removeAnimationForKey:(NSString *)key;
28 |
29 | /// Clears Everything from the Cache
30 | - (void)clearCache;
31 |
32 | /// Disables Caching Animation Model Objects
33 | - (void)disableCaching;
34 |
35 | @end
36 |
37 | NS_ASSUME_NONNULL_END
38 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTAnimationView_Compat.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimationView_Compat.h
3 | // Lottie
4 | //
5 | // Created by Oleksii Pavlovskyi on 2/2/17.
6 | // Copyright (c) 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
10 |
11 | #import
12 | @compatibility_alias LOTView UIView;
13 |
14 | #else
15 |
16 | #import
17 | @compatibility_alias LOTView NSView;
18 |
19 | typedef NS_ENUM(NSInteger, LOTViewContentMode) {
20 | LOTViewContentModeScaleToFill,
21 | LOTViewContentModeScaleAspectFit,
22 | LOTViewContentModeScaleAspectFill,
23 | LOTViewContentModeRedraw,
24 | LOTViewContentModeCenter,
25 | LOTViewContentModeTop,
26 | LOTViewContentModeBottom,
27 | LOTViewContentModeLeft,
28 | LOTViewContentModeRight,
29 | LOTViewContentModeTopLeft,
30 | LOTViewContentModeTopRight,
31 | LOTViewContentModeBottomLeft,
32 | LOTViewContentModeBottomRight,
33 | };
34 |
35 | #endif
36 |
37 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XABindLOTAnimationView.m:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLOTAnimationView.m
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/20.
6 | //
7 |
8 | #import "XABindLOTAnimationView.h"
9 | #import
10 | #import "XABindLOTAnimationViewLayer.h"
11 |
12 | @implementation XABindLOTAnimationView
13 |
14 | - (void)setHostView:(UIView *)hostView{
15 | _hostView = hostView;
16 | self.hostLayer = hostView.layer;
17 | }
18 |
19 | - (UIWindow *)window{
20 | if (_hostView) {
21 | return [super window];
22 | }
23 | if (_hostLayer) {
24 | CALayer *windowLayer = _hostLayer;
25 | while (windowLayer) {
26 | if ([windowLayer.delegate isKindOfClass:[UIWindow class]] ) {
27 | return windowLayer.delegate;
28 | }
29 | windowLayer = windowLayer.superlayer;
30 | }
31 | }
32 | return nil;
33 | }
34 |
35 | + (Class)layerClass{
36 | return [XABindLOTAnimationViewLayer class];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeCircle.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeCircle.m
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeCircle.h"
10 |
11 | @implementation LOTShapeCircle
12 |
13 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
14 | self = [super init];
15 | if (self) {
16 | [self _mapFromJSON:jsonDictionary];
17 | }
18 | return self;
19 | }
20 |
21 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
22 |
23 | if (jsonDictionary[@"nm"] ) {
24 | _keyname = [jsonDictionary[@"nm"] copy];
25 | }
26 |
27 | NSDictionary *position = jsonDictionary[@"p"];
28 | if (position) {
29 | _position = [[LOTKeyframeGroup alloc] initWithData:position];
30 | }
31 |
32 | NSDictionary *size= jsonDictionary[@"s"];
33 | if (size) {
34 | _size = [[LOTKeyframeGroup alloc] initWithData:size];
35 | }
36 | NSNumber *reversed = jsonDictionary[@"d"];
37 | _reversed = (reversed.integerValue == 3);
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeGradientFill.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeGradientFill.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/26/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | typedef enum : NSUInteger {
15 | LOTGradientTypeLinear,
16 | LOTGradientTypeRadial
17 | } LOTGradientType;
18 |
19 | @interface LOTShapeGradientFill : NSObject
20 |
21 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
22 |
23 | @property (nonatomic, readonly) NSString *keyname;
24 | @property (nonatomic, readonly) NSNumber *numberOfColors;
25 | @property (nonatomic, readonly) LOTKeyframeGroup *startPoint;
26 | @property (nonatomic, readonly) LOTKeyframeGroup *endPoint;
27 | @property (nonatomic, readonly) LOTKeyframeGroup *gradient;
28 | @property (nonatomic, readonly) LOTKeyframeGroup *opacity;
29 | @property (nonatomic, readonly) BOOL evenOddFillRule;
30 | @property (nonatomic, readonly) LOTGradientType type;
31 |
32 | @end
33 |
34 | NS_ASSUME_NONNULL_END
35 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTArrayInterpolator.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTArrayInterpolator.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTArrayInterpolator.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTArrayInterpolator
13 |
14 | - (NSArray *)numberArrayForFrame:(NSNumber *)frame {
15 | CGFloat progress = [self progressForFrame:frame];
16 | if (progress == 0) {
17 | return self.leadingKeyframe.arrayValue;
18 | }
19 | if (progress == 1) {
20 | return self.trailingKeyframe.arrayValue;
21 | }
22 | NSMutableArray *returnArray = [NSMutableArray array];
23 | for (int i = 0; i < self.leadingKeyframe.arrayValue.count; i ++) {
24 | CGFloat from = [(NSNumber *)self.leadingKeyframe.arrayValue[i] floatValue];
25 | CGFloat to = [(NSNumber *)self.trailingKeyframe.arrayValue[i] floatValue];
26 | CGFloat value = LOT_RemapValue(progress, 0, 1, from, to);
27 | [returnArray addObject:@(value)];
28 | }
29 | return returnArray;
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeRepeater.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeRepeater.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/28/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface LOTShapeRepeater : NSObject
15 |
16 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
17 |
18 | @property (nonatomic, readonly) NSString *keyname;
19 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *copies;
20 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *offset;
21 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *anchorPoint;
22 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *scale;
23 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *position;
24 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *rotation;
25 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *startOpacity;
26 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *endOpacity;
27 |
28 | @end
29 |
30 | NS_ASSUME_NONNULL_END
31 |
--------------------------------------------------------------------------------
/NOTICE THIRD PARTY:
--------------------------------------------------------------------------------
1 | THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
2 |
3 | This extension uses Open Source components. You can find the source code of their
4 | open source projects along with the license information below. We acknowledge and
5 | are grateful to these developers for their contribution to open source.
6 |
7 |
8 | 1 lottie-ios https://github.com/airbnb/lottie-ios
9 |
10 |
11 | lottie-ios NOTICES BEGIN HERE
12 | ===============================
13 |
14 | Copyright (C) 2018 Airbnb, Inc.
15 |
16 | Licensed under the Apache License, Version 2.0 (the "License");
17 | you may not use this file except in compliance with the License.
18 | You may obtain a copy of the License at
19 |
20 | http://www.apache.org/licenses/LICENSE-2.0
21 |
22 | Unless required by applicable law or agreed to in writing, software
23 | distributed under the License is distributed on an "AS IS" BASIS,
24 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 | See the License for the specific language governing permissions and
26 | limitations under the License.
27 |
28 |
29 | ====================================
30 |
31 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeTrimPath.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeTrimPath.m
3 | // LottieAnimator
4 | //
5 | // Created by brandon_withrow on 7/26/16.
6 | // Copyright © 2016 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeTrimPath.h"
10 |
11 | @implementation LOTShapeTrimPath
12 |
13 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
14 | self = [super init];
15 | if (self) {
16 | [self _mapFromJSON:jsonDictionary];
17 | }
18 | return self;
19 | }
20 |
21 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
22 |
23 | if (jsonDictionary[@"nm"] ) {
24 | _keyname = [jsonDictionary[@"nm"] copy];
25 | }
26 |
27 | NSDictionary *start = jsonDictionary[@"s"];
28 | if (start) {
29 | _start = [[LOTKeyframeGroup alloc] initWithData:start];
30 | }
31 |
32 | NSDictionary *end = jsonDictionary[@"e"];
33 | if (end) {
34 | _end = [[LOTKeyframeGroup alloc] initWithData:end];
35 | }
36 |
37 | NSDictionary *offset = jsonDictionary[@"o"];
38 | if (offset) {
39 | _offset = [[LOTKeyframeGroup alloc] initWithData:offset];
40 | }
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeStar.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeStar.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | typedef enum : NSUInteger {
13 | LOTPolystarShapeNone,
14 | LOTPolystarShapeStar,
15 | LOTPolystarShapePolygon
16 | } LOTPolystarShape;
17 |
18 | @interface LOTShapeStar : NSObject
19 |
20 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
21 |
22 | @property (nonatomic, readonly) NSString *keyname;
23 | @property (nonatomic, readonly) LOTKeyframeGroup *outerRadius;
24 | @property (nonatomic, readonly) LOTKeyframeGroup *outerRoundness;
25 |
26 | @property (nonatomic, readonly) LOTKeyframeGroup *innerRadius;
27 | @property (nonatomic, readonly) LOTKeyframeGroup *innerRoundness;
28 |
29 | @property (nonatomic, readonly) LOTKeyframeGroup *position;
30 | @property (nonatomic, readonly) LOTKeyframeGroup *numberOfPoints;
31 | @property (nonatomic, readonly) LOTKeyframeGroup *rotation;
32 |
33 | @property (nonatomic, readonly) LOTPolystarShape type;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/Lottie.h:
--------------------------------------------------------------------------------
1 | //
2 | // Lottie.h
3 | // Pods
4 | //
5 | // Created by brandon_withrow on 1/27/17.
6 | //
7 | // Dream Big.
8 |
9 | #if __has_feature(modules)
10 | @import Foundation;
11 | #else
12 | #import
13 | #endif
14 |
15 | #ifndef Lottie_h
16 | #define Lottie_h
17 |
18 | //! Project version number for Lottie.
19 | FOUNDATION_EXPORT double LottieVersionNumber;
20 |
21 | //! Project version string for Lottie.
22 | FOUNDATION_EXPORT const unsigned char LottieVersionString[];
23 |
24 | #include
25 |
26 | #if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
27 | #import "LOTAnimationTransitionController.h"
28 | #import "LOTAnimatedSwitch.h"
29 | #import "LOTAnimatedControl.h"
30 | #endif
31 |
32 | #if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
33 | #import "LOTCacheProvider.h"
34 | #endif
35 |
36 | #import
37 | #import "LOTAnimationCache.h"
38 | #import "LOTComposition.h"
39 | #import "LOTBlockCallback.h"
40 | #import "LOTInterpolatorCallback.h"
41 | #import "LOTValueCallback.h"
42 | #import "LOTValueDelegate.h"
43 |
44 | #endif /* Lottie_h */
45 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/AnimatorNodes/LOTPathAnimator.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTPathAnimator.m
3 | // Pods
4 | //
5 | // Created by brandon_withrow on 6/27/17.
6 | //
7 | //
8 |
9 | #import "LOTPathAnimator.h"
10 | #import "LOTPathInterpolator.h"
11 |
12 | @implementation LOTPathAnimator {
13 | LOTShapePath *_pathConent;
14 | LOTPathInterpolator *_interpolator;
15 | }
16 |
17 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
18 | shapePath:(LOTShapePath *_Nonnull)shapePath {
19 | self = [super initWithInputNode:inputNode keyName:shapePath.keyname];
20 | if (self) {
21 | _pathConent = shapePath;
22 | _interpolator = [[LOTPathInterpolator alloc] initWithKeyframes:_pathConent.shapePath.keyframes];
23 | }
24 | return self;
25 | }
26 |
27 | - (NSDictionary *)valueInterpolators {
28 | return @{@"Path" : _interpolator};
29 | }
30 |
31 | - (BOOL)needsUpdateForFrame:(NSNumber *)frame {
32 | return [_interpolator hasUpdateForFrame:frame];
33 | }
34 |
35 | - (void)performLocalUpdate {
36 | self.localPath = [_interpolator pathForFrame:self.currentFrame cacheLengths:self.pathShouldCacheLengths];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTAsset.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAsset.h
3 | // Pods
4 | //
5 | // Created by Brandon Withrow on 2/16/17.
6 | //
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @class LOTLayerGroup;
15 | @class LOTLayer;
16 | @class LOTAssetGroup;
17 |
18 | @interface LOTAsset : NSObject
19 |
20 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary
21 | withAssetGroup:(LOTAssetGroup * _Nullable)assetGroup
22 | withAssetBundle:(NSBundle *_Nonnull)bundle
23 | withFramerate:(NSNumber *)framerate;
24 |
25 | @property (nonatomic, readonly, nullable) NSString *referenceID;
26 | @property (nonatomic, readonly, nullable) NSNumber *assetWidth;
27 | @property (nonatomic, readonly, nullable) NSNumber *assetHeight;
28 |
29 | @property (nonatomic, readonly, nullable) NSString *imageName;
30 | @property (nonatomic, readonly, nullable) NSString *imageDirectory;
31 |
32 | @property (nonatomic, readonly, nullable) LOTLayerGroup *layerGroup;
33 |
34 | @property (nonatomic, readwrite) NSString *rootDirectory;
35 | @property (nonatomic, readonly) NSBundle *assetBundle;
36 | @end
37 |
38 | NS_ASSUME_NONNULL_END
39 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeStroke.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeStroke.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTKeyframe.h"
11 |
12 | typedef enum : NSUInteger {
13 | LOTLineCapTypeButt,
14 | LOTLineCapTypeRound,
15 | LOTLineCapTypeUnknown
16 | } LOTLineCapType;
17 |
18 | typedef enum : NSUInteger {
19 | LOTLineJoinTypeMiter,
20 | LOTLineJoinTypeRound,
21 | LOTLineJoinTypeBevel
22 | } LOTLineJoinType;
23 |
24 | @interface LOTShapeStroke : NSObject
25 |
26 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
27 |
28 | @property (nonatomic, readonly) NSString *keyname;
29 | @property (nonatomic, readonly) BOOL fillEnabled;
30 | @property (nonatomic, readonly) LOTKeyframeGroup *color;
31 | @property (nonatomic, readonly) LOTKeyframeGroup *opacity;
32 | @property (nonatomic, readonly) LOTKeyframeGroup *width;
33 | @property (nonatomic, readonly) LOTKeyframeGroup *dashOffset;
34 | @property (nonatomic, readonly) LOTLineCapType capType;
35 | @property (nonatomic, readonly) LOTLineJoinType joinType;
36 |
37 | @property (nonatomic, readonly) NSArray *lineDashPattern;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeRectangle.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeRectangle.m
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeRectangle.h"
10 |
11 | @implementation LOTShapeRectangle
12 |
13 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
14 | self = [super init];
15 | if (self) {
16 | [self _mapFromJSON:jsonDictionary];
17 | }
18 | return self;
19 | }
20 |
21 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
22 |
23 | if (jsonDictionary[@"nm"] ) {
24 | _keyname = [jsonDictionary[@"nm"] copy];
25 | }
26 |
27 | NSDictionary *position = jsonDictionary[@"p"];
28 | if (position) {
29 | _position = [[LOTKeyframeGroup alloc] initWithData:position];
30 | }
31 |
32 | NSDictionary *cornerRadius = jsonDictionary[@"r"];
33 | if (cornerRadius) {
34 | _cornerRadius = [[LOTKeyframeGroup alloc] initWithData:cornerRadius];
35 | }
36 |
37 | NSDictionary *size = jsonDictionary[@"s"];
38 | if (size) {
39 | _size = [[LOTKeyframeGroup alloc] initWithData:size];
40 | }
41 | NSNumber *reversed = jsonDictionary[@"d"];
42 | _reversed = (reversed.integerValue == 3);
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/LOTRenderNode.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTRenderNode.m
3 | // Pods
4 | //
5 | // Created by brandon_withrow on 6/27/17.
6 | //
7 | //
8 |
9 | #import "LOTRenderNode.h"
10 |
11 | @implementation LOTRenderNode
12 |
13 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
14 | keyName:(NSString * _Nullable)keyname {
15 | self = [super initWithInputNode:inputNode keyName:keyname];
16 | if (self) {
17 | _outputLayer = [CAShapeLayer new];
18 | _outputLayer.actions = [self actionsForRenderLayer];
19 | }
20 | return self;
21 | }
22 |
23 | /// Layer Properties that need to disable implicit animations
24 | - (NSDictionary * _Nonnull)actionsForRenderLayer {
25 | return @{@"path": [NSNull null]};
26 | }
27 |
28 | /// Local interpolators have changed. Update layer specific properties.
29 | - (void)performLocalUpdate {
30 |
31 | }
32 |
33 | /// The path for rendering has changed. Do any rendering required.
34 | - (void)rebuildOutputs {
35 |
36 | }
37 |
38 | - (LOTBezierPath *)localPath {
39 | return self.inputNode.localPath;
40 | }
41 |
42 | /// Forwards its input node's output path forwards downstream
43 | - (LOTBezierPath *)outputPath {
44 | return self.inputNode.outputPath;
45 | }
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/XAnimation/Classes/AnimatableLayers/LOTLayerContainer.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTLayerContainer.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/18/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTPlatformCompat.h"
10 | #import "LOTLayer.h"
11 | #import "LOTLayerGroup.h"
12 | #import "LOTKeypath.h"
13 | #import "LOTValueDelegate.h"
14 |
15 | @class LOTValueCallback;
16 |
17 | @interface LOTLayerContainer : CALayer
18 |
19 | - (instancetype _Nonnull)initWithModel:(LOTLayer * _Nullable)layer
20 | inLayerGroup:(LOTLayerGroup * _Nullable)layerGroup;
21 |
22 | @property (nonatomic, readonly, strong, nullable) NSString *layerName;
23 | @property (nonatomic, nullable) NSNumber *currentFrame;
24 | @property (nonatomic, readonly, nonnull) NSNumber *timeStretchFactor;
25 | @property (nonatomic, assign) CGRect viewportBounds;
26 | @property (nonatomic, readonly, nonnull) CALayer *wrapperLayer;
27 | @property (nonatomic, readonly, nonnull) NSDictionary *valueInterpolators;
28 |
29 | - (void)displayWithFrame:(NSNumber * _Nonnull)frame;
30 | - (void)displayWithFrame:(NSNumber * _Nonnull)frame forceUpdate:(BOOL)forceUpdate;
31 |
32 | - (void)searchNodesForKeypath:(LOTKeypath * _Nonnull)keypath;
33 |
34 | - (void)setValueDelegate:(id _Nonnull)delegate
35 | forKeypath:(LOTKeypath * _Nonnull)keypath;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/XAnimation/Classes/MacCompatibility/UIColor.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor.h
3 | // Lottie
4 | //
5 | // Created by Oleksii Pavlovskyi on 2/2/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #include
10 |
11 | #if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
12 | #import
13 | #import
14 |
15 | @interface UIColor : NSObject
16 |
17 | + (UIColor *)colorWithWhite:(CGFloat)white alpha:(CGFloat)alpha;
18 | + (UIColor *)colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha;
19 | + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
20 | + (UIColor *)colorWithCGColor:(CGColorRef)cgColor;
21 |
22 | + (UIColor *)blackColor;
23 | + (UIColor *)darkGrayColor;
24 | + (UIColor *)lightGrayColor;
25 | + (UIColor *)whiteColor;
26 | + (UIColor *)grayColor;
27 | + (UIColor *)redColor;
28 | + (UIColor *)greenColor;
29 | + (UIColor *)blueColor;
30 | + (UIColor *)cyanColor;
31 | + (UIColor *)yellowColor;
32 | + (UIColor *)magentaColor;
33 | + (UIColor *)orangeColor;
34 | + (UIColor *)purpleColor;
35 | + (UIColor *)brownColor;
36 | + (UIColor *)clearColor;
37 |
38 | - (UIColor *)colorWithAlphaComponent:(CGFloat)alpha;
39 |
40 | @property (nonatomic, readonly) CGColorRef CGColor;
41 |
42 | @end
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeFill.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeFill.m
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeFill.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTShapeFill
13 |
14 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
15 | self = [super init];
16 | if (self) {
17 | [self _mapFromJSON:jsonDictionary];
18 | }
19 | return self;
20 | }
21 |
22 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
23 |
24 | if (jsonDictionary[@"nm"] ) {
25 | _keyname = [jsonDictionary[@"nm"] copy];
26 | }
27 |
28 | NSDictionary *color = jsonDictionary[@"c"];
29 | if (color) {
30 | _color = [[LOTKeyframeGroup alloc] initWithData:color];
31 | }
32 |
33 | NSDictionary *opacity = jsonDictionary[@"o"];
34 | if (opacity) {
35 | _opacity = [[LOTKeyframeGroup alloc] initWithData:opacity];
36 | [_opacity remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
37 | return LOT_RemapValue(inValue, 0, 100, 0, 1);
38 | }];
39 | }
40 |
41 | NSNumber *evenOdd = jsonDictionary[@"r"];
42 | if (evenOdd.integerValue == 2) {
43 | _evenOddFillRule = YES;
44 | } else {
45 | _evenOddFillRule = NO;
46 | }
47 |
48 | NSNumber *fillEnabled = jsonDictionary[@"fillEnabled"];
49 | _fillEnabled = fillEnabled.boolValue;
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/PublicHeaders/XABindLottieController.h:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLottieController.h
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/30.
6 | //
7 |
8 | #import
9 | #import "XALOTBindControllerDataSource.h"
10 | #import "XALOTBindControllerDelegate.h"
11 |
12 | @class XABindLOTAnimationView;
13 |
14 | typedef void (^XABindLottieCompletionBlock)(BOOL animationFinished);
15 | typedef void (^XABindLottieLoadCompletionBlock)(BOOL loadFinished);
16 |
17 | NS_ASSUME_NONNULL_BEGIN
18 |
19 | @interface XABindLottieController : NSObject
20 |
21 |
22 | @property (nonatomic, weak, readonly) id host;
23 | @property (nonatomic, weak) id dataSource;
24 | @property (nonatomic, weak) id delegate;
25 | @property (nonatomic, assign) BOOL loopAnimation;
26 |
27 | + (XABindLottieController *)bindLottieWithContentsOfURL:(nonnull NSURL *)url toHost:(id)host;
28 | + (XABindLottieController *)bindLottieWithAnimationNamed:(NSString *)animationNamed toHost:(id)host;
29 | + (XABindLottieController *)bindLottieWithFilePath:(NSString *)filePath toHost:(id)host;
30 |
31 | - (void)play;
32 | - (void)playFromProgress:(CGFloat)fromStartProgress
33 | toProgress:(CGFloat)toEndProgress
34 | withCompletion:(nullable XABindLottieCompletionBlock)completion;
35 | - (void)pause;
36 | - (void)stop;
37 |
38 | - (CGFloat)currentProgress;
39 |
40 | @end
41 |
42 | NS_ASSUME_NONNULL_END
43 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Extensions/LOTBezierPath.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTBezierPath.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/20/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTPlatformCompat.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LOTBezierPath : NSObject
14 |
15 | + (instancetype)pathWithCGPath:(CGPathRef)path;
16 |
17 | + (instancetype)newPath;
18 |
19 | - (void)LOT_moveToPoint:(CGPoint)point;
20 |
21 | - (void)LOT_addLineToPoint:(CGPoint)point;
22 |
23 | - (void)LOT_addCurveToPoint:(CGPoint)point
24 | controlPoint1:(CGPoint)cp1
25 | controlPoint2:(CGPoint)cp2;
26 |
27 | - (void)LOT_closePath;
28 |
29 | - (void)LOT_removeAllPoints;
30 |
31 | - (void)LOT_appendPath:(LOTBezierPath *)bezierPath;
32 |
33 | - (void)trimPathFromT:(CGFloat)fromT toT:(CGFloat)toT offset:(CGFloat)offset;
34 |
35 | - (void)LOT_applyTransform:(CGAffineTransform)transform;
36 |
37 | @property (nonatomic, assign) BOOL cacheLengths;
38 |
39 | @property (nonatomic, readonly) CGFloat length;
40 |
41 | @property (nonatomic, readonly) CGPathRef CGPath;
42 | @property (nonatomic, readonly) CGPoint currentPoint;
43 | @property (nonatomic) CGFloat lineWidth;
44 | @property (nonatomic) CGLineCap lineCapStyle;
45 | @property (nonatomic) CGLineJoin lineJoinStyle;
46 | @property (nonatomic) CGFloat miterLimit;
47 | @property (nonatomic) CGFloat flatness;
48 | @property (nonatomic) BOOL usesEvenOddFillRule;
49 | @property (readonly, getter=isEmpty) BOOL empty;
50 | @property (nonatomic, readonly) CGRect bounds;
51 |
52 | @end
53 |
54 | NS_ASSUME_NONNULL_END
55 |
--------------------------------------------------------------------------------
/XAnimation/Classes/AnimatableProperties/LOTKeyframe.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTKeyframe.h
3 | // Pods
4 | //
5 | // Created by brandon_withrow on 7/10/17.
6 | //
7 | //
8 |
9 | #import
10 | #import
11 | #import "LOTPlatformCompat.h"
12 | #import "LOTBezierData.h"
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | @interface LOTKeyframe : NSObject
17 |
18 | - (instancetype)initWithKeyframe:(NSDictionary *)keyframe;
19 | - (instancetype)initWithValue:(id)value;
20 | - (void)remapValueWithBlock:(CGFloat (^)(CGFloat inValue))remapBlock;
21 | - (LOTKeyframe *)copyWithData:(id)data;
22 |
23 | @property (nonatomic, readonly) NSNumber *keyframeTime;
24 | @property (nonatomic, readonly) BOOL isHold;
25 | @property (nonatomic, readonly) CGPoint inTangent;
26 | @property (nonatomic, readonly) CGPoint outTangent;
27 | @property (nonatomic, readonly) CGPoint spatialInTangent;
28 | @property (nonatomic, readonly) CGPoint spatialOutTangent;
29 |
30 | @property (nonatomic, readonly) CGFloat floatValue;
31 | @property (nonatomic, readonly) CGPoint pointValue;
32 | @property (nonatomic, readonly) CGSize sizeValue;
33 | @property (nonatomic, readonly) UIColor *colorValue;
34 | @property (nonatomic, readonly, nullable) LOTBezierData *pathData;
35 | @property (nonatomic, readonly) NSArray *arrayValue;
36 |
37 | @end
38 |
39 | @interface LOTKeyframeGroup : NSObject
40 |
41 | - (instancetype)initWithData:(id)data;
42 |
43 | - (void)remapKeyframesWithBlock:(CGFloat (^)(CGFloat inValue))remapBlock;
44 |
45 | @property (nonatomic, readonly) NSArray *keyframes;
46 |
47 | @end
48 |
49 | NS_ASSUME_NONNULL_END
50 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTAsset.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAsset.m
3 | // Pods
4 | //
5 | // Created by Brandon Withrow on 2/16/17.
6 | //
7 | //
8 |
9 | #import "LOTAsset.h"
10 | #import "LOTLayer.h"
11 | #import "LOTLayerGroup.h"
12 | #import "LOTAssetGroup.h"
13 |
14 | @implementation LOTAsset
15 |
16 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary
17 | withAssetGroup:(LOTAssetGroup * _Nullable)assetGroup
18 | withAssetBundle:(NSBundle *_Nonnull)bundle
19 | withFramerate:(NSNumber *)framerate {
20 | self = [super init];
21 | if (self) {
22 | _assetBundle = bundle;
23 | [self _mapFromJSON:jsonDictionary
24 | withAssetGroup:assetGroup
25 | withFramerate:framerate];
26 | }
27 | return self;
28 | }
29 |
30 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary
31 | withAssetGroup:(LOTAssetGroup * _Nullable)assetGroup
32 | withFramerate:(NSNumber *)framerate {
33 | _referenceID = [jsonDictionary[@"id"] copy];
34 |
35 | if (jsonDictionary[@"w"]) {
36 | _assetWidth = [jsonDictionary[@"w"] copy];
37 | }
38 |
39 | if (jsonDictionary[@"h"]) {
40 | _assetHeight = [jsonDictionary[@"h"] copy];
41 | }
42 |
43 | if (jsonDictionary[@"u"]) {
44 | _imageDirectory = [jsonDictionary[@"u"] copy];
45 | }
46 |
47 | if (jsonDictionary[@"p"]) {
48 | _imageName = [jsonDictionary[@"p"] copy];
49 | }
50 |
51 | NSArray *layersJSON = jsonDictionary[@"layers"];
52 | if (layersJSON) {
53 | _layerGroup = [[LOTLayerGroup alloc] initWithLayerJSON:layersJSON
54 | withAssetGroup:assetGroup
55 | withFramerate:framerate];
56 | }
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTMask.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTMask.m
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/14/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTMask.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTMask
13 |
14 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
15 | self = [super init];
16 | if (self) {
17 | [self _mapFromJSON:jsonDictionary];
18 | }
19 | return self;
20 | }
21 |
22 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
23 | NSNumber *closed = jsonDictionary[@"cl"];
24 | _closed = closed.boolValue;
25 |
26 | NSNumber *inverted = jsonDictionary[@"inv"];
27 | _inverted = inverted.boolValue;
28 |
29 | NSString *mode = jsonDictionary[@"mode"];
30 | if ([mode isEqualToString:@"a"]) {
31 | _maskMode = LOTMaskModeAdd;
32 | } else if ([mode isEqualToString:@"s"]) {
33 | _maskMode = LOTMaskModeSubtract;
34 | } else if ([mode isEqualToString:@"i"]) {
35 | _maskMode = LOTMaskModeIntersect;
36 | } else {
37 | _maskMode = LOTMaskModeUnknown;
38 | }
39 |
40 | NSDictionary *maskshape = jsonDictionary[@"pt"];
41 | if (maskshape) {
42 | _maskPath = [[LOTKeyframeGroup alloc] initWithData:maskshape];
43 | }
44 |
45 | NSDictionary *opacity = jsonDictionary[@"o"];
46 | if (opacity) {
47 | _opacity = [[LOTKeyframeGroup alloc] initWithData:opacity];
48 | [_opacity remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
49 | return LOT_RemapValue(inValue, 0, 100, 0, 1);
50 | }];
51 | }
52 |
53 | NSDictionary *expansion = jsonDictionary[@"x"];
54 | if (expansion) {
55 | _expansion = [[LOTKeyframeGroup alloc] initWithData:expansion];
56 | }
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/XAnimation/Classes/AnimatableLayers/LOTCompositionContainer.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTCompositionContainer.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/18/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTLayerContainer.h"
10 | #import "LOTAssetGroup.h"
11 |
12 | @interface LOTCompositionContainer : LOTLayerContainer
13 |
14 | - (instancetype _Nonnull)initWithModel:(LOTLayer * _Nullable)layer
15 | inLayerGroup:(LOTLayerGroup * _Nullable)layerGroup
16 | withLayerGroup:(LOTLayerGroup * _Nullable)childLayerGroup
17 | withAssestGroup:(LOTAssetGroup * _Nullable)assetGroup;
18 |
19 | - (nullable NSArray *)keysForKeyPath:(nonnull LOTKeypath *)keypath;
20 |
21 | - (CGPoint)convertPoint:(CGPoint)point
22 | toKeypathLayer:(nonnull LOTKeypath *)keypath
23 | withParentLayer:(CALayer *_Nonnull)parent;
24 |
25 | - (CGRect)convertRect:(CGRect)rect
26 | toKeypathLayer:(nonnull LOTKeypath *)keypath
27 | withParentLayer:(CALayer *_Nonnull)parent;
28 |
29 | - (CGPoint)convertPoint:(CGPoint)point
30 | fromKeypathLayer:(nonnull LOTKeypath *)keypath
31 | withParentLayer:(CALayer *_Nonnull)parent;
32 |
33 | - (CGRect)convertRect:(CGRect)rect
34 | fromKeypathLayer:(nonnull LOTKeypath *)keypath
35 | withParentLayer:(CALayer *_Nonnull)parent;
36 |
37 | - (void)addSublayer:(nonnull CALayer *)subLayer
38 | toKeypathLayer:(nonnull LOTKeypath *)keypath;
39 |
40 | - (void)maskSublayer:(nonnull CALayer *)subLayer
41 | toKeypathLayer:(nonnull LOTKeypath *)keypath;
42 |
43 | @property (nonatomic, readonly, nonnull) NSArray *childLayers;
44 | @property (nonatomic, readonly, nonnull) NSDictionary *childMap;
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/Example/XAnimation/XAnimation-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/Test/XABindLottieDebugWindowRootViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLottieDebugWindowRootViewController.m
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | //
7 |
8 | #ifdef XABindLottieDebug
9 |
10 | #import "XABindLottieDebugWindowRootViewController.h"
11 | #import "XABindLottieHomeViewController.h"
12 |
13 | @interface XABindLottieDebugWindowRootViewController ()
14 |
15 | @end
16 |
17 | @implementation XABindLottieDebugWindowRootViewController
18 |
19 | - (instancetype)init{
20 | self = [super init];
21 | if (self) {
22 | self.viewControllers = @[[XABindLottieHomeViewController new]];
23 | self.view.clipsToBounds = NO;
24 |
25 | }
26 | return self;
27 | }
28 |
29 | /*
30 | #pragma mark - Navigation
31 |
32 | // In a storyboard-based application, you will often want to do a little preparation before navigation
33 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
34 | // Get the new view controller using [segue destinationViewController].
35 | // Pass the selected object to the new view controller.
36 | }
37 | */
38 |
39 | - (void)viewDidLoad {
40 | [super viewDidLoad];
41 | // Do any additional setup after loading the view.
42 | self.interactivePopGestureRecognizer.delegate = self;
43 | self.navigationBarHidden = YES;
44 | }
45 |
46 |
47 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
48 | BOOL enable = YES; // 默认为支持右滑反回
49 | SEL sel = @selector(gestureRecognizerShouldBegin:);
50 | if ([self.topViewController respondsToSelector:sel]) {
51 | enable = [self.topViewController performSelector:sel withObject:gestureRecognizer];
52 | }
53 | return enable;
54 |
55 | }
56 |
57 | @end
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTNumberInterpolator.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTNumberInterpolator.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/11/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTNumberInterpolator.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTNumberInterpolator
13 |
14 | - (CGFloat)floatValueForFrame:(NSNumber *)frame {
15 | CGFloat progress = [self progressForFrame:frame];
16 | CGFloat returnValue;
17 | if (progress == 0) {
18 | returnValue = self.leadingKeyframe.floatValue;
19 | } else if (progress == 1) {
20 | returnValue = self.trailingKeyframe.floatValue;
21 | } else {
22 | returnValue = LOT_RemapValue(progress, 0, 1, self.leadingKeyframe.floatValue, self.trailingKeyframe.floatValue);
23 | }
24 | if (self.hasDelegateOverride) {
25 | return [self.delegate floatValueForFrame:frame.floatValue
26 | startKeyframe:self.leadingKeyframe.keyframeTime.floatValue
27 | endKeyframe:self.trailingKeyframe.keyframeTime.floatValue
28 | interpolatedProgress:progress
29 | startValue:self.leadingKeyframe.floatValue
30 | endValue:self.trailingKeyframe.floatValue
31 | currentValue:returnValue];
32 | }
33 |
34 | return returnValue;
35 | }
36 |
37 | - (BOOL)hasDelegateOverride {
38 | return self.delegate != nil;
39 | }
40 |
41 | - (void)setValueDelegate:(id _Nonnull)delegate {
42 | NSAssert(([delegate conformsToProtocol:@protocol(LOTNumberValueDelegate)]), @"Number Interpolator set with incorrect callback type. Expected LOTNumberValueDelegate");
43 | self.delegate = (id)delegate;
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTColorInterpolator.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTColorInterpolator.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/13/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTColorInterpolator.h"
10 | #import "LOTPlatformCompat.h"
11 | #import "UIColor+Expanded.h"
12 |
13 | @implementation LOTColorInterpolator
14 |
15 | - (CGColorRef)colorForFrame:(NSNumber *)frame {
16 | CGFloat progress = [self progressForFrame:frame];
17 | UIColor *returnColor;
18 |
19 | if (progress == 0) {
20 | returnColor = self.leadingKeyframe.colorValue;
21 | } else if (progress == 1) {
22 | returnColor = self.trailingKeyframe.colorValue;
23 | } else {
24 | returnColor = [UIColor LOT_colorByLerpingFromColor:self.leadingKeyframe.colorValue toColor:self.trailingKeyframe.colorValue amount:progress];
25 | }
26 | if (self.hasDelegateOverride) {
27 | return [self.delegate colorForFrame:frame.floatValue
28 | startKeyframe:self.leadingKeyframe.keyframeTime.floatValue
29 | endKeyframe:self.trailingKeyframe.keyframeTime.floatValue
30 | interpolatedProgress:progress
31 | startColor:self.leadingKeyframe.colorValue.CGColor
32 | endColor:self.trailingKeyframe.colorValue.CGColor
33 | currentColor:returnColor.CGColor];
34 | }
35 |
36 | return returnColor.CGColor;
37 | }
38 |
39 | - (void)setValueDelegate:(id)delegate {
40 | NSAssert(([delegate conformsToProtocol:@protocol(LOTColorValueDelegate)]), @"Color Interpolator set with incorrect callback type. Expected LOTColorValueDelegate");
41 | self.delegate = (id)delegate;
42 | }
43 |
44 | - (BOOL)hasDelegateOverride {
45 | return self.delegate != nil;
46 | }
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/Test/XABindLottieDebugWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLottieDebugWindow.m
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | //
7 |
8 | #ifdef XABindLottieDebug
9 |
10 | #import "XABindLottieDebugWindow.h"
11 | #import "XABindLottieDebugWindowRootViewController.h"
12 |
13 | @implementation XABindLottieDebugWindow
14 |
15 | + (XABindLottieDebugWindow *)sharedInstance{
16 | static XABindLottieDebugWindow *_sharedInstance = nil;
17 | if (!_sharedInstance) {
18 | _sharedInstance = [XABindLottieDebugWindow new];
19 | _sharedInstance.backgroundColor = [UIColor clearColor];
20 | _sharedInstance.windowLevel = UIWindowLevelAlert;
21 | }
22 | return _sharedInstance;
23 | }
24 |
25 | + (void)showDebugWindow{
26 | [[XABindLottieDebugWindow sharedInstance] setHidden:NO];
27 | UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
28 | [[XABindLottieDebugWindow sharedInstance] makeKeyAndVisible];
29 | [keyWindow makeKeyAndVisible];
30 | }
31 |
32 | + (void)hiddenDebugWindow{
33 | [[XABindLottieDebugWindow sharedInstance] setHidden:YES];
34 | }
35 |
36 | //+ (void)load{
37 | // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
38 | // [XABindLottieDebugWindow sharedInstance].appMainWindow = [UIApplication sharedApplication].keyWindow;
39 | //// [self showDebugWindow];
40 | // });
41 | //}
42 |
43 | - (instancetype)init{
44 | self = [super init];
45 | if (self) {
46 | self.rootViewController = [[XABindLottieDebugWindowRootViewController alloc] init];
47 | }
48 | return self;
49 | }
50 |
51 | + (double)screenWidth{
52 | return [UIScreen mainScreen].bounds.size.width;
53 | }
54 |
55 | + (double)screenHeight{
56 | return [UIScreen mainScreen].bounds.size.height;
57 | }
58 |
59 | @end
60 |
61 |
62 | #endif
63 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTLayerGroup.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTLayerGroup.m
3 | // Pods
4 | //
5 | // Created by Brandon Withrow on 2/16/17.
6 | //
7 | //
8 |
9 | #import "LOTLayerGroup.h"
10 | #import "LOTLayer.h"
11 | #import "LOTAssetGroup.h"
12 |
13 | @implementation LOTLayerGroup {
14 | NSDictionary *_modelMap;
15 | NSDictionary *_referenceIDMap;
16 | }
17 |
18 | - (instancetype)initWithLayerJSON:(NSArray *)layersJSON
19 | withAssetGroup:(LOTAssetGroup * _Nullable)assetGroup
20 | withFramerate:(NSNumber *)framerate {
21 | self = [super init];
22 | if (self) {
23 | [self _mapFromJSON:layersJSON withAssetGroup:assetGroup withFramerate:framerate];
24 | }
25 | return self;
26 | }
27 |
28 | - (void)_mapFromJSON:(NSArray *)layersJSON
29 | withAssetGroup:(LOTAssetGroup * _Nullable)assetGroup
30 | withFramerate:(NSNumber *)framerate {
31 |
32 | NSMutableArray *layers = [NSMutableArray array];
33 | NSMutableDictionary *modelMap = [NSMutableDictionary dictionary];
34 | NSMutableDictionary *referenceMap = [NSMutableDictionary dictionary];
35 |
36 | for (NSDictionary *layerJSON in layersJSON) {
37 | LOTLayer *layer = [[LOTLayer alloc] initWithJSON:layerJSON
38 | withAssetGroup:assetGroup
39 | withFramerate:framerate];
40 | [layers addObject:layer];
41 | if(layer.layerID) {
42 | modelMap[layer.layerID] = layer;
43 | }
44 | if (layer.referenceID) {
45 | referenceMap[layer.referenceID] = layer;
46 | }
47 | }
48 |
49 | _referenceIDMap = referenceMap;
50 | _modelMap = modelMap;
51 | _layers = layers;
52 | }
53 |
54 | - (LOTLayer *)layerModelForID:(NSNumber *)layerID {
55 | return _modelMap[layerID];
56 | }
57 |
58 | - (LOTLayer *)layerForReferenceID:(NSString *)referenceID {
59 | return _referenceIDMap[referenceID];
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTSizeInterpolator.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTSizeInterpolator.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/13/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTPlatformCompat.h"
10 | #import "LOTSizeInterpolator.h"
11 | #import "CGGeometry+LOTAdditions.h"
12 |
13 | @implementation LOTSizeInterpolator
14 |
15 | - (CGSize)sizeValueForFrame:(NSNumber *)frame {
16 | CGFloat progress = [self progressForFrame:frame];
17 | CGSize returnSize;
18 | if (progress == 0) {
19 | returnSize = self.leadingKeyframe.sizeValue;
20 | }else if (progress == 1) {
21 | returnSize = self.trailingKeyframe.sizeValue;
22 | } else {
23 | returnSize = CGSizeMake(LOT_RemapValue(progress, 0, 1, self.leadingKeyframe.sizeValue.width, self.trailingKeyframe.sizeValue.width),
24 | LOT_RemapValue(progress, 0, 1, self.leadingKeyframe.sizeValue.height, self.trailingKeyframe.sizeValue.height));
25 | }
26 | if (self.hasDelegateOverride) {
27 | return [self.delegate sizeForFrame:frame.floatValue
28 | startKeyframe:self.leadingKeyframe.keyframeTime.floatValue
29 | endKeyframe:self.trailingKeyframe.keyframeTime.floatValue
30 | interpolatedProgress:progress startSize:self.leadingKeyframe.sizeValue
31 | endSize:self.trailingKeyframe.sizeValue
32 | currentSize:returnSize];
33 | }
34 | return returnSize;
35 | }
36 |
37 | - (BOOL)hasDelegateOverride {
38 | return self.delegate != nil;
39 | }
40 |
41 | - (void)setValueDelegate:(id)delegate {
42 | NSAssert(([delegate conformsToProtocol:@protocol(LOTSizeValueDelegate)]), @"Size Interpolator set with incorrect callback type. Expected LOTSizeValueDelegate");
43 | self.delegate = (id)delegate;
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeGradientFill.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeGradientFill.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/26/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeGradientFill.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTShapeGradientFill
13 |
14 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
15 | self = [super init];
16 | if (self) {
17 | [self _mapFromJSON:jsonDictionary];
18 | }
19 | return self;
20 | }
21 |
22 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
23 | if (jsonDictionary[@"nm"] ) {
24 | _keyname = [jsonDictionary[@"nm"] copy];
25 | }
26 |
27 | NSNumber *type = jsonDictionary[@"t"];
28 |
29 | if (type.integerValue != 1) {
30 | _type = LOTGradientTypeRadial;
31 | } else {
32 | _type = LOTGradientTypeLinear;
33 | }
34 |
35 | NSDictionary *start = jsonDictionary[@"s"];
36 | if (start) {
37 | _startPoint = [[LOTKeyframeGroup alloc] initWithData:start];
38 | }
39 |
40 | NSDictionary *end = jsonDictionary[@"e"];
41 | if (end) {
42 | _endPoint = [[LOTKeyframeGroup alloc] initWithData:end];
43 | }
44 |
45 | NSDictionary *gradient = jsonDictionary[@"g"];
46 | if (gradient) {
47 | NSDictionary *unwrappedGradient = gradient[@"k"];
48 | _numberOfColors = gradient[@"p"];
49 | _gradient = [[LOTKeyframeGroup alloc] initWithData:unwrappedGradient];
50 | }
51 |
52 | NSDictionary *opacity = jsonDictionary[@"o"];
53 | if (opacity) {
54 | _opacity = [[LOTKeyframeGroup alloc] initWithData:opacity];
55 | [_opacity remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
56 | return LOT_RemapValue(inValue, 0, 100, 0, 1);
57 | }];
58 | }
59 |
60 | NSNumber *evenOdd = jsonDictionary[@"r"];
61 | if (evenOdd.integerValue == 2) {
62 | _evenOddFillRule = YES;
63 | } else {
64 | _evenOddFillRule = NO;
65 | }
66 | }
67 | @end
68 |
--------------------------------------------------------------------------------
/Example/XAnimation/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeStar.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeStar.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeStar.h"
10 |
11 | @implementation LOTShapeStar
12 |
13 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
14 | self = [super init];
15 | if (self) {
16 | [self _mapFromJSON:jsonDictionary];
17 | }
18 | return self;
19 | }
20 |
21 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
22 |
23 | if (jsonDictionary[@"nm"] ) {
24 | _keyname = [jsonDictionary[@"nm"] copy];
25 | }
26 |
27 | NSDictionary *outerRadius = jsonDictionary[@"or"];
28 | if (outerRadius) {
29 | _outerRadius = [[LOTKeyframeGroup alloc] initWithData:outerRadius];
30 | }
31 |
32 | NSDictionary *outerRoundness = jsonDictionary[@"os"];
33 | if (outerRoundness) {
34 | _outerRoundness = [[LOTKeyframeGroup alloc] initWithData:outerRoundness];
35 | }
36 |
37 | NSDictionary *innerRadius = jsonDictionary[@"ir"];
38 | if (innerRadius) {
39 | _innerRadius = [[LOTKeyframeGroup alloc] initWithData:innerRadius];
40 | }
41 |
42 | NSDictionary *innerRoundness = jsonDictionary[@"is"];
43 | if (innerRoundness) {
44 | _innerRoundness = [[LOTKeyframeGroup alloc] initWithData:innerRoundness];
45 | }
46 |
47 | NSDictionary *position = jsonDictionary[@"p"];
48 | if (position) {
49 | _position = [[LOTKeyframeGroup alloc] initWithData:position];
50 | }
51 |
52 | NSDictionary *numberOfPoints = jsonDictionary[@"pt"];
53 | if (numberOfPoints) {
54 | _numberOfPoints = [[LOTKeyframeGroup alloc] initWithData:numberOfPoints];
55 | }
56 |
57 | NSDictionary *rotation = jsonDictionary[@"r"];
58 | if (rotation) {
59 | _rotation = [[LOTKeyframeGroup alloc] initWithData:rotation];
60 | }
61 |
62 | NSNumber *type = jsonDictionary[@"sy"];
63 | _type = type.integerValue;
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/Example/XAnimation/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTAnimatedSwitch.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimatedSwitch.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 8/25/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTAnimatedControl.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface LOTAnimatedSwitch : LOTAnimatedControl
14 |
15 | /// Convenience method to initialize a control from the Main Bundle by name
16 | + (instancetype _Nonnull)switchNamed:(NSString * _Nonnull)toggleName;
17 |
18 | /// Convenience method to initialize a control from the specified bundle by name
19 | + (instancetype _Nonnull)switchNamed:(NSString * _Nonnull)toggleName inBundle:(NSBundle * _Nonnull)bundle;
20 |
21 |
22 | /// The ON/OFF state of the control. Setting will toggle without animation
23 | @property (nonatomic, getter=isOn) BOOL on;
24 |
25 | /// Enable interactive sliding gesture for toggle
26 | @property (nonatomic) BOOL interactiveGesture;
27 |
28 | /// Set the state of the control with animation
29 | - (void)setOn:(BOOL)on animated:(BOOL)animated; // does not send action
30 |
31 | /// Styling
32 |
33 | /**
34 | * Sets the animation play range for the ON state animation.
35 | * fromProgress is the start of the animation
36 | * toProgress is the end of the animation and also the ON static state
37 | * Defaults 0-1
38 | **/
39 | - (void)setProgressRangeForOnState:(CGFloat)fromProgress
40 | toProgress:(CGFloat)toProgress NS_SWIFT_NAME(setProgressRangeForOnState(fromProgress:toProgress:));
41 |
42 | /**
43 | * Sets the animation play range for the OFF state animation.
44 | * fromProgress is the start of the animation
45 | * toProgress is the end of the animation and also the OFF static state
46 | * Defaults 1-0
47 | **/
48 | - (void)setProgressRangeForOffState:(CGFloat)fromProgress
49 | toProgress:(CGFloat)toProgress NS_SWIFT_NAME(setProgressRangeForOffState(fromProgress:toProgress:));
50 |
51 | @end
52 |
53 | NS_ASSUME_NONNULL_END
54 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Private/LOTAnimationCache.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimationCache.m
3 | // Lottie
4 | //
5 | // Created by Brandon Withrow on 1/9/17.
6 | // Copyright © 2017 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTAnimationCache.h"
10 |
11 | const NSInteger kLOTCacheSize = 50;
12 |
13 | @implementation LOTAnimationCache {
14 | NSMutableDictionary *animationsCache_;
15 | NSMutableArray *lruOrderArray_;
16 | }
17 |
18 | + (instancetype)sharedCache {
19 | static LOTAnimationCache *sharedCache = nil;
20 | static dispatch_once_t onceToken;
21 | dispatch_once(&onceToken, ^{
22 | sharedCache = [[self alloc] init];
23 | });
24 | return sharedCache;
25 | }
26 |
27 | - (instancetype)init {
28 | self = [super init];
29 | if (self) {
30 | animationsCache_ = [[NSMutableDictionary alloc] init];
31 | lruOrderArray_ = [[NSMutableArray alloc] init];
32 | }
33 | return self;
34 | }
35 |
36 | - (void)addAnimation:(LOTComposition *)animation forKey:(NSString *)key {
37 | if (lruOrderArray_.count >= kLOTCacheSize) {
38 | NSString *oldKey = lruOrderArray_[0];
39 | [animationsCache_ removeObjectForKey:oldKey];
40 | [lruOrderArray_ removeObject:oldKey];
41 | }
42 | [lruOrderArray_ removeObject:key];
43 | [lruOrderArray_ addObject:key];
44 | [animationsCache_ setObject:animation forKey:key];
45 | }
46 |
47 | - (LOTComposition *)animationForKey:(NSString *)key {
48 | if (!key) {
49 | return nil;
50 | }
51 | LOTComposition *animation = [animationsCache_ objectForKey:key];
52 | [lruOrderArray_ removeObject:key];
53 | [lruOrderArray_ addObject:key];
54 | return animation;
55 | }
56 |
57 | - (void)clearCache {
58 | [animationsCache_ removeAllObjects];
59 | [lruOrderArray_ removeAllObjects];
60 | }
61 |
62 | - (void)removeAnimationForKey:(NSString *)key {
63 | [lruOrderArray_ removeObject:key];
64 | [animationsCache_ removeObjectForKey:key];
65 | }
66 |
67 | - (void)disableCaching {
68 | [self clearCache];
69 | animationsCache_ = nil;
70 | lruOrderArray_ = nil;
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/Example/XAnimation/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/CALayer+XALottie.m:
--------------------------------------------------------------------------------
1 | //
2 | // CALayer+XALottie.m
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/20.
6 | //
7 |
8 | #import "CALayer+XALottie.h"
9 | #import
10 | #import "XABindLottieController.h"
11 | static const char *kXALotLayerNM = "XALotLayerNM";
12 | static const char *kBindLotController = "XY80861";
13 |
14 | @implementation CALayer (XALottie)
15 |
16 | - (XABindLottieController *)bindLottieWithContentsOfURL:(nonnull NSURL *)url{
17 | XABindLottieController *controller = [XABindLottieController bindLottieWithContentsOfURL:url toHost:self];
18 | if (controller){
19 | objc_setAssociatedObject(self, kBindLotController, controller, OBJC_ASSOCIATION_RETAIN);
20 | }
21 | return controller;
22 | }
23 |
24 | - (XABindLottieController *)bindLottieWithAnimationNamed:(NSString *)animationNamed{
25 | XABindLottieController *controller = [XABindLottieController bindLottieWithAnimationNamed:animationNamed toHost:self];
26 | if (controller){
27 | objc_setAssociatedObject(self, kBindLotController, controller, OBJC_ASSOCIATION_RETAIN);
28 | }
29 | return controller;
30 | }
31 |
32 | - (XABindLottieController *)bindLottieWithFilePath:(NSString *)filePath{
33 | XABindLottieController *controller = [XABindLottieController bindLottieWithFilePath:filePath toHost:self];
34 | if (controller){
35 | objc_setAssociatedObject(self, kBindLotController, controller, OBJC_ASSOCIATION_RETAIN);
36 | }
37 | return controller;
38 | }
39 |
40 | - (void)bindLottieLayerName:(NSString *)lotLayerName{
41 | if (lotLayerName && [lotLayerName isKindOfClass:[NSString class]] ) {
42 | objc_setAssociatedObject(self, kXALotLayerNM, lotLayerName, OBJC_ASSOCIATION_RETAIN);
43 | }
44 | }
45 |
46 | - (NSString *)bindLottieLayerName{
47 | NSString *name = objc_getAssociatedObject(self, kXALotLayerNM);
48 | return name;
49 | }
50 |
51 | - (XABindLottieController *)currentBindController{
52 | XABindLottieController *controller = objc_getAssociatedObject(self, kBindLotController);
53 | return controller;
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/Example/XAnimation/XAAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // XAAppDelegate.m
3 | // XAnimation
4 | //
5 | // Created by wangxiyuan on 09/14/2022.
6 | // Copyright (c) 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import "XAAppDelegate.h"
10 |
11 | @implementation XAAppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeStroke.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeStroke.m
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeStroke.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTShapeStroke
13 |
14 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
15 | self = [super init];
16 | if (self) {
17 | [self _mapFromJSON:jsonDictionary];
18 | }
19 | return self;
20 | }
21 |
22 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
23 |
24 | if (jsonDictionary[@"nm"] ) {
25 | _keyname = [jsonDictionary[@"nm"] copy];
26 | }
27 |
28 | NSDictionary *color = jsonDictionary[@"c"];
29 | if (color) {
30 | _color = [[LOTKeyframeGroup alloc] initWithData:color];
31 | }
32 |
33 | NSDictionary *width = jsonDictionary[@"w"];
34 | if (width) {
35 | _width = [[LOTKeyframeGroup alloc] initWithData:width];
36 | }
37 |
38 | NSDictionary *opacity = jsonDictionary[@"o"];
39 | if (opacity) {
40 | _opacity = [[LOTKeyframeGroup alloc] initWithData:opacity];
41 | [_opacity remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
42 | return LOT_RemapValue(inValue, 0, 100, 0, 1);
43 | }];
44 | }
45 |
46 | _capType = [jsonDictionary[@"lc"] integerValue] - 1;
47 | _joinType = [jsonDictionary[@"lj"] integerValue] - 1;
48 |
49 | NSNumber *fillEnabled = jsonDictionary[@"fillEnabled"];
50 | _fillEnabled = fillEnabled.boolValue;
51 |
52 | NSDictionary *dashOffset = nil;
53 | NSArray *dashes = jsonDictionary[@"d"];
54 | if (dashes) {
55 | NSMutableArray *dashPattern = [NSMutableArray array];
56 | for (NSDictionary *dash in dashes) {
57 | if ([dash[@"n"] isEqualToString:@"o"]) {
58 | dashOffset = dash[@"v"];
59 | continue;
60 | }
61 | // TODO DASH PATTERNS
62 | NSDictionary *value = dash[@"v"];
63 | LOTKeyframeGroup *keyframeGroup = [[LOTKeyframeGroup alloc] initWithData:value];
64 | [dashPattern addObject:keyframeGroup];
65 | }
66 | _lineDashPattern = dashPattern;
67 | }
68 | if (dashOffset) {
69 | _dashOffset = [[LOTKeyframeGroup alloc] initWithData:dashOffset];
70 | }
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/XAnimation.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod lib lint XAnimation.podspec' to ensure this is a
3 | # valid spec before submitting.
4 | #
5 | # Any lines starting with a # are optional, but their use is encouraged
6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
7 | #
8 |
9 | Pod::Spec.new do |s|
10 | s.name = 'XAnimation'
11 | s.version = '0.1.1'
12 | s.summary = 'XAnimation based on opensorce airbnb Lottie to apply AE Animation to yourself layer.'
13 |
14 | # This description is used to generate tags and improve search results.
15 | # * Think: What does it do? Why did you write it? What is the focus?
16 | # * Try to keep it short, snappy and to the point.
17 | # * Write the description between the DESC delimiters below.
18 | # * Finally, don't worry about the indent, CocoaPods strips it!
19 |
20 | s.description = <<-DESC
21 | Use XAnimation you can run lottie file effect on yourself view or layer. that means whatever view or layer exsits can attach lottie animation effect without modify your own logic. it's cool?
22 | DESC
23 |
24 | s.homepage = 'https://github.com/JDFED/XAnimation'
25 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
26 | s.license = { :type => 'Apache License 2.0', :file => 'LICENSE' }
27 | s.author = { 'wangxiyuan' => 'wangxiyuan613@163.com' }
28 | s.source = { :git => 'https://github.com/JDFED/XAnimation.git', :tag => s.version.to_s }
29 | # s.social_media_url = 'https://twitter.com/'
30 |
31 | s.ios.deployment_target = '10.0'
32 |
33 | s.source_files = 'XAnimation/Classes/**/*'
34 | s.resources = 'XAnimation/Classes/**/*'
35 | # s.resource_bundles = {
36 | # 'XAnimation' => ['XAnimation/Assets/*.png']
37 | # }
38 |
39 | s.static_framework = true
40 | # # arc和mrc选项
41 | s.requires_arc = true
42 | # # 链接设置 重要
43 | # s.xcconfig = {'OTHER_LDFLAGS' => '-ObjC'}
44 |
45 | s.public_header_files = "XAnimation/Classes/PublicHeaders/*.h","XAnimation/Classes/XAimationExtends/PublicHeaders/*.h"
46 | #如果需要暴露头文件,请保留umbrella.h,头文件不给值默认所有头文件为public
47 |
48 | # s.frameworks = 'UIKit', 'MapKit'
49 | # s.dependency 'AFNetworking', '~> 2.3'
50 | end
51 |
52 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTPointInterpolator.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTPointInterpolator.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/12/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTPointInterpolator.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTPointInterpolator
13 |
14 | - (CGPoint)pointValueForFrame:(NSNumber *)frame {
15 | CGFloat progress = [self progressForFrame:frame];
16 | CGPoint returnPoint;
17 | if (progress == 0) {
18 | returnPoint = self.leadingKeyframe.pointValue;
19 | } else if (progress == 1) {
20 | returnPoint = self.trailingKeyframe.pointValue;
21 | } else if (!CGPointEqualToPoint(self.leadingKeyframe.spatialOutTangent, CGPointZero) ||
22 | !CGPointEqualToPoint(self.trailingKeyframe.spatialInTangent, CGPointZero)) {
23 | // Spatial Bezier path
24 | CGPoint outTan = LOT_PointAddedToPoint(self.leadingKeyframe.pointValue, self.leadingKeyframe.spatialOutTangent);
25 | CGPoint inTan = LOT_PointAddedToPoint(self.trailingKeyframe.pointValue, self.trailingKeyframe.spatialInTangent);
26 | returnPoint = LOT_PointInCubicCurve(self.leadingKeyframe.pointValue, outTan, inTan, self.trailingKeyframe.pointValue, progress);
27 | } else {
28 | returnPoint = LOT_PointInLine(self.leadingKeyframe.pointValue, self.trailingKeyframe.pointValue, progress);
29 | }
30 | if (self.hasDelegateOverride) {
31 | return [self.delegate pointForFrame:frame.floatValue
32 | startKeyframe:self.leadingKeyframe.keyframeTime.floatValue
33 | endKeyframe:self.trailingKeyframe.keyframeTime.floatValue
34 | interpolatedProgress:progress
35 | startPoint:self.leadingKeyframe.pointValue
36 | endPoint:self.trailingKeyframe.pointValue
37 | currentPoint:returnPoint];
38 | }
39 | return returnPoint;
40 | }
41 |
42 | - (BOOL)hasDelegateOverride {
43 | return self.delegate != nil;
44 | }
45 |
46 | - (void)setValueDelegate:(id)delegate {
47 | NSAssert(([delegate conformsToProtocol:@protocol(LOTPointValueDelegate)]), @"Point Interpolator set with incorrect callback type. Expected LOTPointValueDelegate");
48 | self.delegate = (id)delegate;
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/UIView+XALottie.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+XALottie.m
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/20.
6 | //
7 |
8 | #import "UIView+XALottie.h"
9 | #import "XABindLottieController.h"
10 | #import
11 | #import "CALayer+XALottie.h"
12 |
13 | static const char *kXALotLayerNM = "XALotLayerNM";
14 | static const char *kBindLotController = "XY80861";
15 |
16 | @implementation UIView (XALottie)
17 |
18 | - (XABindLottieController *)bindLottieWithContentsOfURL:(nonnull NSURL *)url{
19 | XABindLottieController *controller = [XABindLottieController bindLottieWithContentsOfURL:url toHost:self];
20 | if (controller){
21 | objc_setAssociatedObject(self, kBindLotController, controller, OBJC_ASSOCIATION_RETAIN);
22 | if (self.layer) {
23 | objc_setAssociatedObject(self.layer, kBindLotController, controller, OBJC_ASSOCIATION_RETAIN);
24 | }
25 | }
26 | return controller;
27 | }
28 |
29 | - (XABindLottieController *)bindLottieWithAnimationNamed:(NSString *)animationNamed{
30 | XABindLottieController *controller = [XABindLottieController bindLottieWithAnimationNamed:animationNamed toHost:self];
31 | if (controller){
32 | objc_setAssociatedObject(self, kBindLotController, controller, OBJC_ASSOCIATION_RETAIN);
33 | }
34 | return controller;
35 | }
36 |
37 | - (XABindLottieController *)bindLottieWithFilePath:(NSString *)filePath{
38 | XABindLottieController *controller = [XABindLottieController bindLottieWithFilePath:filePath toHost:self];
39 | if (controller){
40 | objc_setAssociatedObject(self, kBindLotController, controller, OBJC_ASSOCIATION_RETAIN);
41 | }
42 | return controller;
43 | }
44 |
45 |
46 | - (void)bindLottieLayerName:(NSString *)lotLayerName{
47 | if (lotLayerName && [lotLayerName isKindOfClass:[NSString class]] ) {
48 | objc_setAssociatedObject(self, kXALotLayerNM, lotLayerName, OBJC_ASSOCIATION_RETAIN);
49 | [self.layer bindLottieLayerName:lotLayerName];
50 | }
51 | }
52 |
53 | - (NSString *)bindLottieLayerName{
54 | NSString *name = objc_getAssociatedObject(self, kXALotLayerNM);
55 | return name;
56 | }
57 |
58 | - (XABindLottieController *)currentBindController{
59 | XABindLottieController *controller = objc_getAssociatedObject(self, kBindLotController);
60 | return controller;
61 | }
62 | @end
63 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTAssetGroup.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAssetGroup.m
3 | // Pods
4 | //
5 | // Created by Brandon Withrow on 2/17/17.
6 | //
7 | //
8 |
9 | #import "LOTAssetGroup.h"
10 | #import "LOTAsset.h"
11 |
12 | @implementation LOTAssetGroup {
13 | NSMutableDictionary *_assetMap;
14 | NSDictionary *_assetJSONMap;
15 | }
16 |
17 | - (instancetype _Nonnull)initWithJSON:(NSArray * _Nonnull)jsonArray
18 | withAssetBundle:(NSBundle * _Nullable)bundle
19 | withFramerate:(NSNumber * _Nonnull)framerate {
20 | self = [super init];
21 | if (self) {
22 | _assetBundle = bundle;
23 | _assetMap = [NSMutableDictionary dictionary];
24 | NSMutableDictionary *assetJSONMap = [NSMutableDictionary dictionary];
25 | for (NSDictionary *assetDictionary in jsonArray) {
26 | NSString *referenceID = assetDictionary[@"id"];
27 | if (referenceID) {
28 | assetJSONMap[referenceID] = assetDictionary;
29 | }
30 | }
31 | _assetJSONMap = assetJSONMap;
32 | }
33 | return self;
34 | }
35 |
36 | - (void)buildAssetNamed:(NSString *)refID
37 | withFramerate:(NSNumber * _Nonnull)framerate {
38 |
39 | if ([self assetModelForID:refID]) {
40 | return;
41 | }
42 |
43 | NSDictionary *assetDictionary = _assetJSONMap[refID];
44 | if (assetDictionary) {
45 | LOTAsset *asset = [[LOTAsset alloc] initWithJSON:assetDictionary
46 | withAssetGroup:self
47 | withAssetBundle:_assetBundle
48 | withFramerate:framerate];
49 | _assetMap[refID] = asset;
50 | }
51 | }
52 |
53 | - (void)finalizeInitializationWithFramerate:(NSNumber * _Nonnull)framerate {
54 | for (NSString *refID in _assetJSONMap.allKeys) {
55 | [self buildAssetNamed:refID withFramerate:framerate];
56 | }
57 | _assetJSONMap = nil;
58 | }
59 |
60 | - (LOTAsset *)assetModelForID:(NSString *)assetID {
61 | return _assetMap[assetID];
62 | }
63 |
64 | - (void)setRootDirectory:(NSString *)rootDirectory {
65 | _rootDirectory = rootDirectory;
66 | [_assetMap enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, LOTAsset * _Nonnull obj, BOOL * _Nonnull stop) {
67 | obj.rootDirectory = rootDirectory;
68 | }];
69 | }
70 | @end
71 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/RenderNodes/LOTFillRenderer.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTFillRenderer.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 6/27/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTFillRenderer.h"
10 | #import "LOTColorInterpolator.h"
11 | #import "LOTNumberInterpolator.h"
12 | #import "LOTHelpers.h"
13 |
14 | @implementation LOTFillRenderer {
15 | LOTColorInterpolator *colorInterpolator_;
16 | LOTNumberInterpolator *opacityInterpolator_;
17 | BOOL _evenOddFillRule;
18 | CALayer *centerPoint_DEBUG;
19 | }
20 |
21 | - (instancetype)initWithInputNode:(LOTAnimatorNode *)inputNode
22 | shapeFill:(LOTShapeFill *)fill {
23 | self = [super initWithInputNode:inputNode keyName:fill.keyname];
24 | if (self) {
25 | colorInterpolator_ = [[LOTColorInterpolator alloc] initWithKeyframes:fill.color.keyframes];
26 | opacityInterpolator_ = [[LOTNumberInterpolator alloc] initWithKeyframes:fill.opacity.keyframes];
27 | centerPoint_DEBUG = [CALayer layer];
28 | centerPoint_DEBUG.bounds = CGRectMake(0, 0, 20, 20);
29 | if (ENABLE_DEBUG_SHAPES) {
30 | [self.outputLayer addSublayer:centerPoint_DEBUG];
31 | }
32 | _evenOddFillRule = fill.evenOddFillRule;
33 |
34 | self.outputLayer.fillRule = _evenOddFillRule ? @"even-odd" : @"non-zero";
35 | }
36 | return self;
37 | }
38 |
39 | - (NSDictionary *)valueInterpolators {
40 | return @{@"Color" : colorInterpolator_,
41 | @"Opacity" : opacityInterpolator_};
42 | }
43 |
44 | - (BOOL)needsUpdateForFrame:(NSNumber *)frame {
45 | return [colorInterpolator_ hasUpdateForFrame:frame] || [opacityInterpolator_ hasUpdateForFrame:frame];
46 | }
47 |
48 | - (void)performLocalUpdate {
49 | centerPoint_DEBUG.backgroundColor = [colorInterpolator_ colorForFrame:self.currentFrame];
50 | centerPoint_DEBUG.borderColor = [UIColor lightGrayColor].CGColor;
51 | centerPoint_DEBUG.borderWidth = 2.f;
52 | self.outputLayer.fillColor = [colorInterpolator_ colorForFrame:self.currentFrame];
53 | self.outputLayer.opacity = [opacityInterpolator_ floatValueForFrame:self.currentFrame];
54 | }
55 |
56 | - (void)rebuildOutputs {
57 | self.outputLayer.path = self.inputNode.outputPath.CGPath;
58 | }
59 |
60 | - (NSDictionary *)actionsForRenderLayer {
61 | return @{@"backgroundColor": [NSNull null],
62 | @"fillColor": [NSNull null],
63 | @"opacity" : [NSNull null]};
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTComposition.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTScene.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/14/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class LOTLayerGroup;
13 | @class LOTLayer;
14 | @class LOTAssetGroup;
15 |
16 | @interface LOTComposition : NSObject
17 |
18 | /// Load animation by name from the default bundle, Images are also loaded from the bundle
19 | + (nullable instancetype)animationNamed:(nonnull NSString *)animationName NS_SWIFT_NAME(init(name:));
20 |
21 | /// Loads animation by name from specified bundle, Images are also loaded from the bundle
22 | + (nullable instancetype)animationNamed:(nonnull NSString *)animationName
23 | inBundle:(nonnull NSBundle *)bundle NS_SWIFT_NAME(init(name:bundle:));
24 |
25 | /// Loads an animation from a specific file path. WARNING Do not use a web URL for file path.
26 | + (nullable instancetype)animationWithFilePath:(nonnull NSString *)filePath NS_SWIFT_NAME(init(filePath:));
27 |
28 | /// Creates an animation from the deserialized JSON Dictionary
29 | + (nonnull instancetype)animationFromJSON:(nonnull NSDictionary *)animationJSON NS_SWIFT_NAME(init(json:));
30 |
31 | /// Creates an animation from the deserialized JSON Dictionary, images are loaded from the specified bundle
32 | + (nonnull instancetype)animationFromJSON:(nullable NSDictionary *)animationJSON
33 | inBundle:(nullable NSBundle *)bundle NS_SWIFT_NAME(init(json:bundle:));
34 |
35 | - (instancetype _Nonnull)initWithJSON:(NSDictionary * _Nullable)jsonDictionary
36 | withAssetBundle:(NSBundle * _Nullable)bundle;
37 |
38 | @property (nonatomic, readonly) CGRect compBounds;
39 | @property (nonatomic, strong, readonly, nullable) NSNumber *startFrame;
40 | @property (nonatomic, strong, readonly, nullable) NSNumber *endFrame;
41 | @property (nonatomic, strong, readonly, nullable) NSNumber *framerate;
42 | @property (nonatomic, readonly) NSTimeInterval timeDuration;
43 | @property (nonatomic, strong, readonly, nullable) LOTLayerGroup *layerGroup;
44 | @property (nonatomic, strong, readonly, nullable) LOTAssetGroup *assetGroup;
45 | @property (nonatomic, strong, readwrite, nullable) NSString *rootDirectory;
46 | @property (nonatomic, strong, readonly, nullable) NSBundle *assetBundle;
47 | @property (nonatomic, copy, nullable) NSString *cacheKey;
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Extensions/UIColor+Expanded.h:
--------------------------------------------------------------------------------
1 | #import "LOTPlatformCompat.h"
2 |
3 | // From http://github.com/ars/uicolor-utilities
4 | #define CLAMP(val,min,max) MIN(MAX(val,min),max)
5 |
6 | @interface UIColor (UIColor_Expanded)
7 | @property (nonatomic, readonly) CGColorSpaceModel colorSpaceModel;
8 | @property (nonatomic, readonly) BOOL canProvideRGBComponents;
9 | @property (nonatomic, readonly) CGFloat red; // Only valid if canProvideRGBComponents is YES
10 | @property (nonatomic, readonly) CGFloat green; // Only valid if canProvideRGBComponents is YES
11 | @property (nonatomic, readonly) CGFloat blue; // Only valid if canProvideRGBComponents is YES
12 | @property (nonatomic, readonly) CGFloat white; // Only valid if colorSpaceModel == kCGColorSpaceModelMonochrome
13 | @property (nonatomic, readonly) CGFloat alpha;
14 | @property (nonatomic, readonly) UInt32 rgbHex;
15 |
16 | - (NSString *)LOT_colorSpaceString;
17 |
18 | - (NSArray *)LOT_arrayFromRGBAComponents;
19 |
20 | - (BOOL)LOT_red:(CGFloat *)r green:(CGFloat *)g blue:(CGFloat *)b alpha:(CGFloat *)a;
21 |
22 | - (UIColor *)LOT_colorByLuminanceMapping;
23 |
24 | - (UIColor *)LOT_colorByMultiplyingByRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
25 | - (UIColor *) LOT_colorByAddingRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
26 | - (UIColor *) LOT_colorByLighteningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
27 | - (UIColor *) LOT_colorByDarkeningToRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
28 |
29 | - (UIColor *)LOT_colorByMultiplyingBy:(CGFloat)f;
30 | - (UIColor *) LOT_colorByAdding:(CGFloat)f;
31 | - (UIColor *) LOT_colorByLighteningTo:(CGFloat)f;
32 | - (UIColor *) LOT_colorByDarkeningTo:(CGFloat)f;
33 |
34 | - (UIColor *)LOT_colorByMultiplyingByColor:(UIColor *)color;
35 | - (UIColor *) LOT_colorByAddingColor:(UIColor *)color;
36 | - (UIColor *) LOT_colorByLighteningToColor:(UIColor *)color;
37 | - (UIColor *) LOT_colorByDarkeningToColor:(UIColor *)color;
38 |
39 | - (NSString *)LOT_stringFromColor;
40 | - (NSString *)LOT_hexStringValue;
41 |
42 | + (UIColor *)LOT_randomColor;
43 | + (UIColor *)LOT_colorWithString:(NSString *)stringToConvert;
44 | + (UIColor *)LOT_colorWithRGBHex:(UInt32)hex;
45 | + (UIColor *)LOT_colorWithHexString:(NSString *)stringToConvert;
46 |
47 | + (UIColor *)LOT_colorWithName:(NSString *)cssColorName;
48 |
49 | + (UIColor *)LOT_colorByLerpingFromColor:(UIColor *)fromColor toColor:(UIColor *)toColor amount:(CGFloat)amount;
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeRepeater.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeRepeater.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/28/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeRepeater.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTShapeRepeater
13 |
14 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
15 | self = [super init];
16 | if (self) {
17 | [self _mapFromJSON:jsonDictionary];
18 | }
19 | return self;
20 | }
21 |
22 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
23 |
24 | if (jsonDictionary[@"nm"] ) {
25 | _keyname = [jsonDictionary[@"nm"] copy];
26 | }
27 |
28 | NSDictionary *copies = jsonDictionary[@"c"];
29 | if (copies) {
30 | _copies = [[LOTKeyframeGroup alloc] initWithData:copies];
31 | }
32 |
33 | NSDictionary *offset = jsonDictionary[@"o"];
34 | if (offset) {
35 | _offset = [[LOTKeyframeGroup alloc] initWithData:offset];
36 | }
37 |
38 | NSDictionary *transform = jsonDictionary[@"tr"];
39 |
40 | NSDictionary *rotation = transform[@"r"];
41 | if (rotation) {
42 | _rotation = [[LOTKeyframeGroup alloc] initWithData:rotation];
43 | [_rotation remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
44 | return LOT_DegreesToRadians(inValue);
45 | }];
46 | }
47 |
48 | NSDictionary *startOpacity = transform[@"so"];
49 | if (startOpacity) {
50 | _startOpacity = [[LOTKeyframeGroup alloc] initWithData:startOpacity];
51 | [_startOpacity remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
52 | return LOT_RemapValue(inValue, 0, 100, 0, 1);
53 | }];
54 | }
55 |
56 | NSDictionary *endOpacity = transform[@"eo"];
57 | if (endOpacity) {
58 | _endOpacity = [[LOTKeyframeGroup alloc] initWithData:endOpacity];
59 | [_endOpacity remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
60 | return LOT_RemapValue(inValue, 0, 100, 0, 1);
61 | }];
62 | }
63 |
64 | NSDictionary *anchorPoint = transform[@"a"];
65 | if (anchorPoint) {
66 | _anchorPoint = [[LOTKeyframeGroup alloc] initWithData:anchorPoint];
67 | }
68 |
69 | NSDictionary *position = transform[@"p"];
70 | if (position) {
71 | _position = [[LOTKeyframeGroup alloc] initWithData:position];
72 | }
73 |
74 | NSDictionary *scale = transform[@"s"];
75 | if (scale) {
76 | _scale = [[LOTKeyframeGroup alloc] initWithData:scale];
77 | [_scale remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
78 | return LOT_RemapValue(inValue, -100, 100, -1, 1);
79 | }];
80 | }
81 | }
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Private/LOTInterpolatorCallback.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTInterpolatorCallback.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 1/5/18.
6 | // Copyright © 2018 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTInterpolatorCallback.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTFloatInterpolatorCallback
13 |
14 | + (instancetype _Nonnull)withFromFloat:(CGFloat)fromFloat toFloat:(CGFloat)toFloat {
15 | LOTFloatInterpolatorCallback *interpolator = [[self alloc] init];
16 | interpolator.fromFloat = fromFloat;
17 | interpolator.toFloat = toFloat;
18 | return interpolator;
19 | }
20 | - (CGFloat)floatValueForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startValue:(CGFloat)startValue endValue:(CGFloat)endValue currentValue:(CGFloat)interpolatedValue {
21 | return LOT_RemapValue(self.currentProgress, 0, 1, self.fromFloat, self.toFloat);
22 | }
23 |
24 | @end
25 |
26 | @implementation LOTPointInterpolatorCallback
27 |
28 | + (instancetype _Nonnull)withFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint {
29 | LOTPointInterpolatorCallback *interpolator = [[self alloc] init];
30 | interpolator.fromPoint = fromPoint;
31 | interpolator.toPoint = toPoint;
32 | return interpolator;
33 | }
34 | - (CGPoint)pointForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint currentPoint:(CGPoint)interpolatedPoint {
35 | return LOT_PointInLine(self.fromPoint, self.toPoint, self.currentProgress);
36 | }
37 |
38 | @end
39 |
40 | @implementation LOTSizeInterpolatorCallback
41 |
42 | + (instancetype)withFromSize:(CGSize)fromSize toSize:(CGSize)toSize {
43 | LOTSizeInterpolatorCallback *interpolator = [[self alloc] init];
44 | interpolator.fromSize = fromSize;
45 | interpolator.toSize = toSize;
46 | return interpolator;
47 | }
48 |
49 | - (CGSize)sizeForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startSize:(CGSize)startSize endSize:(CGSize)endSize currentSize:(CGSize)interpolatedSize {
50 | CGPoint from = CGPointMake(self.fromSize.width, self.fromSize.height);
51 | CGPoint to = CGPointMake(self.toSize.width, self.toSize.height);
52 | CGPoint returnPoint = LOT_PointInLine(from, to, self.currentProgress);
53 | return CGSizeMake(returnPoint.x, returnPoint.y);
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeTransform.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShapeTransform.m
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/15/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeTransform.h"
10 | #import "LOTHelpers.h"
11 |
12 | @implementation LOTShapeTransform
13 |
14 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
15 | self = [super init];
16 | if (self) {
17 | [self _mapFromJSON:jsonDictionary];
18 | }
19 | return self;
20 | }
21 |
22 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
23 |
24 | if (jsonDictionary[@"nm"] ) {
25 | _keyname = [jsonDictionary[@"nm"] copy];
26 | }
27 |
28 | NSDictionary *position = jsonDictionary[@"p"];
29 | if (position) {
30 | _position = [[LOTKeyframeGroup alloc] initWithData:position];
31 | }
32 |
33 | NSDictionary *anchor = jsonDictionary[@"a"];
34 | if (anchor) {
35 | _anchor = [[LOTKeyframeGroup alloc] initWithData:anchor];
36 | }
37 |
38 | NSDictionary *scale = jsonDictionary[@"s"];
39 | if (scale) {
40 | _scale = [[LOTKeyframeGroup alloc] initWithData:scale];
41 | [_scale remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
42 | return LOT_RemapValue(inValue, -100, 100, -1, 1);
43 | }];
44 | }
45 |
46 | NSDictionary *rotation = jsonDictionary[@"r"];
47 | if (rotation) {
48 | _rotation = [[LOTKeyframeGroup alloc] initWithData:rotation];
49 | [_rotation remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
50 | return LOT_DegreesToRadians(inValue);
51 | }];
52 | }
53 |
54 | NSDictionary *opacity = jsonDictionary[@"o"];
55 | if (opacity) {
56 | _opacity = [[LOTKeyframeGroup alloc] initWithData:opacity];
57 | [_opacity remapKeyframesWithBlock:^CGFloat(CGFloat inValue) {
58 | return LOT_RemapValue(inValue, 0, 100, 0, 1);
59 | }];
60 | }
61 |
62 | NSString *name = jsonDictionary[@"nm"];
63 |
64 | NSDictionary *skew = jsonDictionary[@"sk"];
65 | BOOL hasSkew = (skew && [skew[@"k"] isEqual:@0] == NO);
66 | NSDictionary *skewAxis = jsonDictionary[@"sa"];
67 | BOOL hasSkewAxis = (skewAxis && [skewAxis[@"k"] isEqual:@0] == NO);
68 |
69 | if (hasSkew || hasSkewAxis) {
70 | NSLog(@"%s: Warning: skew is not supported: %@", __PRETTY_FUNCTION__, name);
71 | }
72 | }
73 |
74 | - (NSString *)description {
75 | return [NSString stringWithFormat:@"LOTShapeTransform \"Position: %@ Anchor: %@ Scale: %@ Rotation: %@ Opacity: %@\"", _position.description, _anchor.description, _scale.description, _rotation.description, _opacity.description];
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/LOTAnimatorNode.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimatorNode.h
3 | // Pods
4 | //
5 | // Created by brandon_withrow on 6/27/17.
6 | //
7 | //
8 |
9 | #import
10 | #import "LOTPlatformCompat.h"
11 | #import "LOTBezierPath.h"
12 | #import "LOTKeypath.h"
13 | #import "LOTValueDelegate.h"
14 |
15 | extern NSInteger indentation_level;
16 | @interface LOTAnimatorNode : NSObject
17 |
18 | /// Initializes the node with and optional input node and keyname.
19 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
20 | keyName:(NSString *_Nullable)keyname;
21 |
22 | /// A dictionary of the value interpolators this node controls
23 | @property (nonatomic, readonly, strong) NSDictionary * _Nullable valueInterpolators;
24 |
25 | /// The keyname of the node. Used for dynamically setting keyframe data.
26 | @property (nonatomic, readonly, strong) NSString * _Nullable keyname;
27 |
28 | /// The current time in frames
29 | @property (nonatomic, readonly, strong) NSNumber * _Nullable currentFrame;
30 | /// The upstream animator node
31 | @property (nonatomic, readonly, strong) LOTAnimatorNode * _Nullable inputNode;
32 |
33 | /// This nodes path in local object space
34 | @property (nonatomic, strong) LOTBezierPath * _Nonnull localPath;
35 | /// The sum of all paths in the tree including this node
36 | @property (nonatomic, strong) LOTBezierPath * _Nonnull outputPath;
37 |
38 | /// Returns true if this node needs to update its contents for the given frame. To be overwritten by subclasses.
39 | - (BOOL)needsUpdateForFrame:(NSNumber *_Nonnull)frame;
40 |
41 | /// Sets the current frame and performs any updates. Returns true if any updates were performed, locally or upstream.
42 | - (BOOL)updateWithFrame:(NSNumber *_Nonnull)frame;
43 | - (BOOL)updateWithFrame:(NSNumber *_Nonnull)frame
44 | withModifierBlock:(void (^_Nullable)(LOTAnimatorNode * _Nonnull inputNode))modifier
45 | forceLocalUpdate:(BOOL)forceUpdate;
46 |
47 | - (void)forceSetCurrentFrame:(NSNumber *_Nonnull)frame;
48 |
49 | @property (nonatomic, assign) BOOL pathShouldCacheLengths;
50 | /// Update the local content for the frame.
51 | - (void)performLocalUpdate;
52 |
53 | /// Rebuild all outputs for the node. This is called after upstream updates have been performed.
54 | - (void)rebuildOutputs;
55 |
56 | - (void)logString:(NSString *_Nonnull)string;
57 |
58 | - (void)searchNodesForKeypath:(LOTKeypath * _Nonnull)keypath;
59 |
60 | - (void)setValueDelegate:(id _Nonnull)delegate
61 | forKeypath:(LOTKeypath * _Nonnull)keypath;
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTLayer.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTLayer.h
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/14/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LOTPlatformCompat.h"
11 | #import "LOTKeyframe.h"
12 |
13 | @class LOTShapeGroup;
14 | @class LOTMask;
15 | @class LOTAsset;
16 | @class LOTAssetGroup;
17 |
18 | typedef enum : NSInteger {
19 | LOTLayerTypePrecomp,
20 | LOTLayerTypeSolid,
21 | LOTLayerTypeImage,
22 | LOTLayerTypeNull,
23 | LOTLayerTypeShape,
24 | LOTLayerTypeUnknown
25 | } LOTLayerType;
26 |
27 | typedef enum : NSInteger {
28 | LOTMatteTypeNone,
29 | LOTMatteTypeAdd,
30 | LOTMatteTypeInvert,
31 | LOTMatteTypeUnknown
32 | } LOTMatteType;
33 |
34 | NS_ASSUME_NONNULL_BEGIN
35 |
36 | @interface LOTLayer : NSObject
37 |
38 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary
39 | withAssetGroup:(LOTAssetGroup * _Nullable)assetGroup
40 | withFramerate:(NSNumber *)framerate;
41 |
42 | @property (nonatomic, readonly) NSString *layerName;
43 | @property (nonatomic, readonly, nullable) NSString *referenceID;
44 | @property (nonatomic, readonly) NSNumber *layerID;
45 | @property (nonatomic, readonly) LOTLayerType layerType;
46 | @property (nonatomic, readonly, nullable) NSNumber *parentID;
47 | @property (nonatomic, readonly) NSNumber *startFrame;
48 | @property (nonatomic, readonly) NSNumber *inFrame;
49 | @property (nonatomic, readonly) NSNumber *outFrame;
50 | @property (nonatomic, readonly) NSNumber *timeStretch;
51 | @property (nonatomic, readonly) CGRect layerBounds;
52 |
53 | @property (nonatomic, readonly, nullable) NSArray *shapes;
54 | @property (nonatomic, readonly, nullable) NSArray *masks;
55 |
56 | @property (nonatomic, readonly, nullable) NSNumber *layerWidth;
57 | @property (nonatomic, readonly, nullable) NSNumber *layerHeight;
58 | @property (nonatomic, readonly, nullable) UIColor *solidColor;
59 | @property (nonatomic, readonly, nullable) LOTAsset *imageAsset;
60 |
61 | @property (nonatomic, readonly) LOTKeyframeGroup *opacity;
62 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *timeRemapping;
63 | @property (nonatomic, readonly) LOTKeyframeGroup *rotation;
64 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *position;
65 |
66 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *positionX;
67 | @property (nonatomic, readonly, nullable) LOTKeyframeGroup *positionY;
68 |
69 | @property (nonatomic, readonly) LOTKeyframeGroup *anchor;
70 | @property (nonatomic, readonly) LOTKeyframeGroup *scale;
71 |
72 | @property (nonatomic, readonly) LOTMatteType matteType;
73 |
74 | @end
75 |
76 | NS_ASSUME_NONNULL_END
77 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTTransformInterpolator.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Airbnb, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Modifications copyright (C) 2022 JD.com, Inc.
17 | */
18 |
19 | //
20 | // LOTTransformInterpolator.h
21 | // Lottie
22 | //
23 | // Created by brandon_withrow on 7/18/17.
24 | // Copyright © 2017 Airbnb. All rights reserved.
25 | //
26 |
27 | #import
28 | #import "LOTNumberInterpolator.h"
29 | #import "LOTPointInterpolator.h"
30 | #import "LOTSizeInterpolator.h"
31 | #import "LOTKeyframe.h"
32 | #import "LOTLayer.h"
33 |
34 | NS_ASSUME_NONNULL_BEGIN
35 |
36 | @interface LOTTransformInterpolator : NSObject
37 |
38 | + (instancetype)transformForLayer:(LOTLayer *)layer;
39 |
40 | - (instancetype)initWithPosition:(NSArray *)position
41 | rotation:(NSArray *)rotation
42 | anchor:(NSArray *)anchor
43 | scale:(NSArray *)scale;
44 |
45 | - (instancetype)initWithPositionX:(NSArray *)positionX
46 | positionY:(NSArray *)positionY
47 | rotation:(NSArray *)rotation
48 | anchor:(NSArray *)anchor
49 | scale:(NSArray *)scale;
50 |
51 | @property (nonatomic, strong) LOTTransformInterpolator * inputNode;
52 |
53 | @property (nonatomic, readonly) LOTPointInterpolator *positionInterpolator;
54 | @property (nonatomic, readonly) LOTPointInterpolator *anchorInterpolator;
55 | @property (nonatomic, readonly) LOTSizeInterpolator *scaleInterpolator;
56 | @property (nonatomic, readonly) LOTNumberInterpolator *rotationInterpolator;
57 | @property (nonatomic, readonly) LOTNumberInterpolator *positionXInterpolator;
58 | @property (nonatomic, readonly) LOTNumberInterpolator *positionYInterpolator;
59 | @property (nonatomic, strong, nullable) NSString *parentKeyName;
60 |
61 | - (CATransform3D)transformForFrame:(NSNumber *)frame;
62 | - (BOOL)hasUpdateForFrame:(NSNumber *)frame;
63 |
64 | //@wxy modify
65 | - (NSDictionary *)transformDicForFrame:(NSNumber *)frame;
66 |
67 | @end
68 |
69 | NS_ASSUME_NONNULL_END
70 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/BindLottieDemo/TestBindLottieRootViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestBindLottieRootViewController.m
3 | // XAnimation_Example
4 | //
5 | // Created by xiyuan wang on 2022/3/24.
6 | // Copyright © 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import "TestBindLottieRootViewController.h"
10 | #import
11 | #import
12 | #import
13 |
14 | @interface TestBindLottieRootViewController ()
15 |
16 | @property (strong, nonatomic) UIView *testBindView;
17 | @property (strong, nonatomic) NSArray *titles;
18 | @property (strong, nonatomic) NSArray *classNames;
19 |
20 | @end
21 |
22 | @implementation TestBindLottieRootViewController
23 |
24 | - (void)viewDidLoad
25 | {
26 | [super viewDidLoad];
27 | self.navigationController.navigationBar.translucent = NO;
28 | self.title = @"绑定 Lottie 测试";
29 | self.titles = @[
30 | @"绑定(旋转 平移 缩放)",
31 | @"绑定(呼吸效果)",
32 | @"2个图层联动",
33 | @"播放控制",
34 | @"动态更换内容",
35 | @"锚点适配",
36 | ];
37 | self.classNames = @[
38 | @"TestBind0",
39 | @"TestBind1",
40 | @"TestBind2",
41 | @"TestBind3",
42 | @"TestBind4",
43 | @"TestBind5",
44 | ];
45 | [self runTest];
46 | }
47 |
48 | - (void)viewDidAppear:(BOOL)animated{
49 | [super viewDidAppear:animated];
50 | }
51 |
52 | - (void)runTest{
53 | self.view.backgroundColor = [UIColor purpleColor];
54 |
55 | UITableView *table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
56 | [table registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
57 | table.dataSource = self;
58 | table.delegate = self;
59 | table.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
60 | [self.view addSubview:table];
61 |
62 | }
63 |
64 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
65 | return self.titles.count;
66 | }
67 |
68 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
69 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
70 | cell.textLabel.font = [UIFont systemFontOfSize:20];
71 | cell.textLabel.text = [NSString stringWithFormat:@"演示%ld: %@", indexPath.row + 1, self.titles[indexPath.row]];
72 | return cell;
73 | }
74 |
75 |
76 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
77 | return 60;
78 | }
79 |
80 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
81 | NSString *className = self.classNames[indexPath.row];
82 | Class cls = NSClassFromString(className);
83 | if (cls) {
84 | UIViewController *vc = [cls new];
85 | vc.title = self.titles[indexPath.row];
86 | [self.navigationController pushViewController:vc animated:YES];
87 | }
88 | }
89 |
90 | @end
91 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Private/LOTValueCallback.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTValueCallback.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 12/15/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTValueCallback.h"
10 |
11 | @implementation LOTColorValueCallback
12 |
13 | + (instancetype _Nonnull)withCGColor:(CGColorRef _Nonnull)color {
14 | LOTColorValueCallback *colorCallback = [[self alloc] init];
15 | colorCallback.colorValue = color;
16 | return colorCallback;
17 | }
18 |
19 | - (CGColorRef)colorForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startColor:(CGColorRef)startColor endColor:(CGColorRef)endColor currentColor:(CGColorRef)interpolatedColor {
20 | return self.colorValue;
21 | }
22 |
23 | @end
24 |
25 | @implementation LOTNumberValueCallback
26 |
27 | + (instancetype _Nonnull)withFloatValue:(CGFloat)numberValue {
28 | LOTNumberValueCallback *numberCallback = [[self alloc] init];
29 | numberCallback.numberValue = numberValue;
30 | return numberCallback;
31 | }
32 |
33 | - (CGFloat)floatValueForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startValue:(CGFloat)startValue endValue:(CGFloat)endValue currentValue:(CGFloat)interpolatedValue {
34 | return self.numberValue;
35 | }
36 |
37 | @end
38 |
39 | @implementation LOTPointValueCallback
40 |
41 | + (instancetype _Nonnull)withPointValue:(CGPoint)pointValue {
42 | LOTPointValueCallback *callback = [[self alloc] init];
43 | callback.pointValue = pointValue;
44 | return callback;
45 | }
46 |
47 | - (CGPoint)pointForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint currentPoint:(CGPoint)interpolatedPoint {
48 | return self.pointValue;
49 | }
50 |
51 | @end
52 |
53 | @implementation LOTSizeValueCallback
54 |
55 | + (instancetype _Nonnull)withPointValue:(CGSize)sizeValue {
56 | LOTSizeValueCallback *callback = [[self alloc] init];
57 | callback.sizeValue = sizeValue;
58 | return callback;
59 | }
60 |
61 | - (CGSize)sizeForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startSize:(CGSize)startSize endSize:(CGSize)endSize currentSize:(CGSize)interpolatedSize {
62 | return self.sizeValue;
63 | }
64 |
65 | @end
66 |
67 | @implementation LOTPathValueCallback
68 |
69 | + (instancetype _Nonnull)withCGPath:(CGPathRef _Nonnull)path {
70 | LOTPathValueCallback *callback = [[self alloc] init];
71 | callback.pathValue = path;
72 | return callback;
73 | }
74 |
75 | - (CGPathRef)pathForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress {
76 | return self.pathValue;
77 | }
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Extensions/LOTRadialGradientLayer.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimationView
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/14/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTRadialGradientLayer.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTRadialGradientLayer
13 |
14 | @dynamic isRadial;
15 | @dynamic startPoint;
16 | @dynamic endPoint;
17 | @dynamic colors;
18 | @dynamic locations;
19 |
20 | + (BOOL)needsDisplayForKey:(NSString *)key {
21 | if ([key isEqualToString:@"startPoint"] ||
22 | [key isEqualToString:@"endPoint"] ||
23 | [key isEqualToString:@"colors"] ||
24 | [key isEqualToString:@"locations"] ||
25 | [key isEqualToString:@"isRadial"]) {
26 | return YES;
27 | }
28 | return [super needsDisplayForKey:key];
29 | }
30 |
31 | - (id)actionForKey:(NSString *)key {
32 | id action = self.actions[key];
33 | if (action) {
34 | if (action == [NSNull null]) {
35 | return nil;
36 | }
37 | return action;
38 | }
39 |
40 | if ([key isEqualToString:@"startPoint"] ||
41 | [key isEqualToString:@"endPoint"] ||
42 | [key isEqualToString:@"colors"] ||
43 | [key isEqualToString:@"locations"] ||
44 | [key isEqualToString:@"isRadial"]) {
45 | CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:key];
46 | theAnimation.fromValue = [self.presentationLayer valueForKey:key];
47 | return theAnimation;
48 | }
49 | return [super actionForKey:key];
50 | }
51 |
52 | - (void)drawInContext:(CGContextRef)ctx {
53 | if (self.colors.count == 0) {
54 | return;
55 | }
56 |
57 | NSInteger numberOfLocations = self.locations.count;
58 | CGColorRef colorRef = (__bridge CGColorRef)[self.colors objectAtIndex:0];
59 | NSInteger numberOfComponents = CGColorGetNumberOfComponents(colorRef);
60 | CGColorSpaceRef colorSpace = CGColorGetColorSpace(colorRef);
61 |
62 | CGPoint origin = self.startPoint;
63 | CGFloat radius = LOT_PointDistanceFromPoint(self.startPoint, self.endPoint);
64 |
65 | CGFloat gradientLocations[numberOfLocations];
66 | CGFloat gradientComponents[numberOfLocations * numberOfComponents];
67 |
68 | for (NSInteger locationIndex = 0; locationIndex < numberOfLocations; locationIndex++) {
69 |
70 | gradientLocations[locationIndex] = [self.locations[locationIndex] floatValue];
71 | const CGFloat *colorComponents = CGColorGetComponents((__bridge CGColorRef)self.colors[locationIndex]);
72 |
73 | for (NSInteger componentIndex = 0; componentIndex < numberOfComponents; componentIndex++) {
74 | gradientComponents[numberOfComponents * locationIndex + componentIndex] = colorComponents[componentIndex];
75 | }
76 | }
77 |
78 | CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientComponents, gradientLocations, numberOfLocations);
79 |
80 | if (self.isRadial) {
81 | CGContextDrawRadialGradient(ctx, gradient, origin, 0, origin, radius, kCGGradientDrawsAfterEndLocation);
82 | } else {
83 | CGContextDrawLinearGradient(ctx, gradient, self.startPoint, self.endPoint, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
84 | }
85 |
86 | CGGradientRelease(gradient);
87 | }
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTInterpolatorCallback.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTInterpolatorCallback.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 12/15/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "LOTValueDelegate.h"
12 |
13 | /*!
14 | @brief LOTPointInterpolatorCallback is a container for a CGPointRef. This container is a LOTPointValueDelegate that will return the point interpolated at currentProgress between fromPoint and toPoint. Externally changing currentProgress will change the point of the animation.
15 | @discussion LOTPointInterpolatorCallback is used in conjunction with LOTAnimationView setValueDelegate:forKeypoint to set a point value of an animation property.
16 | */
17 |
18 | @interface LOTPointInterpolatorCallback : NSObject
19 |
20 | + (instancetype _Nonnull)withFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint NS_SWIFT_NAME(init(from:to:));
21 |
22 | @property (nonatomic) CGPoint fromPoint;
23 | @property (nonatomic) CGPoint toPoint;
24 |
25 | /*!
26 | @brief As currentProgress changes from 0 to 1 the point sent to the animation view is interpolated between fromPoint and toPoint.
27 | */
28 |
29 | @property (nonatomic, assign) CGFloat currentProgress;
30 |
31 | @end
32 |
33 | /*!
34 | @brief LOTSizeInterpolatorCallback is a container for a CGSizeRef. This container is a LOTSizeValueDelegate that will return the size interpolated at currentProgress between fromSize and toSize. Externally changing currentProgress will change the size of the animation.
35 | @discussion LOTSizeInterpolatorCallback is used in conjunction with LOTAnimationView setValueDelegate:forKeysize to set a size value of an animation property.
36 | */
37 |
38 | @interface LOTSizeInterpolatorCallback : NSObject
39 |
40 | + (instancetype _Nonnull)withFromSize:(CGSize)fromSize toSize:(CGSize)toSize NS_SWIFT_NAME(init(from:to:));
41 |
42 | @property (nonatomic) CGSize fromSize;
43 | @property (nonatomic) CGSize toSize;
44 |
45 | /*!
46 | @brief As currentProgress changes from 0 to 1 the size sent to the animation view is interpolated between fromSize and toSize.
47 | */
48 |
49 | @property (nonatomic, assign) CGFloat currentProgress;
50 |
51 | @end
52 |
53 | /*!
54 | @brief LOTFloatInterpolatorCallback is a container for a CGFloatRef. This container is a LOTFloatValueDelegate that will return the float interpolated at currentProgress between fromFloat and toFloat. Externally changing currentProgress will change the float of the animation.
55 | @discussion LOTFloatInterpolatorCallback is used in conjunction with LOTAnimationView setValueDelegate:forKeyfloat to set a float value of an animation property.
56 | */
57 |
58 | @interface LOTFloatInterpolatorCallback : NSObject
59 |
60 | + (instancetype _Nonnull)withFromFloat:(CGFloat)fromFloat toFloat:(CGFloat)toFloat NS_SWIFT_NAME(init(from:to:));
61 |
62 | @property (nonatomic) CGFloat fromFloat;
63 | @property (nonatomic) CGFloat toFloat;
64 |
65 | /*!
66 | @brief As currentProgress changes from 0 to 1 the float sent to the animation view is interpolated between fromFloat and toFloat.
67 | */
68 |
69 | @property (nonatomic, assign) CGFloat currentProgress;
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/AnimatorNodes/LOTCircleAnimator.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTCircleAnimator.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/19/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTCircleAnimator.h"
10 | #import "LOTPointInterpolator.h"
11 |
12 | const CGFloat kLOTEllipseControlPointPercentage = 0.55228;
13 |
14 | @implementation LOTCircleAnimator {
15 | LOTPointInterpolator *_centerInterpolator;
16 | LOTPointInterpolator *_sizeInterpolator;
17 | BOOL _reversed;
18 | }
19 |
20 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
21 | shapeCircle:(LOTShapeCircle *_Nonnull)shapeCircle {
22 | self = [super initWithInputNode:inputNode keyName:shapeCircle.keyname];
23 | if (self) {
24 | _centerInterpolator = [[LOTPointInterpolator alloc] initWithKeyframes:shapeCircle.position.keyframes];
25 | _sizeInterpolator = [[LOTPointInterpolator alloc] initWithKeyframes:shapeCircle.size.keyframes];
26 | _reversed = shapeCircle.reversed;
27 | }
28 | return self;
29 | }
30 |
31 | - (NSDictionary *)valueInterpolators {
32 | return @{@"Size" : _sizeInterpolator,
33 | @"Position" : _centerInterpolator};
34 | }
35 |
36 | - (BOOL)needsUpdateForFrame:(NSNumber *)frame {
37 | return [_centerInterpolator hasUpdateForFrame:frame] || [_sizeInterpolator hasUpdateForFrame:frame];
38 | }
39 |
40 | - (void)performLocalUpdate {
41 | // Unfortunately we HAVE to manually build out the ellipse.
42 | // Every Apple method constructs from the 3 o-clock position
43 | // After effects constructs from the Noon position.
44 | // After effects does clockwise, but also has a flag for reversed.
45 | CGPoint center = [_centerInterpolator pointValueForFrame:self.currentFrame];
46 | CGPoint size = [_sizeInterpolator pointValueForFrame:self.currentFrame];
47 |
48 | CGFloat halfWidth = size.x / 2;
49 | CGFloat halfHeight = size.y / 2;
50 |
51 | if (_reversed) {
52 | halfWidth = halfWidth * -1;
53 | }
54 |
55 | CGPoint circleQ1 = CGPointMake(center.x, center.y - halfHeight);
56 | CGPoint circleQ2 = CGPointMake(center.x + halfWidth, center.y);
57 | CGPoint circleQ3 = CGPointMake(center.x, center.y + halfHeight);
58 | CGPoint circleQ4 = CGPointMake(center.x - halfWidth, center.y);
59 |
60 | CGFloat cpW = halfWidth * kLOTEllipseControlPointPercentage;
61 | CGFloat cpH = halfHeight * kLOTEllipseControlPointPercentage;
62 |
63 | LOTBezierPath *path = [[LOTBezierPath alloc] init];
64 | path.cacheLengths = self.pathShouldCacheLengths;
65 | [path LOT_moveToPoint:circleQ1];
66 | [path LOT_addCurveToPoint:circleQ2 controlPoint1:CGPointMake(circleQ1.x + cpW, circleQ1.y) controlPoint2:CGPointMake(circleQ2.x, circleQ2.y - cpH)];
67 |
68 | [path LOT_addCurveToPoint:circleQ3 controlPoint1:CGPointMake(circleQ2.x, circleQ2.y + cpH) controlPoint2:CGPointMake(circleQ3.x + cpW, circleQ3.y)];
69 |
70 | [path LOT_addCurveToPoint:circleQ4 controlPoint1:CGPointMake(circleQ3.x - cpW, circleQ3.y) controlPoint2:CGPointMake(circleQ4.x, circleQ4.y + cpH)];
71 |
72 | [path LOT_addCurveToPoint:circleQ1 controlPoint1:CGPointMake(circleQ4.x, circleQ4.y - cpH) controlPoint2:CGPointMake(circleQ1.x - cpW, circleQ1.y)];
73 |
74 | self.localPath = path;
75 | }
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTValueCallback.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTValueCallback.h
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 12/15/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "LOTValueDelegate.h"
12 |
13 | /*!
14 | @brief LOTColorValueCallback is a container for a CGColorRef. This container is a LOTColorValueDelegate that always returns the colorValue property to its animation delegate.
15 | @discussion LOTColorValueCallback is used in conjunction with LOTAnimationView setValueDelegate:forKeypath to set a color value of an animation property.
16 | */
17 |
18 | @interface LOTColorValueCallback : NSObject
19 |
20 | + (instancetype _Nonnull)withCGColor:(CGColorRef _Nonnull)color NS_SWIFT_NAME(init(color:));
21 |
22 | @property (nonatomic, nonnull) CGColorRef colorValue;
23 |
24 | @end
25 |
26 | /*!
27 | @brief LOTNumberValueCallback is a container for a CGFloat value. This container is a LOTNumberValueDelegate that always returns the numberValue property to its animation delegate.
28 | @discussion LOTNumberValueCallback is used in conjunction with LOTAnimationView setValueDelegate:forKeypath to set a number value of an animation property.
29 | */
30 |
31 | @interface LOTNumberValueCallback : NSObject
32 |
33 | + (instancetype _Nonnull)withFloatValue:(CGFloat)numberValue NS_SWIFT_NAME(init(number:));
34 |
35 | @property (nonatomic, assign) CGFloat numberValue;
36 |
37 | @end
38 |
39 | /*!
40 | @brief LOTPointValueCallback is a container for a CGPoint value. This container is a LOTPointValueDelegate that always returns the pointValue property to its animation delegate.
41 | @discussion LOTPointValueCallback is used in conjunction with LOTAnimationView setValueDelegate:forKeypath to set a point value of an animation property.
42 | */
43 |
44 | @interface LOTPointValueCallback : NSObject
45 |
46 | + (instancetype _Nonnull)withPointValue:(CGPoint)pointValue;
47 |
48 | @property (nonatomic, assign) CGPoint pointValue;
49 |
50 | @end
51 |
52 | /*!
53 | @brief LOTSizeValueCallback is a container for a CGSize value. This container is a LOTSizeValueDelegate that always returns the sizeValue property to its animation delegate.
54 | @discussion LOTSizeValueCallback is used in conjunction with LOTAnimationView setValueDelegate:forKeypath to set a size value of an animation property.
55 | */
56 |
57 | @interface LOTSizeValueCallback : NSObject
58 |
59 | + (instancetype _Nonnull)withPointValue:(CGSize)sizeValue NS_SWIFT_NAME(init(size:));
60 |
61 | @property (nonatomic, assign) CGSize sizeValue;
62 |
63 | @end
64 |
65 | /*!
66 | @brief LOTPathValueCallback is a container for a CGPathRef value. This container is a LOTPathValueDelegate that always returns the pathValue property to its animation delegate.
67 | @discussion LOTPathValueCallback is used in conjunction with LOTAnimationView setValueDelegate:forKeypath to set a path value of an animation property.
68 | */
69 |
70 | @interface LOTPathValueCallback : NSObject
71 |
72 | + (instancetype _Nonnull)withCGPath:(CGPathRef _Nonnull)path NS_SWIFT_NAME(init(path:));
73 |
74 | @property (nonatomic, nonnull) CGPathRef pathValue;
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/XAnimation/Classes/AnimatableProperties/LOTBezierData.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTBezierData.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/10/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTBezierData.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTBezierData {
13 | CGPoint *_vertices;
14 | CGPoint *_inTangents;
15 | CGPoint *_outTangents;
16 | }
17 |
18 | - (instancetype)initWithData:(NSDictionary *)bezierData
19 | {
20 | self = [super init];
21 | if (self) {
22 | [self initializeData:bezierData];
23 | }
24 | return self;
25 | }
26 |
27 | - (void)dealloc {
28 | free(_vertices);
29 | free(_inTangents);
30 | free(_outTangents);
31 | }
32 |
33 | - (CGPoint)vertexAtIndex:(NSInteger)index {
34 | NSAssert((index < _count &&
35 | index >= 0),
36 | @"Lottie: Index out of bounds");
37 | return _vertices[index];
38 | }
39 |
40 | - (CGPoint)inTangentAtIndex:(NSInteger)index {
41 | NSAssert((index < _count &&
42 | index >= 0),
43 | @"Lottie: Index out of bounds");
44 | return _inTangents[index];
45 | }
46 |
47 | - (CGPoint)outTangentAtIndex:(NSInteger)index {
48 | NSAssert((index < _count &&
49 | index >= 0),
50 | @"Lottie: Index out of bounds");
51 | return _outTangents[index];
52 | }
53 |
54 | - (void)initializeData:(NSDictionary *)bezierData {
55 |
56 | NSArray *pointsArray = bezierData[@"v"];
57 | NSArray *inTangents = bezierData[@"i"];
58 | NSArray *outTangents = bezierData[@"o"];
59 |
60 | if (pointsArray.count == 0) {
61 | NSLog(@"%s: Warning: shape has no vertices", __PRETTY_FUNCTION__);
62 | return ;
63 | }
64 |
65 | NSAssert((pointsArray.count == inTangents.count &&
66 | pointsArray.count == outTangents.count),
67 | @"Lottie: Incorrect number of points and tangents");
68 | _count = pointsArray.count;
69 | _vertices = (CGPoint *)malloc(sizeof(CGPoint) * pointsArray.count);
70 | _inTangents = (CGPoint *)malloc(sizeof(CGPoint) * pointsArray.count);
71 | _outTangents = (CGPoint *)malloc(sizeof(CGPoint) * pointsArray.count);
72 | if (bezierData[@"c"]) {
73 | _closed = [bezierData[@"c"] boolValue];
74 | }
75 | for (int i = 0; i < pointsArray.count; i ++) {
76 | CGPoint vertex = [self _vertexAtIndex:i inArray:pointsArray];
77 | CGPoint outTan = LOT_PointAddedToPoint(vertex, [self _vertexAtIndex:i inArray:outTangents]);
78 | CGPoint inTan = LOT_PointAddedToPoint(vertex, [self _vertexAtIndex:i inArray:inTangents]);
79 | // BW BUG Straight Lines - Test Later
80 | // Bake fix for lines here
81 | _vertices[i] = vertex;
82 | _inTangents[i] = inTan;
83 | _outTangents[i] = outTan;
84 | }
85 | }
86 |
87 | - (CGPoint)_vertexAtIndex:(NSInteger)idx inArray:(NSArray *)points {
88 | NSAssert((idx < points.count),
89 | @"Lottie: Vertex Point out of bounds");
90 |
91 | NSArray *pointArray = points[idx];
92 |
93 | NSAssert((pointArray.count >= 2 &&
94 | [pointArray.firstObject isKindOfClass:[NSNumber class]]),
95 | @"Lottie: Point Data Malformed");
96 |
97 | return CGPointMake([(NSNumber *)pointArray[0] floatValue], [(NSNumber *)pointArray[1] floatValue]);
98 | }
99 |
100 | @end
101 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/InterpolatorNodes/LOTPathInterpolator.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTPathInterpolator.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/13/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTPathInterpolator.h"
10 | #import "CGGeometry+LOTAdditions.h"
11 |
12 | @implementation LOTPathInterpolator
13 |
14 | - (LOTBezierPath *)pathForFrame:(NSNumber *)frame cacheLengths:(BOOL)cacheLengths {
15 | CGFloat progress = [self progressForFrame:frame];
16 | if (self.hasDelegateOverride) {
17 | CGPathRef callBackPath = [self.delegate pathForFrame:frame.floatValue
18 | startKeyframe:self.leadingKeyframe.keyframeTime.floatValue
19 | endKeyframe:self.trailingKeyframe.keyframeTime.floatValue
20 | interpolatedProgress:progress];
21 | return [LOTBezierPath pathWithCGPath:callBackPath];
22 | }
23 |
24 | LOTBezierPath *returnPath = [[LOTBezierPath alloc] init];
25 | returnPath.cacheLengths = cacheLengths;
26 | LOTBezierData *leadingData = self.leadingKeyframe.pathData;
27 | LOTBezierData *trailingData = self.trailingKeyframe.pathData;
28 | NSInteger vertexCount = leadingData ? leadingData.count : trailingData.count;
29 | BOOL closePath = leadingData ? leadingData.closed : trailingData.closed;
30 | CGPoint cp1 = CGPointMake(0, 0);
31 | CGPoint cp2, p1, cp3 = CGPointZero;
32 | CGPoint startPoint = CGPointMake(0, 0);
33 | CGPoint startInTangent = CGPointMake(0, 0);
34 | for (int i = 0; i < vertexCount; i++) {
35 | if (progress == 0) {
36 | cp2 = [leadingData inTangentAtIndex:i];
37 | p1 = [leadingData vertexAtIndex:i];
38 | cp3 = [leadingData outTangentAtIndex:i];
39 | } else if (progress == 1) {
40 | cp2 = [trailingData inTangentAtIndex:i];
41 | p1 = [trailingData vertexAtIndex:i];
42 | cp3 = [trailingData outTangentAtIndex:i];
43 | } else {
44 | cp2 = LOT_PointInLine([leadingData inTangentAtIndex:i],
45 | [trailingData inTangentAtIndex:i],
46 | progress);
47 | p1 = LOT_PointInLine([leadingData vertexAtIndex:i],
48 | [trailingData vertexAtIndex:i],
49 | progress);
50 | cp3 = LOT_PointInLine([leadingData outTangentAtIndex:i],
51 | [trailingData outTangentAtIndex:i],
52 | progress);
53 | }
54 | if (i == 0) {
55 | startPoint = p1;
56 | startInTangent = cp2;
57 | [returnPath LOT_moveToPoint:p1];
58 | } else {
59 | [returnPath LOT_addCurveToPoint:p1 controlPoint1:cp1 controlPoint2:cp2];
60 | }
61 | cp1 = cp3;
62 | }
63 |
64 | if (closePath) {
65 | [returnPath LOT_addCurveToPoint:startPoint controlPoint1:cp3 controlPoint2:startInTangent];
66 | [returnPath LOT_closePath];
67 | }
68 |
69 | return returnPath;
70 | }
71 |
72 | - (void)setValueDelegate:(id)delegate {
73 | NSAssert(([delegate conformsToProtocol:@protocol(LOTPathValueDelegate)]), @"Path Interpolator set with incorrect callback type. Expected LOTPathValueDelegate");
74 | self.delegate = (id)delegate;
75 | }
76 |
77 | - (BOOL)hasDelegateOverride {
78 | return self.delegate != nil;
79 | }
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTAnimationTransitionController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTAnimationTransitionController.h
3 | // Lottie
4 | //
5 | // Created by Brandon Withrow on 1/18/17.
6 | // Copyright © 2017 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | /** LOTAnimationTransitionController
13 | *
14 | * This class creates a custom UIViewController transition animation
15 | * using a Lottie animation to transition between two view controllers
16 | * The transition can use custom defined layers in After Effects for to/from
17 | *
18 | * When referencing After Effects layers the animator masks or transforms the to/from viewController
19 | * with the referenced layer.
20 | *
21 | */
22 |
23 | @interface LOTAnimationTransitionController : NSObject
24 |
25 | /**
26 | The initializer to create a new transition animation.
27 |
28 | @param animation The name of the Lottie Animation to load for the transition
29 |
30 | @param fromLayer The name of the custom layer to mask the fromVC screenshot with.
31 | If no layer is specified then the screenshot is added behind the Lottie Animation
32 |
33 | @param toLayer The name of the custom layer to mask the toVC screenshot with.
34 | If no layer is specified then the screenshot is added behind the Lottie Animation
35 | and a fade transition is performed along with the Lottie animation.
36 |
37 | @param applyAnimationTransform A boolean that determines if the custom layer should
38 | have the transform animation from the After Effects layer applied to it. If NO the
39 | layer will be masked by the After Effects Layer
40 |
41 | */
42 | - (nonnull instancetype)initWithAnimationNamed:(nonnull NSString *)animation
43 | fromLayerNamed:(nullable NSString *)fromLayer
44 | toLayerNamed:(nullable NSString *)toLayer
45 | applyAnimationTransform:(BOOL)applyAnimationTransform;
46 |
47 | /**
48 | The initializer to create a new transition animation.
49 |
50 | @param animation The name of the Lottie Animation to load for the transition
51 |
52 | @param fromLayer The name of the custom layer to mask the fromVC screenshot with.
53 | If no layer is specified then the screenshot is added behind the Lottie Animation
54 |
55 | @param toLayer The name of the custom layer to mask the toVC screenshot with.
56 | If no layer is specified then the screenshot is added behind the Lottie Animation
57 | and a fade transition is performed along with the Lottie animation.
58 |
59 | @param applyAnimationTransform A boolean that determines if the custom layer should
60 | have the transform animation from the After Effects layer applied to it. If NO the
61 | layer will be masked by the After Effects Layer
62 |
63 | @param bundle custom bundle to load animation and images, if no bundle is specified will load
64 | from mainBundle
65 | */
66 | - (instancetype _Nonnull)initWithAnimationNamed:(NSString *_Nonnull)animation
67 | fromLayerNamed:(NSString *_Nullable)fromLayer
68 | toLayerNamed:(NSString *_Nullable)toLayer
69 | applyAnimationTransform:(BOOL)applyAnimationTransform
70 | inBundle:(NSBundle *_Nonnull)bundle;
71 |
72 | @end
73 |
74 |
--------------------------------------------------------------------------------
/XAnimation/Classes/RenderSystem/ManipulatorNodes/LOTTrimPathNode.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTTrimPathNode.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/21/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTTrimPathNode.h"
10 | #import "LOTNumberInterpolator.h"
11 | #import "LOTPathAnimator.h"
12 | #import "LOTCircleAnimator.h"
13 | #import "LOTRoundedRectAnimator.h"
14 | #import "LOTRenderGroup.h"
15 |
16 | @implementation LOTTrimPathNode {
17 | LOTNumberInterpolator *_startInterpolator;
18 | LOTNumberInterpolator *_endInterpolator;
19 | LOTNumberInterpolator *_offsetInterpolator;
20 |
21 | CGFloat _startT;
22 | CGFloat _endT;
23 | CGFloat _offsetT;
24 | }
25 |
26 | - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
27 | trimPath:(LOTShapeTrimPath *_Nonnull)trimPath {
28 | self = [super initWithInputNode:inputNode keyName:trimPath.keyname];
29 | if (self) {
30 | inputNode.pathShouldCacheLengths = YES;
31 | _startInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:trimPath.start.keyframes];
32 | _endInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:trimPath.end.keyframes];
33 | _offsetInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:trimPath.offset.keyframes];
34 | }
35 | return self;
36 | }
37 |
38 | - (NSDictionary *)valueInterpolators {
39 | return @{@"Start" : _startInterpolator,
40 | @"End" : _endInterpolator,
41 | @"Offset" : _offsetInterpolator};
42 | }
43 |
44 | - (BOOL)needsUpdateForFrame:(NSNumber *)frame {
45 | return ([_startInterpolator hasUpdateForFrame:frame] ||
46 | [_endInterpolator hasUpdateForFrame:frame] ||
47 | [_offsetInterpolator hasUpdateForFrame:frame]);
48 | }
49 |
50 | - (BOOL)updateWithFrame:(NSNumber *)frame
51 | withModifierBlock:(void (^ _Nullable)(LOTAnimatorNode * _Nonnull))modifier
52 | forceLocalUpdate:(BOOL)forceUpdate {
53 | BOOL localUpdate = [self needsUpdateForFrame:frame];
54 | [self forceSetCurrentFrame:frame];
55 | if (localUpdate) {
56 | [self performLocalUpdate];
57 | }
58 | if (self.inputNode == nil) {
59 | return localUpdate;
60 | }
61 |
62 | BOOL inputUpdated = [self.inputNode updateWithFrame:frame withModifierBlock:^(LOTAnimatorNode * _Nonnull inputNode) {
63 | if ([inputNode isKindOfClass:[LOTPathAnimator class]] ||
64 | [inputNode isKindOfClass:[LOTCircleAnimator class]] ||
65 | [inputNode isKindOfClass:[LOTRoundedRectAnimator class]]) {
66 | [inputNode.localPath trimPathFromT:self->_startT toT:self->_endT offset:self->_offsetT];
67 | }
68 | if (modifier) {
69 | modifier(inputNode);
70 | }
71 |
72 | } forceLocalUpdate:(localUpdate || forceUpdate)];
73 |
74 | return inputUpdated;
75 | }
76 |
77 | - (void)performLocalUpdate {
78 | _startT = [_startInterpolator floatValueForFrame:self.currentFrame] / 100;
79 | _endT = [_endInterpolator floatValueForFrame:self.currentFrame] / 100;
80 | _offsetT = [_offsetInterpolator floatValueForFrame:self.currentFrame] / 360;
81 | }
82 |
83 | - (void)rebuildOutputs {
84 | // Skip this step.
85 | }
86 |
87 | - (LOTBezierPath *)localPath {
88 | return self.inputNode.localPath;
89 | }
90 |
91 | /// Forwards its input node's output path forwards downstream
92 | - (LOTBezierPath *)outputPath {
93 | return self.inputNode.outputPath;
94 | }
95 |
96 | @end
97 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Private/LOTBlockCallback.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTBlockCallback.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 12/15/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTBlockCallback.h"
10 |
11 | @implementation LOTColorBlockCallback
12 |
13 | + (instancetype)withBlock:(LOTColorValueCallbackBlock)block {
14 | LOTColorBlockCallback *colorCallback = [[self alloc] init];
15 | colorCallback.callback = block;
16 | return colorCallback;
17 | }
18 |
19 | - (CGColorRef)colorForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startColor:(CGColorRef)startColor endColor:(CGColorRef)endColor currentColor:(CGColorRef)interpolatedColor {
20 | return self.callback(currentFrame, startKeyframe, endKeyframe, interpolatedProgress, startColor, endColor, interpolatedColor);
21 | }
22 |
23 | @end
24 |
25 | @implementation LOTNumberBlockCallback
26 |
27 | + (instancetype)withBlock:(LOTNumberValueCallbackBlock)block {
28 | LOTNumberBlockCallback *numberCallback = [[self alloc] init];
29 | numberCallback.callback = block;
30 | return numberCallback;
31 | }
32 |
33 | - (CGFloat)floatValueForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startValue:(CGFloat)startValue endValue:(CGFloat)endValue currentValue:(CGFloat)interpolatedValue {
34 | return self.callback(currentFrame, startKeyframe, endKeyframe, interpolatedProgress, startValue, endValue, interpolatedValue);
35 | }
36 |
37 | @end
38 |
39 | @implementation LOTPointBlockCallback
40 |
41 | + (instancetype)withBlock:(LOTPointValueCallbackBlock)block {
42 | LOTPointBlockCallback *callback = [[self alloc] init];
43 | callback.callback = block;
44 | return callback;
45 | }
46 |
47 | - (CGPoint)pointForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint currentPoint:(CGPoint)interpolatedPoint {
48 | return self.callback(currentFrame, startKeyframe, endKeyframe, interpolatedProgress, startPoint, endPoint, interpolatedPoint);
49 | }
50 |
51 | @end
52 |
53 | @implementation LOTSizeBlockCallback
54 |
55 | + (instancetype)withBlock:(LOTSizeValueCallbackBlock)block {
56 | LOTSizeBlockCallback *callback = [[self alloc] init];
57 | callback.callback = block;
58 | return callback;
59 | }
60 |
61 | - (CGSize)sizeForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress startSize:(CGSize)startSize endSize:(CGSize)endSize currentSize:(CGSize)interpolatedSize {
62 | return self.callback(currentFrame, startKeyframe, endKeyframe, interpolatedProgress, startSize, endSize, interpolatedSize);
63 | }
64 |
65 | @end
66 |
67 | @implementation LOTPathBlockCallback
68 |
69 | + (instancetype)withBlock:(LOTPathValueCallbackBlock)block {
70 | LOTPathBlockCallback *callback = [[self alloc] init];
71 | callback.callback = block;
72 | return callback;
73 | }
74 |
75 | - (CGPathRef)pathForFrame:(CGFloat)currentFrame startKeyframe:(CGFloat)startKeyframe endKeyframe:(CGFloat)endKeyframe interpolatedProgress:(CGFloat)interpolatedProgress {
76 | return self.callback(currentFrame, startKeyframe, endKeyframe, interpolatedProgress);
77 | }
78 |
79 | @end
80 |
81 |
--------------------------------------------------------------------------------
/XAnimation/Classes/AnimatableLayers/LOTMaskContainer.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTMaskContainer.m
3 | // Lottie
4 | //
5 | // Created by brandon_withrow on 7/19/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import "LOTMaskContainer.h"
10 | #import "LOTPathInterpolator.h"
11 | #import "LOTNumberInterpolator.h"
12 |
13 | @interface LOTMaskNodeLayer : CAShapeLayer
14 |
15 | @property (nonatomic, readonly) LOTMask *maskNode;
16 |
17 | - (instancetype)initWithMask:(LOTMask *)maskNode;
18 | - (BOOL)hasUpdateForFrame:(NSNumber *)frame;
19 |
20 | @end
21 |
22 | @implementation LOTMaskNodeLayer {
23 | LOTPathInterpolator *_pathInterpolator;
24 | LOTNumberInterpolator *_opacityInterpolator;
25 | LOTNumberInterpolator *_expansionInterpolator;
26 | }
27 |
28 | - (instancetype)initWithMask:(LOTMask *)maskNode {
29 | self = [super init];
30 | if (self) {
31 | _pathInterpolator = [[LOTPathInterpolator alloc] initWithKeyframes:maskNode.maskPath.keyframes];
32 | _opacityInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:maskNode.opacity.keyframes];
33 | _expansionInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:maskNode.expansion.keyframes];
34 | _maskNode = maskNode;
35 | self.fillColor = [UIColor blueColor].CGColor;
36 | }
37 | return self;
38 | }
39 |
40 | - (void)updateForFrame:(NSNumber *)frame withViewBounds:(CGRect)viewBounds {
41 | if ([self hasUpdateForFrame:frame]) {
42 | LOTBezierPath *path = [_pathInterpolator pathForFrame:frame cacheLengths:NO];
43 |
44 | if (self.maskNode.maskMode == LOTMaskModeSubtract) {
45 | CGMutablePathRef pathRef = CGPathCreateMutable();
46 | CGPathAddRect(pathRef, NULL, viewBounds);
47 | CGPathAddPath(pathRef, NULL, path.CGPath);
48 | self.path = pathRef;
49 | self.fillRule = @"even-odd";
50 | CGPathRelease(pathRef);
51 | } else {
52 | self.path = path.CGPath;
53 | }
54 |
55 | self.opacity = [_opacityInterpolator floatValueForFrame:frame];
56 | }
57 | }
58 |
59 | - (BOOL)hasUpdateForFrame:(NSNumber *)frame {
60 | return ([_pathInterpolator hasUpdateForFrame:frame] ||
61 | [_opacityInterpolator hasUpdateForFrame:frame]);
62 | }
63 |
64 | @end
65 |
66 | @implementation LOTMaskContainer {
67 | NSArray *_masks;
68 | }
69 |
70 | - (instancetype)initWithMasks:(NSArray *)masks {
71 | self = [super init];
72 | if (self) {
73 | NSMutableArray *maskNodes = [NSMutableArray array];
74 | CALayer *containerLayer = [CALayer layer];
75 |
76 | for (LOTMask *mask in masks) {
77 | LOTMaskNodeLayer *node = [[LOTMaskNodeLayer alloc] initWithMask:mask];
78 | [maskNodes addObject:node];
79 | if (mask.maskMode == LOTMaskModeAdd ||
80 | mask == masks.firstObject) {
81 | [containerLayer addSublayer:node];
82 | } else {
83 | containerLayer.mask = node;
84 | CALayer *newContainer = [CALayer layer];
85 | [newContainer addSublayer:containerLayer];
86 | containerLayer = newContainer;
87 | }
88 | }
89 | [self addSublayer:containerLayer];
90 | _masks = maskNodes;
91 |
92 | }
93 | return self;
94 | }
95 |
96 | - (void)setCurrentFrame:(NSNumber *)currentFrame {
97 | if (_currentFrame == currentFrame) {
98 | return;
99 | }
100 | _currentFrame = currentFrame;
101 |
102 | for (LOTMaskNodeLayer *nodeLayer in _masks) {
103 | [nodeLayer updateForFrame:currentFrame withViewBounds:self.bounds];
104 | }
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/Example/XAnimation/classes/BindLottieDemo/TestBind2.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestBind2.m
3 | // XAnimation_Example
4 | //
5 | // Created by xiyuan wang on 2022/3/25.
6 | // Copyright © 2022 wangxiyuan. All rights reserved.
7 | //
8 |
9 | #import "TestBind2.h"
10 | #import
11 | #import
12 | #import
13 |
14 | @interface TestBind2 ()
15 |
16 | @property (nonatomic, strong) LOTAnimationView *origin;
17 | @property (nonatomic, strong) UIImageView *paiziV;
18 |
19 | @property (nonatomic, strong) NSMutableArray *bindViews;
20 |
21 | @property (nonatomic, strong) UIView *sepLine;
22 |
23 | @end
24 |
25 | @implementation TestBind2
26 |
27 | - (void)viewDidLoad {
28 | [super viewDidLoad];
29 | // Do any additional setup after loading the view.
30 | self.view.backgroundColor = [UIColor whiteColor];
31 | self.bindViews = [NSMutableArray new];
32 |
33 | UILabel *lb= [[UILabel alloc] initWithFrame:CGRectMake(20, 120, 0, 0)];
34 | lb.text = @"原始 lottie:";
35 | lb.textColor = [UIColor blackColor];
36 | [lb sizeToFit];
37 | [self.view addSubview:lb];
38 |
39 |
40 | LOTAnimationView *view = [LOTAnimationView animationNamed:@"fengche_paizi"];
41 | // LOTAnimationView *view = [[LOTAnimationView alloc] initWithContentsOfURL:[NSURL URLWithString:@"https://storage.360buyimg.com/xview-beta/2022-3-23/749aa980-3ab9-4ddc-86aa-0049c52f9bc1.json"]];
42 | view.frame = CGRectMake(lb.frame.origin.x + lb.frame.size.width + 10, 100, 153, 127);
43 | view.center = CGPointMake(view.center.x, lb.center.y);
44 | // view.loopAnimationCount = 0;
45 | [self.view addSubview:view];
46 | self.origin = view;
47 |
48 | UIView *sepLine = [[UIView alloc] initWithFrame:CGRectMake(0, _origin.frame.origin.y +_origin.frame.size.height + 10, self.view.frame.size.width, 1)];
49 | sepLine.backgroundColor = [UIColor grayColor];
50 | [self.view addSubview:sepLine];
51 | self.sepLine = sepLine;
52 |
53 | [self setupBindViews];
54 |
55 | }
56 |
57 | - (void)setupBindViews{
58 |
59 | UILabel *title= [[UILabel alloc] initWithFrame:CGRectMake(20, self.sepLine.frame.origin.y + self.sepLine.frame.size.height + 30, 0, 0)];
60 | title.text = @"示例: 分别绑定到俩个视图";
61 | title.textColor = [UIColor blueColor];
62 | [title sizeToFit];
63 | [self.view addSubview:title];
64 |
65 | UILabel *lb= [[UILabel alloc] initWithFrame:CGRectMake(_paiziV.frame.origin.x, title.frame.origin.y + title.frame.size.height + 60, 0, 0)];
66 | lb.text = @"棋子动画";
67 | lb.font = [UIFont systemFontOfSize:30];
68 | lb.textColor = [UIColor redColor];
69 | [lb sizeToFit];
70 | lb.center = CGPointMake(self.view.frame.size.width / 4, lb.center.y);
71 | [lb bindLottieLayerName:@"牌子"];
72 | [self.view addSubview:lb];
73 | [self.bindViews addObject:lb];
74 |
75 | UILabel *lb1= [[UILabel alloc] initWithFrame:CGRectZero];
76 | lb1.text = @"风车动画";
77 | lb1.font = [UIFont systemFontOfSize:30];
78 | lb1.textColor = [UIColor orangeColor];
79 | [lb1 sizeToFit];
80 | lb1.center = CGPointMake(self.view.frame.size.width / 4 * 3, lb.center.y);
81 | [lb1 bindLottieLayerName:@"风车"];
82 | [self.view addSubview:lb1];
83 | [self.bindViews addObject:lb1];
84 | }
85 |
86 | // [bindView bindLottieWithContentsOfURL:[NSURL URLWithString:@"https://storage.360buyimg.com/xview-beta/2022-3-23/749aa980-3ab9-4ddc-86aa-0049c52f9bc1.json"]];
87 |
88 | - (void)viewDidAppear:(BOOL)animated{
89 | // @"预合成 1" : @"img_0.png"
90 | [super viewDidAppear:animated];
91 | [self.view bindLottieWithAnimationNamed:@"fengche_paizi"];
92 | [[self.view currentBindController] play];
93 | [self.origin play];
94 | }
95 |
96 | @end
97 |
--------------------------------------------------------------------------------
/XAnimation/Classes/XAimationExtends/XABindLOTAnimationViewLayer.m:
--------------------------------------------------------------------------------
1 | //
2 | // XABindLOTAnimationViewLayer.m
3 | //
4 | //
5 | // Created by xiyuan wang on 2022/3/20.
6 | //
7 |
8 | #import "XABindLOTAnimationViewLayer.h"
9 | #import "XABindLOTAnimationView.h"
10 | #import "LOTCompositionContainer.h"
11 |
12 | @interface XABindLOTAnimationViewLayer ()
13 | @property (nonatomic, weak) UIWindow *layerWindow;
14 |
15 | @end
16 |
17 |
18 | @implementation XABindLOTAnimationViewLayer
19 |
20 | - (id)actionForKey:(NSString *)event {
21 | XABindLOTAnimationView *animV = self.delegate;
22 | if ([animV isKindOfClass:[XABindLOTAnimationView class]] ) {
23 | if ([event isEqualToString:kCAOnOrderIn]) {
24 | if (self.superlayer == nil) {
25 | [self _callCompletionIfNecessary:NO];
26 | } else {
27 | UIWindow *window = nil;
28 | CALayer *windowLayer = self.superlayer;
29 | while (windowLayer) {
30 | if ([windowLayer.delegate isKindOfClass:[UIWindow class]] ) {
31 | window = windowLayer.delegate;
32 | break;
33 | }
34 | windowLayer = windowLayer.superlayer;
35 | }
36 | if (
37 | (window && !_layerWindow) ||
38 | (!window && _layerWindow)
39 | ) {
40 | [self _handleWindowChanges:window != nil];
41 | if (window){
42 | LOTCompositionContainer *compContainer = [animV valueForKeyPath:@"compContainer"];
43 | if ([compContainer isKindOfClass:[LOTCompositionContainer class]] ) {
44 | compContainer.rasterizationScale = window.screen.scale;
45 | }
46 | }
47 | }
48 | self.layerWindow = window;
49 | }
50 | } else if ([event isEqualToString:kCAOnOrderOut]) {
51 | if (self.superlayer == nil) {
52 | [self _callCompletionIfNecessary:NO];
53 | }
54 | }
55 | }
56 |
57 | return [super actionForKey:event];
58 | }
59 |
60 | - (void)_handleWindowChanges:(BOOL)param{
61 | XABindLOTAnimationView *animV = self.delegate;
62 | if (![animV isKindOfClass:[XABindLOTAnimationView class]] ) return;
63 | if ([animV respondsToSelector:@selector(_handleWindowChanges:)] ) {
64 | Class class = NSClassFromString(@"LOTAnimationView");
65 | SEL sel = NSSelectorFromString(@"_handleWindowChanges:");
66 | NSMethodSignature *signature = [class instanceMethodSignatureForSelector:sel];
67 |
68 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
69 | [invocation setArgument:¶m atIndex:2];
70 | invocation.selector = sel;
71 | invocation.target = animV;
72 | [invocation invoke];
73 | }
74 | }
75 |
76 | - (void)_callCompletionIfNecessary:(BOOL)param{
77 | XABindLOTAnimationView *animV = self.delegate;
78 | if (![animV isKindOfClass:[XABindLOTAnimationView class]] ) return;
79 | if ([animV respondsToSelector:@selector(_callCompletionIfNecessary:)] ) {
80 | Class class = NSClassFromString(@"LOTAnimationView");
81 | SEL sel = NSSelectorFromString(@"_callCompletionIfNecessary:");
82 | NSMethodSignature *signature = [class instanceMethodSignatureForSelector:sel];
83 |
84 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
85 | [invocation setArgument:¶m atIndex:2];
86 | invocation.selector = sel;
87 | invocation.target = animV;
88 | [invocation invoke];
89 | }
90 |
91 | }
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/XAnimation/Classes/PublicHeaders/LOTKeypath.h:
--------------------------------------------------------------------------------
1 | //
2 | // LOTKeypath.h
3 | // Lottie_iOS
4 | //
5 | // Created by brandon_withrow on 12/13/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | extern NSString * _Nonnull const kLOTKeypathEnd;
12 |
13 | /*!
14 | @brief LOTKeypath is an object that describes a keypath search for nodes in the animation JSON. LOTKeypath matches views inside of LOTAnimationView to their After Effects counterparts.
15 |
16 | @discussion
17 | LOTKeypath is used with LOTAnimationView to set animation properties dynamically at runtime, to add or mask subviews, converting geometry, and numerous other functions.
18 |
19 | LOTKeypath can describe a specific object, or can use wildcards for fuzzy matching of objects. Acceptable wildcards are either "*" (star) or "**" (double star). Single star will search a single depth for the next object, double star will search any depth.
20 |
21 | Read More at http://airbnb.io/lottie/ios/dynamic.html
22 |
23 | EG:
24 | @"Layer.Shape Group.Stroke 1.Color"
25 | Represents a specific color node on a specific stroke.
26 |
27 | @"**.Stroke 1.Color"
28 | Represents the color node for every "Stroke 1" in the animation scene.
29 |
30 | */
31 |
32 | @interface LOTKeypath : NSObject
33 |
34 | /*!
35 | @brief Creates a LOTKeypath from a dot separated string, can use wildcards @"*" and fuzzy depth wild cards @"**".
36 |
37 | @discussion LOTKeypath is an object that describes a keypath search for nodes in the animation JSON.
38 |
39 | LOTKeypath is used with LOTAnimationView to set animation properties dynamically at runtime, to add or mask subviews, converting geometry, and numerous other functions.
40 |
41 | LOTKeypath can describe a specific object, or can use wildcards for fuzzy matching of objects. Acceptable wildcards are either "*" (star) or "**" (double star). Single star will search a single depth for the next object, double star will search any depth.
42 |
43 | @param keypath A dot separated string describing a keypath from the JSON animation. EG @"Layer.Shape Group.Stroke 1.Color"
44 |
45 | @return A new LOTKeypath
46 | */
47 |
48 | + (nonnull LOTKeypath *)keypathWithString:(nonnull NSString *)keypath;
49 |
50 | /*!
51 | @brief Creates a LOTKeypath from a list of keypath string objects, can use wildcards @"*" and fuzzy depth wild cards @"**".
52 |
53 | @discussion LOTKeypath is an object that describes a keypath search for nodes in the animation JSON.
54 |
55 | LOTKeypath is used with LOTAnimationView to set animation properties dynamically at runtime, to add or mask subviews, converting geometry, and numerous other functions.
56 |
57 | LOTKeypath can describe a specific object, or can use wildcards for fuzzy matching of objects. Acceptable wildcards are either "*" (star) or "**" (double star). Single star will search a single depth for the next object, double star will search any depth.
58 |
59 | @param firstKey A nil terminated list of strings describing a keypath. EG @"Layer", @"Shape Group", @"Stroke 1", @"Color", nil
60 |
61 | @return A new LOTKeypath
62 | */
63 |
64 | + (nonnull LOTKeypath *)keypathWithKeys:(nonnull NSString *)firstKey, ...
65 | NS_REQUIRES_NIL_TERMINATION;
66 |
67 | @property (nonatomic, readonly, nonnull) NSString *absoluteKeypath;
68 | @property (nonatomic, readonly, nonnull) NSString *currentKey;
69 | @property (nonatomic, readonly, nonnull) NSString *currentKeyPath;
70 |
71 | @property (nonatomic, readonly, nonnull) NSDictionary *searchResults;
72 |
73 | @property (nonatomic, readonly) BOOL hasFuzzyWildcard;
74 | @property (nonatomic, readonly) BOOL hasWildcard;
75 | @property (nonatomic, readonly) BOOL endOfKeypath;
76 |
77 | - (BOOL)pushKey:(nonnull NSString *)key;
78 | - (void)popKey;
79 | - (void)popToRootKey;
80 |
81 | - (void)addSearchResultForCurrentPath:(id _Nonnull)result;
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/XAnimation/Classes/Models/LOTShapeGroup.m:
--------------------------------------------------------------------------------
1 | //
2 | // LOTShape.m
3 | // LottieAnimator
4 | //
5 | // Created by Brandon Withrow on 12/14/15.
6 | // Copyright © 2015 Brandon Withrow. All rights reserved.
7 | //
8 |
9 | #import "LOTShapeGroup.h"
10 | #import "LOTShapeFill.h"
11 | #import "LOTShapePath.h"
12 | #import "LOTShapeCircle.h"
13 | #import "LOTShapeStroke.h"
14 | #import "LOTShapeTransform.h"
15 | #import "LOTShapeRectangle.h"
16 | #import "LOTShapeTrimPath.h"
17 | #import "LOTShapeGradientFill.h"
18 | #import "LOTShapeStar.h"
19 | #import "LOTShapeRepeater.h"
20 |
21 | @implementation LOTShapeGroup
22 |
23 | - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
24 | self = [super init];
25 | if (self) {
26 | [self _mapFromJSON:jsonDictionary];
27 | }
28 | return self;
29 | }
30 |
31 | - (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
32 |
33 | if (jsonDictionary[@"nm"] ) {
34 | _keyname = [jsonDictionary[@"nm"] copy];
35 | }
36 |
37 | NSArray *itemsJSON = jsonDictionary[@"it"];
38 | NSMutableArray *items = [NSMutableArray array];
39 | for (NSDictionary *itemJSON in itemsJSON) {
40 | id newItem = [LOTShapeGroup shapeItemWithJSON:itemJSON];
41 | if (newItem) {
42 | [items addObject:newItem];
43 | }
44 | }
45 | _items = items;
46 | }
47 |
48 | + (id)shapeItemWithJSON:(NSDictionary *)itemJSON {
49 | NSString *type = itemJSON[@"ty"];
50 | if ([type isEqualToString:@"gr"]) {
51 | LOTShapeGroup *group = [[LOTShapeGroup alloc] initWithJSON:itemJSON];
52 | return group;
53 | } else if ([type isEqualToString:@"st"]) {
54 | LOTShapeStroke *stroke = [[LOTShapeStroke alloc] initWithJSON:itemJSON];
55 | return stroke;
56 | } else if ([type isEqualToString:@"fl"]) {
57 | LOTShapeFill *fill = [[LOTShapeFill alloc] initWithJSON:itemJSON];
58 | return fill;
59 | } else if ([type isEqualToString:@"tr"]) {
60 | LOTShapeTransform *transform = [[LOTShapeTransform alloc] initWithJSON:itemJSON];
61 | return transform;
62 | } else if ([type isEqualToString:@"sh"]) {
63 | LOTShapePath *path = [[LOTShapePath alloc] initWithJSON:itemJSON];
64 | return path;
65 | } else if ([type isEqualToString:@"el"]) {
66 | LOTShapeCircle *circle = [[LOTShapeCircle alloc] initWithJSON:itemJSON];
67 | return circle;
68 | } else if ([type isEqualToString:@"rc"]) {
69 | LOTShapeRectangle *rectangle = [[LOTShapeRectangle alloc] initWithJSON:itemJSON];
70 | return rectangle;
71 | } else if ([type isEqualToString:@"tm"]) {
72 | LOTShapeTrimPath *trim = [[LOTShapeTrimPath alloc] initWithJSON:itemJSON];
73 | return trim;
74 | } else if ([type isEqualToString:@"gs"]) {
75 | NSLog(@"%s: Warning: gradient strokes are not supported", __PRETTY_FUNCTION__);
76 | } else if ([type isEqualToString:@"gf"]) {
77 | LOTShapeGradientFill *gradientFill = [[LOTShapeGradientFill alloc] initWithJSON:itemJSON];
78 | return gradientFill;
79 | } else if ([type isEqualToString:@"sr"]) {
80 | LOTShapeStar *star = [[LOTShapeStar alloc] initWithJSON:itemJSON];
81 | return star;
82 | } else if ([type isEqualToString:@"mm"]) {
83 | NSString *name = itemJSON[@"nm"];
84 | NSLog(@"%s: Warning: merge shape is not supported. name: %@", __PRETTY_FUNCTION__, name);
85 | } else if ([type isEqualToString:@"rp"]) {
86 | LOTShapeRepeater *repeater = [[LOTShapeRepeater alloc] initWithJSON:itemJSON];
87 | return repeater;
88 | } else {
89 | NSString *name = itemJSON[@"nm"];
90 | NSLog(@"%s: Unsupported shape: %@ name: %@", __PRETTY_FUNCTION__, type, name);
91 | }
92 |
93 | return nil;
94 | }
95 |
96 | - (NSString *)description {
97 | NSMutableString *text = [[super description] mutableCopy];
98 | [text appendFormat:@" items: %@", self.items];
99 | return text;
100 | }
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/XAnimation/Classes/MacCompatibility/UIColor.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor.m
3 | // Lottie
4 | //
5 | // Created by Oleksii Pavlovskyi on 2/2/17.
6 | // Copyright © 2017 Airbnb. All rights reserved.
7 | //
8 |
9 | #include
10 |
11 | #if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
12 | #import "UIColor.h"
13 | #import
14 |
15 | #define StaticColor(staticColor) \
16 | static UIColor *color = nil; \
17 | static dispatch_once_t onceToken; \
18 | dispatch_once(&onceToken, ^{ \
19 | color = NSColor.staticColor.UIColor; \
20 | }); \
21 | return color; \
22 |
23 | @interface UIColor ()
24 |
25 | @property (nonatomic, strong) NSColor *color;
26 |
27 | - (instancetype)initWithNSColor:(NSColor *)color;
28 |
29 | @end
30 |
31 | @interface NSColor (UIColor)
32 |
33 | @property (nonatomic, readonly) UIColor *UIColor;
34 |
35 | @end
36 |
37 | @implementation UIColor
38 |
39 | - (instancetype)initWithNSColor:(NSColor *)color {
40 | self = [super init];
41 | if (self) {
42 | self.color = color;
43 | }
44 | return self;
45 | }
46 |
47 | + (UIColor *)colorWithNSColor:(NSColor *)color {
48 | return [[self alloc] initWithNSColor:color];
49 | }
50 |
51 | + (UIColor *)colorWithWhite:(CGFloat)white alpha:(CGFloat)alpha {
52 | return [[NSColor colorWithWhite:white alpha:alpha] UIColor];
53 | }
54 |
55 | + (UIColor *)colorWithHue:(CGFloat)hue
56 | saturation:(CGFloat)saturation
57 | brightness:(CGFloat)brightness
58 | alpha:(CGFloat)alpha {
59 | return [[NSColor colorWithHue:hue
60 | saturation:saturation
61 | brightness:brightness
62 | alpha:alpha] UIColor];
63 | }
64 |
65 | + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha {
66 | return [[NSColor colorWithRed:red
67 | green:green
68 | blue:blue
69 | alpha:alpha] UIColor];
70 | }
71 |
72 | + (UIColor *)colorWithCGColor:(CGColorRef)cgColor {
73 | return [[NSColor colorWithCGColor:cgColor] UIColor];
74 | }
75 |
76 | + (UIColor *)blackColor {
77 | StaticColor(blackColor)
78 | }
79 |
80 | + (UIColor *)darkGrayColor {
81 | StaticColor(darkGrayColor)
82 | }
83 |
84 | + (UIColor *)lightGrayColor {
85 | StaticColor(lightGrayColor)
86 | }
87 |
88 | + (UIColor *)whiteColor {
89 | StaticColor(whiteColor)
90 | }
91 |
92 | + (UIColor *)grayColor {
93 | StaticColor(grayColor)
94 | }
95 |
96 | + (UIColor *)redColor {
97 | StaticColor(redColor)
98 | }
99 |
100 | + (UIColor *)greenColor {
101 | StaticColor(greenColor)
102 | }
103 |
104 | + (UIColor *)blueColor {
105 | StaticColor(blueColor)
106 | }
107 |
108 | + (UIColor *)cyanColor {
109 | StaticColor(cyanColor)
110 | }
111 |
112 | + (UIColor *)yellowColor {
113 | StaticColor(yellowColor)
114 | }
115 |
116 | + (UIColor *)magentaColor {
117 | StaticColor(magentaColor)
118 | }
119 |
120 | + (UIColor *)orangeColor {
121 | StaticColor(orangeColor)
122 | }
123 |
124 | + (UIColor *)purpleColor {
125 | StaticColor(purpleColor)
126 | }
127 |
128 | + (UIColor *)brownColor {
129 | StaticColor(brownColor)
130 | }
131 |
132 | + (UIColor *)clearColor {
133 | StaticColor(clearColor)
134 | }
135 |
136 | - (CGColorRef)CGColor {
137 | return self.color.CGColor;
138 | }
139 |
140 | - (UIColor *)colorWithAlphaComponent:(CGFloat)alpha {
141 | return [self.color colorWithAlphaComponent:alpha].UIColor;
142 | }
143 |
144 | - (id)copyWithZone:(NSZone *)zone {
145 | return [[self.color copyWithZone:zone] UIColor];
146 | }
147 |
148 | @end
149 |
150 | @implementation NSColor (UIColor)
151 |
152 | - (UIColor *)UIColor {
153 | return [UIColor colorWithNSColor:self];
154 | }
155 |
156 | @end
157 |
158 | #endif
159 |
--------------------------------------------------------------------------------