From d2d4cd40ee84a3aa0045f7cb9d8ca0a70accf5c1 Mon Sep 17 00:00:00 2001 From: Brandon Withrow Date: Tue, 26 Jul 2016 16:52:31 -0700 Subject: [PATCH] Added mask, matte, line dash, trim support --- LotteAnimator.xcodeproj/project.pbxproj | 30 ++++- .../UserInterfaceState.xcuserstate | Bin 58057 -> 66060 bytes .../xcdebugger/Breakpoints_v2.xcbkptlist | 70 ++-------- LotteAnimator/LAAnimatableLayer.m | 1 - LotteAnimator/LAAnimatableRectValue.h | 28 ---- LotteAnimator/LAAnimatableRectValue.m | 22 ---- LotteAnimator/LACompView.m | 13 +- LotteAnimator/LAEllipseShapeLayer.h | 20 +++ LotteAnimator/LAEllipseShapeLayer.m | 121 ++++++++++++++++++ LotteAnimator/LAGroupLayerView.m | 16 +++ LotteAnimator/LALayer.h | 15 ++- LotteAnimator/LALayer.m | 9 +- LotteAnimator/LALayerView.m | 34 ++++- LotteAnimator/LAMaskLayer.m | 28 ++++ LotteAnimator/LAModels.h | 2 +- LotteAnimator/LARectShapeLayer.h | 6 +- LotteAnimator/LARectShapeLayer.m | 40 +++--- LotteAnimator/LAShapeCircle.h | 3 + LotteAnimator/LAShapeCircle.m | 9 ++ LotteAnimator/LAShapeGroup.m | 4 + LotteAnimator/LAShapeLayerView.h | 3 +- LotteAnimator/LAShapeLayerView.m | 63 ++++++--- LotteAnimator/LAShapeStroke.h | 1 + LotteAnimator/LAShapeStroke.m | 14 ++ LotteAnimator/LAShapeTrimPath.h | 19 +++ LotteAnimator/LAShapeTrimPath.m | 35 +++++ LotteAnimator/UIColor+Expanded.m | 3 +- LotteAnimator/circleTest.json | 1 + LotteAnimator/masksAndSolids.json | 1 + LotteAnimator/masktest.json | 1 + 30 files changed, 444 insertions(+), 168 deletions(-) delete mode 100644 LotteAnimator/LAAnimatableRectValue.h delete mode 100644 LotteAnimator/LAAnimatableRectValue.m create mode 100644 LotteAnimator/LAEllipseShapeLayer.h create mode 100644 LotteAnimator/LAEllipseShapeLayer.m create mode 100644 LotteAnimator/LAShapeTrimPath.h create mode 100644 LotteAnimator/LAShapeTrimPath.m create mode 100644 LotteAnimator/circleTest.json create mode 100644 LotteAnimator/masksAndSolids.json create mode 100644 LotteAnimator/masktest.json diff --git a/LotteAnimator.xcodeproj/project.pbxproj b/LotteAnimator.xcodeproj/project.pbxproj index 9ec0539dd7..9d8307be2a 100644 --- a/LotteAnimator.xcodeproj/project.pbxproj +++ b/LotteAnimator.xcodeproj/project.pbxproj @@ -35,7 +35,6 @@ 620A565F1D1C81750030EBFB /* LAAnimatablePointValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620A565E1D1C81750030EBFB /* LAAnimatablePointValue.m */; }; 620A56621D1C81850030EBFB /* LAAnimatableNumberValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620A56611D1C81850030EBFB /* LAAnimatableNumberValue.m */; }; 620A56651D1C81930030EBFB /* LAAnimatableShapeValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620A56641D1C81930030EBFB /* LAAnimatableShapeValue.m */; }; - 620CD7CD1D3415F000055AD1 /* LAAnimatableRectValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620CD7CC1D3415F000055AD1 /* LAAnimatableRectValue.m */; }; 620CD7D01D343A2500055AD1 /* LAAnimatableScaleValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620CD7CF1D343A2500055AD1 /* LAAnimatableScaleValue.m */; }; 620CD7E51D38180800055AD1 /* LAGroupLayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 620CD7E41D38180800055AD1 /* LAGroupLayerView.m */; }; 62FE408D1D3EC81C00CA389D /* CAAnimationGroup+LAAnimatableGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FE408C1D3EC81C00CA389D /* CAAnimationGroup+LAAnimatableGroup.m */; }; @@ -90,6 +89,11 @@ 62FE41C21D46886600CA389D /* goftldalt.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41BE1D46886600CA389D /* goftldalt.json */; }; 62FE41C31D46886600CA389D /* govtid.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41BF1D46886600CA389D /* govtid.json */; }; 62FE41C41D46886600CA389D /* selfie.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41C01D46886600CA389D /* selfie.json */; }; + 62FE41C61D46D5C900CA389D /* masktest.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41C51D46D5C900CA389D /* masktest.json */; }; + 62FE41C81D47D92E00CA389D /* masksAndSolids.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41C71D47D92E00CA389D /* masksAndSolids.json */; }; + 62FE41CB1D48004A00CA389D /* LAEllipseShapeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FE41CA1D48004A00CA389D /* LAEllipseShapeLayer.m */; }; + 62FE41CD1D4804E400CA389D /* circleTest.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41CC1D4804E400CA389D /* circleTest.json */; }; + 62FE41D31D4829E100CA389D /* LAShapeTrimPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FE41D21D4829E100CA389D /* LAShapeTrimPath.m */; }; F5B4E946F7B28B4594824641 /* libPods-LotteAnimator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BC68632413866F85CEACB7EA /* libPods-LotteAnimator.a */; }; /* End PBXBuildFile section */ @@ -150,8 +154,6 @@ 620A56611D1C81850030EBFB /* LAAnimatableNumberValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAAnimatableNumberValue.m; sourceTree = ""; }; 620A56631D1C81930030EBFB /* LAAnimatableShapeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAAnimatableShapeValue.h; sourceTree = ""; }; 620A56641D1C81930030EBFB /* LAAnimatableShapeValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAAnimatableShapeValue.m; sourceTree = ""; }; - 620CD7CB1D3415F000055AD1 /* LAAnimatableRectValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAAnimatableRectValue.h; sourceTree = ""; }; - 620CD7CC1D3415F000055AD1 /* LAAnimatableRectValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAAnimatableRectValue.m; sourceTree = ""; }; 620CD7CE1D343A2500055AD1 /* LAAnimatableScaleValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAAnimatableScaleValue.h; sourceTree = ""; }; 620CD7CF1D343A2500055AD1 /* LAAnimatableScaleValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAAnimatableScaleValue.m; sourceTree = ""; }; 620CD7E31D38180800055AD1 /* LAGroupLayerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAGroupLayerView.h; sourceTree = ""; }; @@ -214,6 +216,13 @@ 62FE41BE1D46886600CA389D /* goftldalt.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = goftldalt.json; sourceTree = ""; }; 62FE41BF1D46886600CA389D /* govtid.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = govtid.json; sourceTree = ""; }; 62FE41C01D46886600CA389D /* selfie.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = selfie.json; sourceTree = ""; }; + 62FE41C51D46D5C900CA389D /* masktest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = masktest.json; sourceTree = ""; }; + 62FE41C71D47D92E00CA389D /* masksAndSolids.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = masksAndSolids.json; sourceTree = ""; }; + 62FE41C91D48004A00CA389D /* LAEllipseShapeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAEllipseShapeLayer.h; sourceTree = ""; }; + 62FE41CA1D48004A00CA389D /* LAEllipseShapeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAEllipseShapeLayer.m; sourceTree = ""; }; + 62FE41CC1D4804E400CA389D /* circleTest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = circleTest.json; sourceTree = ""; }; + 62FE41D11D4829E100CA389D /* LAShapeTrimPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeTrimPath.h; sourceTree = ""; }; + 62FE41D21D4829E100CA389D /* LAShapeTrimPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeTrimPath.m; sourceTree = ""; }; AEE1A33E4CE2F6024DE7793E /* Pods-LotteAnimator.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LotteAnimator.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LotteAnimator/Pods-LotteAnimator.debug.xcconfig"; sourceTree = ""; }; BC68632413866F85CEACB7EA /* libPods-LotteAnimator.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LotteAnimator.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -277,6 +286,8 @@ 486BE04D1D36F1BE00CD14A0 /* LAShapeLayerView.m */, 62FE40E61D3FFBB400CA389D /* LARectShapeLayer.h */, 62FE40E71D3FFBB400CA389D /* LARectShapeLayer.m */, + 62FE41C91D48004A00CA389D /* LAEllipseShapeLayer.h */, + 62FE41CA1D48004A00CA389D /* LAEllipseShapeLayer.m */, 4804B2FD1C1F55E600DA8AF7 /* ViewController.h */, 4804B2FE1C1F55E600DA8AF7 /* ViewController.m */, 48372A621C20A91C00AD0293 /* LAJSONExplorerViewController.h */, @@ -315,6 +326,8 @@ 48372A4E1C1F99C600AD0293 /* LAShapeGroup.m */, 48372A561C209A6C00AD0293 /* LAShapeStroke.h */, 48372A571C209A6C00AD0293 /* LAShapeStroke.m */, + 62FE41D11D4829E100CA389D /* LAShapeTrimPath.h */, + 62FE41D21D4829E100CA389D /* LAShapeTrimPath.m */, 48372A591C209A7A00AD0293 /* LAShapeFill.h */, 48372A5A1C209A7A00AD0293 /* LAShapeFill.m */, 48372A5C1C209A8900AD0293 /* LAShapeTransform.h */, @@ -345,6 +358,9 @@ 48372A651C20B04300AD0293 /* JSONExamples */ = { isa = PBXGroup; children = ( + 62FE41CC1D4804E400CA389D /* circleTest.json */, + 62FE41C71D47D92E00CA389D /* masksAndSolids.json */, + 62FE41C51D46D5C900CA389D /* masktest.json */, 62FE41BD1D46886600CA389D /* allset.json */, 62FE41BE1D46886600CA389D /* goftldalt.json */, 62FE41BF1D46886600CA389D /* govtid.json */, @@ -413,8 +429,6 @@ 62FE40E41D3FF78800CA389D /* LAAnimatableBoundsValue.m */, 620CD7CE1D343A2500055AD1 /* LAAnimatableScaleValue.h */, 620CD7CF1D343A2500055AD1 /* LAAnimatableScaleValue.m */, - 620CD7CB1D3415F000055AD1 /* LAAnimatableRectValue.h */, - 620CD7CC1D3415F000055AD1 /* LAAnimatableRectValue.m */, 62FE408B1D3EC81C00CA389D /* CAAnimationGroup+LAAnimatableGroup.h */, 62FE408C1D3EC81C00CA389D /* CAAnimationGroup+LAAnimatableGroup.m */, ); @@ -505,6 +519,7 @@ 4804B3041C1F55E600DA8AF7 /* Assets.xcassets in Resources */, 62FE40D11D3EDC7400CA389D /* 062_AnimateTransformParented.json in Resources */, 62FE40D71D3EDC7400CA389D /* 100_House_AnimateInAndOut.json in Resources */, + 62FE41CD1D4804E400CA389D /* circleTest.json in Resources */, 62FE40D41D3EDC7400CA389D /* 071_AnimatePathShape.json in Resources */, 62FE40CE1D3EDC7400CA389D /* 058_AnimateTransformPositionHoldKeyframe.json in Resources */, 62FE40CC1D3EDC7400CA389D /* 056_AnimateTransformPositionCustomEaseIn.json in Resources */, @@ -522,6 +537,7 @@ 62FE40CA1D3EDC7400CA389D /* 054_AnimateTransformPositionEaseOut.json in Resources */, 62FE40B51D3EDC7400CA389D /* 002_ShapeLayerLine_01.json in Resources */, 62FE40DD1D3FF0D900CA389D /* Heart58OnOff.json in Resources */, + 62FE41C81D47D92E00CA389D /* masksAndSolids.json in Resources */, 62FE40B81D3EDC7400CA389D /* 005_TwoShapeLayerSquaresDifferent_01.json in Resources */, 62FE40C01D3EDC7400CA389D /* 013_ShapeMasked_01.json in Resources */, 486BE04B1D36E06C00CD14A0 /* newMoovin.json in Resources */, @@ -539,6 +555,7 @@ 62FE40EA1D401C0700CA389D /* scaleTest.json in Resources */, 62FE40BE1D3EDC7400CA389D /* 011_MergePaths_01.json in Resources */, 62FE40BC1D3EDC7400CA389D /* 009_ShapeLayerRepeater_01.json in Resources */, + 62FE41C61D46D5C900CA389D /* masktest.json in Resources */, 62FE40C21D3EDC7400CA389D /* 015_DottedLine_01.json in Resources */, 62FE40CD1D3EDC7400CA389D /* 057_AnimateTransformPositionCustomEaseInout.json in Resources */, ); @@ -602,9 +619,11 @@ 4804B31E1C1F757600DA8AF7 /* UIColor+Expanded.m in Sources */, 4804B2FF1C1F55E600DA8AF7 /* ViewController.m in Sources */, 48372A641C20A91C00AD0293 /* LAJSONExplorerViewController.m in Sources */, + 62FE41D31D4829E100CA389D /* LAShapeTrimPath.m in Sources */, 62FE41431D41862200CA389D /* LAAnimatableLayer.m in Sources */, 620A56651D1C81930030EBFB /* LAAnimatableShapeValue.m in Sources */, 4804B3191C1F6DEA00DA8AF7 /* LAComposition.m in Sources */, + 62FE41CB1D48004A00CA389D /* LAEllipseShapeLayer.m in Sources */, 4804B2FC1C1F55E600DA8AF7 /* AppDelegate.m in Sources */, 4804B3211C1F761800DA8AF7 /* BWMath.m in Sources */, 62FE40E51D3FF78800CA389D /* LAAnimatableBoundsValue.m in Sources */, @@ -626,7 +645,6 @@ 48372A551C209A5F00AD0293 /* LAShapePath.m in Sources */, 620CD7E51D38180800055AD1 /* LAGroupLayerView.m in Sources */, 48372AB71C20D97200AD0293 /* LAShapeCircle.m in Sources */, - 620CD7CD1D3415F000055AD1 /* LAAnimatableRectValue.m in Sources */, 620A565C1D1C81610030EBFB /* LAAnimatableColorValue.m in Sources */, 48372A5E1C209A8900AD0293 /* LAShapeTransform.m in Sources */, 62FE41BC1D42DD8500CA389D /* LAMaskLayer.m in Sources */, diff --git a/LotteAnimator.xcworkspace/xcuserdata/brandon_withrow.xcuserdatad/UserInterfaceState.xcuserstate b/LotteAnimator.xcworkspace/xcuserdata/brandon_withrow.xcuserdatad/UserInterfaceState.xcuserstate index d2488463bc083187de1b19cb7d95a57f86e0bd0f..85264755fd5cd2bb26bb8bafd874c37c3a263d83 100644 GIT binary patch literal 66060 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 diff --git a/LotteAnimator.xcworkspace/xcuserdata/brandon_withrow.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/LotteAnimator.xcworkspace/xcuserdata/brandon_withrow.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 453d7341b4..c3cce40adc 100644 --- a/LotteAnimator.xcworkspace/xcuserdata/brandon_withrow.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/LotteAnimator.xcworkspace/xcuserdata/brandon_withrow.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -67,13 +67,13 @@ shouldBeEnabled = "Yes" ignoreCount = "0" continueAfterRunningActions = "No" - filePath = "LotteAnimator/LAShapeCircle.m" - timestampString = "490729764.635343" + filePath = "LotteAnimator/LAMaskLayer.m" + timestampString = "491264085.840767" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "14" - endingLineNumber = "14" - landmarkName = "-initWithJSON:frameRate:" + startingLineNumber = "54" + endingLineNumber = "54" + landmarkName = "-renderInContext:" landmarkType = "5"> @@ -83,13 +83,13 @@ shouldBeEnabled = "Yes" ignoreCount = "0" continueAfterRunningActions = "No" - filePath = "LotteAnimator/LAAnimatableScaleValue.m" - timestampString = "490740783.490737" + filePath = "LotteAnimator/LAMaskLayer.m" + timestampString = "491264087.213296" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "82" - endingLineNumber = "82" - landmarkName = "-_buildAnimationForKeyframes:" + startingLineNumber = "50" + endingLineNumber = "50" + landmarkName = "-drawInContext:" landmarkType = "5"> @@ -100,7 +100,7 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "LotteAnimator/LAAnimatableLayer.m" - timestampString = "490920717.958644" + timestampString = "491266116.833188" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" startingLineNumber = "56" @@ -109,53 +109,5 @@ landmarkType = "5"> - - - - - - - - - - - - diff --git a/LotteAnimator/LAAnimatableLayer.m b/LotteAnimator/LAAnimatableLayer.m index 08c12c777f..1c7f672f20 100644 --- a/LotteAnimator/LAAnimatableLayer.m +++ b/LotteAnimator/LAAnimatableLayer.m @@ -93,5 +93,4 @@ layer.beginTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; } - @end diff --git a/LotteAnimator/LAAnimatableRectValue.h b/LotteAnimator/LAAnimatableRectValue.h deleted file mode 100644 index ca8a283716..0000000000 --- a/LotteAnimator/LAAnimatableRectValue.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// LAAnimatableSizeValue.h -// LotteAnimator -// -// Created by brandon_withrow on 7/11/16. -// Copyright © 2016 Brandon Withrow. All rights reserved. -// - -#import - -@interface LAAnimatableRectValue : NSObject - -- (instancetype)initWithRectValues:(NSDictionary *)rectValues frameRate:(NSNumber *)frameRate; - -@property (nonatomic, readonly) CGRect initialRect; -@property (nonatomic, readonly) NSArray *rectKeyframes; -@property (nonatomic, readonly) NSArray *keyTimes; -@property (nonatomic, readonly) NSArray *timingFunctions; -@property (nonatomic, readonly) NSTimeInterval delay; -@property (nonatomic, readonly) NSTimeInterval duration; -@property (nonatomic, readonly) BOOL hasAnimation; -@property (nonatomic, readonly) NSNumber *startFrame; -@property (nonatomic, readonly) NSNumber *durationFrames; -@property (nonatomic, readonly) NSNumber *frameRate; - -- (CAKeyframeAnimation *)animationForKeyPath:(NSString *)keypath; - -@end diff --git a/LotteAnimator/LAAnimatableRectValue.m b/LotteAnimator/LAAnimatableRectValue.m deleted file mode 100644 index 40023029b4..0000000000 --- a/LotteAnimator/LAAnimatableRectValue.m +++ /dev/null @@ -1,22 +0,0 @@ -// -// LAAnimatableSizeValue.m -// LotteAnimator -// -// Created by brandon_withrow on 7/11/16. -// Copyright © 2016 Brandon Withrow. All rights reserved. -// - -#import "LAAnimatableRectValue.h" - -@implementation LAAnimatableRectValue - -- (instancetype)initWithRectValues:(NSDictionary *)rectValues frameRate:(NSNumber *)frameRate { - self = [super init]; - if (self) { - _frameRate = frameRate; - - } - return self; -} - -@end diff --git a/LotteAnimator/LACompView.m b/LotteAnimator/LACompView.m index 451393b53d..26fa22b046 100644 --- a/LotteAnimator/LACompView.m +++ b/LotteAnimator/LACompView.m @@ -28,11 +28,20 @@ NSMutableDictionary *layerMap = [NSMutableDictionary dictionary]; NSArray *reversedItems = [[_sceneModel.layers reverseObjectEnumerator] allObjects]; - + + LALayerView *maskedLayer = nil; for (LALayer *layer in reversedItems) { LALayerView *layerView = [[LALayerView alloc] initWithModel:layer inComposition:_sceneModel]; layerMap[layer.layerID] = layerView; - [self.layer addSublayer:layerView]; + if (maskedLayer) { + maskedLayer.mask = layerView; + maskedLayer = nil; + } else { + if (layer.matteType == LAMatteTypeAdd) { + maskedLayer = layerView; + } + [self.layer addSublayer:layerView]; + } } _layerMap = layerMap; } diff --git a/LotteAnimator/LAEllipseShapeLayer.h b/LotteAnimator/LAEllipseShapeLayer.h new file mode 100644 index 0000000000..7914cfcad7 --- /dev/null +++ b/LotteAnimator/LAEllipseShapeLayer.h @@ -0,0 +1,20 @@ +// +// LAEllipseShapeLayer.h +// LotteAnimator +// +// Created by brandon_withrow on 7/26/16. +// Copyright © 2016 Brandon Withrow. All rights reserved. +// + +#import "LAAnimatableLayer.h" + +@interface LAEllipseShapeLayer : LAAnimatableLayer + +- (instancetype)initWithEllipseShape:(LAShapeCircle *)circleShape + fill:(LAShapeFill *)fill + stroke:(LAShapeStroke *)stroke + trim:(LAShapeTrimPath *)trim + transform:(LAShapeTransform *)transform + withDuration:(NSTimeInterval)duration; + +@end diff --git a/LotteAnimator/LAEllipseShapeLayer.m b/LotteAnimator/LAEllipseShapeLayer.m new file mode 100644 index 0000000000..89aacc98e4 --- /dev/null +++ b/LotteAnimator/LAEllipseShapeLayer.m @@ -0,0 +1,121 @@ +// +// LAEllipseShapeLayer.m +// LotteAnimator +// +// Created by brandon_withrow on 7/26/16. +// Copyright © 2016 Brandon Withrow. All rights reserved. +// + +#import "LAEllipseShapeLayer.h" +#import "CAAnimationGroup+LAAnimatableGroup.h" + +@implementation LAEllipseShapeLayer { + LAShapeTransform *_transform; + LAShapeStroke *_stroke; + LAShapeFill *_fill; + LAShapeCircle *_circle; + LAShapeTrimPath *_trim; + + CAShapeLayer *_fillLayer; + CAShapeLayer *_strokeLayer; + + CAAnimationGroup *_animation; + CAAnimationGroup *_strokeAnimation; + CAAnimationGroup *_fillAnimation; +} + +- (instancetype)initWithEllipseShape:(LAShapeCircle *)circleShape + fill:(LAShapeFill *)fill + stroke:(LAShapeStroke *)stroke + trim:(LAShapeTrimPath *)trim + transform:(LAShapeTransform *)transform + withDuration:(NSTimeInterval)duration { + self = [super initWithDuration:duration]; + if (self) { + _circle = circleShape; + _stroke = stroke; + _fill = fill; + _transform = transform; + _trim = trim; + + self.allowsEdgeAntialiasing = YES; + self.frame = _transform.compBounds; + self.anchorPoint = _transform.anchor.initialPoint; + self.opacity = _transform.opacity.initialValue.floatValue; + self.position = _transform.position.initialPoint; + self.transform = _transform.scale.initialScale; + self.sublayerTransform = CATransform3DMakeRotation(_transform.rotation.initialValue.floatValue, 0, 0, 1); + + if (fill) { + _fillLayer = [CAShapeLayer new]; + _fillLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-50, -50, 100, 100)].CGPath; + _fillLayer.allowsEdgeAntialiasing = YES; + _fillLayer.position = circleShape.position.initialPoint; + _fillLayer.transform = circleShape.scale.initialScale; + _fillLayer.fillColor = _fill.color.initialColor.CGColor; + _fillLayer.opacity = _fill.opacity.initialValue.floatValue; + [self addSublayer:_fillLayer]; + } + + if (stroke) { + _strokeLayer = [CAShapeLayer new]; + _strokeLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-50, -50, 100, 100)].CGPath; + _strokeLayer.allowsEdgeAntialiasing = YES; + _strokeLayer.position = circleShape.position.initialPoint; + _strokeLayer.transform = circleShape.scale.initialScale; + _strokeLayer.strokeColor = _stroke.color.initialColor.CGColor; + _strokeLayer.opacity = _stroke.opacity.initialValue.floatValue; + _strokeLayer.lineWidth = _stroke.width.initialValue.floatValue; + _strokeLayer.fillColor = nil; + _strokeLayer.backgroundColor = nil; + _strokeLayer.lineDashPattern = _stroke.lineDashPattern; + if (trim) { + _strokeLayer.strokeStart = _trim.start.initialValue.floatValue; + _strokeLayer.strokeEnd = _trim.end.initialValue.floatValue; + } + [self addSublayer:_strokeLayer]; + } + self.animationSublayers = [NSArray arrayWithArray:self.sublayers]; + + [self _buildAnimation]; + [self pause]; + } + + return self; +} + +- (void)_buildAnimation { + if (_transform) { + _animation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:@{@"opacity" : _transform.opacity, + @"position" : _transform.position, + @"anchorPoint" : _transform.anchor, + @"transform" : _transform.scale, + @"sublayerTransform.rotation" : _transform.rotation}]; + [self addAnimation:_animation forKey:@"LotteAnimation"]; + } + + if (_stroke) { + NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary:@{@"strokeColor" : _stroke.color, + @"opacity" : _stroke.opacity, + @"lineWidth" : _stroke.width, + @"position" : _circle.position, + @"transform" : _circle.scale}]; + if (_trim) { + properties[@"strokeStart"] = _trim.start; + properties[@"strokeEnd"] = _trim.end; + } + _strokeAnimation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:properties]; + [_strokeLayer addAnimation:_strokeAnimation forKey:@""]; + + } + + if (_fill) { + _fillAnimation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:@{@"backgroundColor" : _fill.color, + @"opacity" : _fill.opacity, + @"position" : _circle.position, + @"transform" : _circle.scale}]; + [_fillLayer addAnimation:_fillAnimation forKey:@""]; + } +} + +@end diff --git a/LotteAnimator/LAGroupLayerView.m b/LotteAnimator/LAGroupLayerView.m index 5485d45f19..354a8f5212 100644 --- a/LotteAnimator/LAGroupLayerView.m +++ b/LotteAnimator/LAGroupLayerView.m @@ -9,6 +9,8 @@ #import "LAGroupLayerView.h" #import "LAShapeLayerView.h" #import "LARectShapeLayer.h" +#import "LAEllipseShapeLayer.h" + #import "CAAnimationGroup+LAAnimatableGroup.h" @implementation LAGroupLayerView { @@ -45,6 +47,7 @@ LAShapeFill *currentFill; LAShapeStroke *currentStroke; LAShapeTransform *currentTransform; + LAShapeTrimPath *currentTrim; NSMutableArray *shapeLayers = [NSMutableArray array]; NSMutableArray *groupLayers = [NSMutableArray array]; @@ -56,11 +59,14 @@ currentStroke = item; } else if ([item isKindOfClass:[LAShapeFill class]]) { currentFill = item; + } else if ([item isKindOfClass:[LAShapeTrimPath class]]) { + currentTrim = item; } else if ([item isKindOfClass:[LAShapePath class]]) { LAShapePath *shapePath = (LAShapePath *)item; LAShapeLayerView *shapeLayer = [[LAShapeLayerView alloc] initWithShape:shapePath fill:currentFill stroke:currentStroke + trim:currentTrim transform:currentTransform withDuration:self.laAnimationDuration]; [shapeLayers addObject:shapeLayer]; @@ -74,6 +80,16 @@ withDuration:self.laAnimationDuration]; [shapeLayers addObject:shapeLayer]; [self addSublayer:shapeLayer]; + } else if ([item isKindOfClass:[LAShapeCircle class]]) { + LAShapeCircle *shapeCircle = (LAShapeCircle *)item; + LAEllipseShapeLayer *shapeLayer = [[LAEllipseShapeLayer alloc] initWithEllipseShape:shapeCircle + fill:currentFill + stroke:currentStroke + trim:currentTrim + transform:currentTransform + withDuration:self.laAnimationDuration]; + [shapeLayers addObject:shapeLayer]; + [self addSublayer:shapeLayer]; } else if ([item isKindOfClass:[LAShapeGroup class]]) { LAShapeGroup *shapeGroup = (LAShapeGroup *)item; LAGroupLayerView *groupLayer = [[LAGroupLayerView alloc] initWithShapeGroup:shapeGroup diff --git a/LotteAnimator/LALayer.h b/LotteAnimator/LALayer.h index ce5e1cfebe..d7faa3627b 100644 --- a/LotteAnimator/LALayer.h +++ b/LotteAnimator/LALayer.h @@ -14,7 +14,6 @@ @class LAAnimatableColorValue; @class LAAnimatablePointValue; @class LAAnimatableNumberValue; -@class LAAnimatableRectValue; @class LAAnimatableScaleValue; @class LAComposition; @@ -26,6 +25,13 @@ typedef enum : NSInteger { LALayerTypeShape } LALayerType; +typedef enum : NSInteger { + LAMatteTypeNone, + LAMatteTypeAdd, + LAMatteTypeInvert, + LALayerTypeUknown +} LAMatteType; + @interface LALayer : NSObject - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary fromComposition:(LAComposition *)composition; @@ -42,8 +48,9 @@ typedef enum : NSInteger { @property (nonatomic, readonly) NSArray *shapes; @property (nonatomic, readonly) NSArray *masks; -@property (nonatomic, readonly) LAAnimatableRectValue *solidBounds; -@property (nonatomic, readonly) LAAnimatableColorValue *solidColor; +@property (nonatomic, readonly) NSNumber *solidWidth; +@property (nonatomic, readonly) NSNumber *solidHeight; +@property (nonatomic, readonly) UIColor *solidColor; @property (nonatomic, readonly) LAAnimatableNumberValue *opacity; @property (nonatomic, readonly) LAAnimatableNumberValue *rotation; @@ -59,4 +66,6 @@ typedef enum : NSInteger { @property (nonatomic, readonly) NSArray *inOutKeyTimes; @property (nonatomic, readonly) NSTimeInterval compDuration; +@property (nonatomic, readonly) LAMatteType matteType; + @end diff --git a/LotteAnimator/LALayer.m b/LotteAnimator/LALayer.m index 3ec1c1d0fe..2d6767623d 100644 --- a/LotteAnimator/LALayer.m +++ b/LotteAnimator/LALayer.m @@ -42,8 +42,10 @@ _outFrame = [jsonDictionary[@"op"] copy]; if (_layerType == LALayerTypeSolid) { - // TODO Solids. - + _solidWidth = jsonDictionary[@"sw"]; + _solidHeight = jsonDictionary[@"sh"]; + NSString *solidColor = jsonDictionary[@"sc"]; + _solidColor = [UIColor colorWithHexString:solidColor]; } NSDictionary *ks = jsonDictionary[@"ks"]; @@ -78,6 +80,9 @@ _scale = [[LAAnimatableScaleValue alloc] initWithScaleValues:scale frameRate:_framerate]; } + _matteType = [jsonDictionary[@"tt"] integerValue]; + + NSMutableArray *masks = [NSMutableArray array]; for (NSDictionary *maskJSON in jsonDictionary[@"masksProperties"]) { LAMask *mask = [[LAMask alloc] initWithJSON:maskJSON frameRate:_framerate]; diff --git a/LotteAnimator/LALayerView.m b/LotteAnimator/LALayerView.m index 48401872b4..8163696812 100644 --- a/LotteAnimator/LALayerView.m +++ b/LotteAnimator/LALayerView.m @@ -10,6 +10,7 @@ #import "LAShapeLayerView.h" #import "LAGroupLayerView.h" #import "CAAnimationGroup+LAAnimatableGroup.h" +#import "LAMaskLayer.h" @interface LAParentLayer : LAAnimatableLayer @@ -59,7 +60,7 @@ CAKeyframeAnimation *_inOutAnimation; NSArray *_parentLayers; LAComposition *_composition; - + LAMaskLayer *_maskLayer; } - (instancetype)initWithModel:(LALayer *)model inComposition:(LAComposition *)comp { @@ -73,9 +74,18 @@ } - (void)_setupViewFromModel { - self.bounds = _composition.compBounds; + self.backgroundColor = nil; + if (_layerModel.layerType == LALayerTypeSolid) { + self.bounds = CGRectMake(0, 0, _layerModel.solidWidth.floatValue, _layerModel.solidHeight.floatValue); + } else { + self.bounds = _composition.compBounds; + } + self.anchorPoint = CGPointZero; + _childContainerLayer = [CALayer new]; + _childContainerLayer.bounds = self.bounds; + _childContainerLayer.backgroundColor = _layerModel.solidColor.CGColor; self.animationSublayers = @[_childContainerLayer]; NSNumber *parentID = _layerModel.parentID; @@ -121,9 +131,29 @@ _shapeLayers = shapeLayers; +// CALayer *anchorLayer = [CALayer new]; +// anchorLayer.bounds = CGRectMake(0, 0, 20, 20); +// anchorLayer.backgroundColor = [UIColor redColor].CGColor; +// anchorLayer.anchorPoint = CGPointMake(0.5, 0.5); +// anchorLayer.position = CGPointZero; +// anchorLayer.opacity = 0.25; +// _childContainerLayer.borderWidth = 6; +// _childContainerLayer.backgroundColor = [UIColor greenColor].CGColor; +// _childContainerLayer.borderColor = [UIColor redColor].CGColor; +// [_childContainerLayer addSublayer:anchorLayer]; + + if (_layerModel.masks) { + _maskLayer = [[LAMaskLayer alloc] initWithMasks:_layerModel.masks inComposition:_composition]; + _maskLayer.opacity = 0.5; + [_childContainerLayer addSublayer:_maskLayer]; + } + NSMutableArray *childLayers = [NSMutableArray array]; [childLayers addObjectsFromArray:_parentLayers]; [childLayers addObjectsFromArray:_shapeLayers]; + if (_maskLayer) { + [childLayers addObject:_maskLayer]; + } self.childLayers = childLayers; [self _buildAnimations]; diff --git a/LotteAnimator/LAMaskLayer.m b/LotteAnimator/LAMaskLayer.m index 7597656564..291f25ec67 100644 --- a/LotteAnimator/LAMaskLayer.m +++ b/LotteAnimator/LAMaskLayer.m @@ -7,14 +7,17 @@ // #import "LAMaskLayer.h" +#import "CAAnimationGroup+LAAnimatableGroup.h" @implementation LAMaskLayer { LAComposition *_composition; + NSArray *_maskLayers; } - (instancetype)initWithMasks:(NSArray *)masks inComposition:(LAComposition *)comp { self = [super initWithDuration:comp.timeDuration]; if (self) { +// self.bounds = comp.compBounds; _masks = masks; _composition = comp; [self _setupViewFromModel]; @@ -23,6 +26,31 @@ } - (void)_setupViewFromModel { + NSMutableArray *maskLayers = [NSMutableArray array]; + + for (LAMask *mask in _masks) { + CAShapeLayer *maskLayer = [CAShapeLayer new]; + maskLayer.path = mask.maskPath.initialShape.CGPath; + maskLayer.fillColor = [UIColor whiteColor].CGColor; + maskLayer.opacity = mask.opacity.initialValue.floatValue; + [self addSublayer:maskLayer]; + CAAnimationGroup *animGroup = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:@{@"opacity" : mask.opacity, + @"path" : mask.maskPath}]; + if (animGroup) { + [maskLayer addAnimation:animGroup forKey:@""]; + } + [maskLayers addObject:maskLayer]; + } + _maskLayers = maskLayers; + self.animationSublayers = maskLayers; + [self pause]; +} + +- (void)drawInContext:(CGContextRef)ctx { + +} + +-(void)renderInContext:(CGContextRef)ctx { } diff --git a/LotteAnimator/LAModels.h b/LotteAnimator/LAModels.h index 629b3c281e..1911d44004 100644 --- a/LotteAnimator/LAModels.h +++ b/LotteAnimator/LAModels.h @@ -22,9 +22,9 @@ #import "LAAnimatableColorValue.h" #import "LAAnimatableNumberValue.h" #import "LAAnimatablePointValue.h" -#import "LAAnimatableRectValue.h" #import "LAAnimatableScaleValue.h" #import "LAAnimatableShapeValue.h" +#import "LAShapeTrimPath.h" #endif /* LAModels_h */ diff --git a/LotteAnimator/LARectShapeLayer.h b/LotteAnimator/LARectShapeLayer.h index 7dd331635e..813f3f2949 100644 --- a/LotteAnimator/LARectShapeLayer.h +++ b/LotteAnimator/LARectShapeLayer.h @@ -12,9 +12,9 @@ @interface LARectShapeLayer : LAAnimatableLayer - (instancetype)initWithRectShape:(LAShapeRectangle *)rectShape - fill:(LAShapeFill *)fill - stroke:(LAShapeStroke *)stroke - transform:(LAShapeTransform *)transform + fill:(LAShapeFill *)fill + stroke:(LAShapeStroke *)stroke + transform:(LAShapeTransform *)transform withDuration:(NSTimeInterval)duration; @end diff --git a/LotteAnimator/LARectShapeLayer.m b/LotteAnimator/LARectShapeLayer.m index c1a7a5c7d2..d9abab4589 100644 --- a/LotteAnimator/LARectShapeLayer.m +++ b/LotteAnimator/LARectShapeLayer.m @@ -43,24 +43,30 @@ self.transform = _transform.scale.initialScale; self.sublayerTransform = CATransform3DMakeRotation(_transform.rotation.initialValue.floatValue, 0, 0, 1); - _fillLayer = [CALayer layer]; - _fillLayer.allowsEdgeAntialiasing = YES; - _fillLayer.bounds = rectShape.bounds.initialBounds; - _fillLayer.position = rectShape.position.initialPoint; - _fillLayer.cornerRadius = rectShape.cornerRadius.initialValue.floatValue; - _fillLayer.backgroundColor = _fill.color.initialColor.CGColor; - _fillLayer.opacity = _fill.opacity.initialValue.floatValue; - [self addSublayer:_fillLayer]; + if (fill) { + _fillLayer = [CALayer layer]; + _fillLayer.allowsEdgeAntialiasing = YES; + _fillLayer.bounds = rectShape.bounds.initialBounds; + _fillLayer.position = rectShape.position.initialPoint; + _fillLayer.cornerRadius = rectShape.cornerRadius.initialValue.floatValue; + _fillLayer.backgroundColor = _fill.color.initialColor.CGColor; + _fillLayer.opacity = _fill.opacity.initialValue.floatValue; + [self addSublayer:_fillLayer]; + } + + if (stroke) { + _strokeLayer = [CALayer layer]; + _strokeLayer.allowsEdgeAntialiasing = YES; + _strokeLayer.bounds = rectShape.bounds.initialBounds; + _strokeLayer.position = rectShape.position.initialPoint; + _strokeLayer.cornerRadius = rectShape.cornerRadius.initialValue.floatValue; + _strokeLayer.borderColor = _stroke.color.initialColor.CGColor; + _strokeLayer.opacity = _stroke.opacity.initialValue.floatValue; + _strokeLayer.borderWidth = _stroke.width.initialValue.floatValue; + _strokeLayer.backgroundColor = nil; + } + self.animationSublayers = [NSArray arrayWithArray:self.sublayers]; - _strokeLayer = [CALayer layer]; - _strokeLayer.allowsEdgeAntialiasing = YES; - _strokeLayer.bounds = rectShape.bounds.initialBounds; - _strokeLayer.position = rectShape.position.initialPoint; - _strokeLayer.cornerRadius = rectShape.cornerRadius.initialValue.floatValue; - _strokeLayer.borderColor = _stroke.color.initialColor.CGColor; - _strokeLayer.opacity = _stroke.opacity.initialValue.floatValue; - _strokeLayer.borderWidth = _stroke.width.initialValue.floatValue; - _strokeLayer.backgroundColor = nil; [self addSublayer:_strokeLayer]; [self _buildAnimation]; [self pause]; diff --git a/LotteAnimator/LAShapeCircle.h b/LotteAnimator/LAShapeCircle.h index 8421f50b6d..4347837415 100644 --- a/LotteAnimator/LAShapeCircle.h +++ b/LotteAnimator/LAShapeCircle.h @@ -12,4 +12,7 @@ - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate; +@property (nonatomic, readonly) LAAnimatablePointValue *position; +@property (nonatomic, readonly) LAAnimatableScaleValue *scale; + @end diff --git a/LotteAnimator/LAShapeCircle.m b/LotteAnimator/LAShapeCircle.m index ef4ec4168f..32b3286df3 100644 --- a/LotteAnimator/LAShapeCircle.m +++ b/LotteAnimator/LAShapeCircle.m @@ -19,7 +19,16 @@ } - (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate { + NSDictionary *position = jsonDictionary[@"p"]; + if (position) { + _position = [[LAAnimatablePointValue alloc] initWithPointValues:position frameRate:frameRate]; + _position.usePathAnimation = NO; + } + NSDictionary *scale = jsonDictionary[@"s"]; + if (scale) { + _scale = [[LAAnimatableScaleValue alloc] initWithScaleValues:scale frameRate:frameRate]; + } } @end diff --git a/LotteAnimator/LAShapeGroup.m b/LotteAnimator/LAShapeGroup.m index f68d041480..d122c0f572 100644 --- a/LotteAnimator/LAShapeGroup.m +++ b/LotteAnimator/LAShapeGroup.m @@ -13,6 +13,7 @@ #import "LAShapeStroke.h" #import "LAShapeTransform.h" #import "LAShapeRectangle.h" +#import "LAShapeTrimPath.h" @implementation LAShapeGroup @@ -51,6 +52,9 @@ } else if ([type isEqualToString:@"rc"]) { LAShapeRectangle *rectangle = [[LAShapeRectangle alloc] initWithJSON:itemJSON frameRate:frameRate]; [items addObject:rectangle]; + } else if ([type isEqualToString:@"tm"]) { + LAShapeTrimPath *trim = [[LAShapeTrimPath alloc] initWithJSON:itemJSON frameRate:frameRate]; + [items addObject:trim]; } } _items = items; diff --git a/LotteAnimator/LAShapeLayerView.h b/LotteAnimator/LAShapeLayerView.h index 0cb38abe38..638194ef10 100644 --- a/LotteAnimator/LAShapeLayerView.h +++ b/LotteAnimator/LAShapeLayerView.h @@ -14,9 +14,8 @@ - (instancetype)initWithShape:(LAShapePath *)shape fill:(LAShapeFill *)fill stroke:(LAShapeStroke *)stroke + trim:(LAShapeTrimPath *)trim transform:(LAShapeTransform *)transform withDuration:(NSTimeInterval)duration; -- (void)startAnimation; - @end diff --git a/LotteAnimator/LAShapeLayerView.m b/LotteAnimator/LAShapeLayerView.m index 2d7ec48720..34374c9a94 100644 --- a/LotteAnimator/LAShapeLayerView.m +++ b/LotteAnimator/LAShapeLayerView.m @@ -14,6 +14,7 @@ LAShapeStroke *_stroke; LAShapeFill *_fill; LAShapePath *_path; + LAShapeTrimPath *_trim; CAShapeLayer *_fillLayer; CAShapeLayer *_strokeLayer; @@ -26,6 +27,7 @@ - (instancetype)initWithShape:(LAShapePath *)shape fill:(LAShapeFill *)fill stroke:(LAShapeStroke *)stroke + trim:(LAShapeTrimPath *)trim transform:(LAShapeTransform *)transform withDuration:(NSTimeInterval)duration { self = [super initWithDuration:duration]; @@ -34,6 +36,7 @@ _stroke = stroke; _fill = fill; _transform = transform; + _trim = trim; self.allowsEdgeAntialiasing = YES; self.frame = _transform.compBounds; @@ -43,26 +46,43 @@ self.transform = _transform.scale.initialScale; self.sublayerTransform = CATransform3DMakeRotation(_transform.rotation.initialValue.floatValue, 0, 0, 1); - _fillLayer = [CAShapeLayer layer]; - _fillLayer.allowsEdgeAntialiasing = YES; - _fillLayer.path = _path.shapePath.initialShape.CGPath; - _fillLayer.fillColor = _fill.color.initialColor.CGColor; - _fillLayer.opacity = _fill.opacity.initialValue.floatValue; - [self addSublayer:_fillLayer]; + if (fill) { + _fillLayer = [CAShapeLayer layer]; + _fillLayer.allowsEdgeAntialiasing = YES; + _fillLayer.path = _path.shapePath.initialShape.CGPath; + _fillLayer.fillColor = _fill.color.initialColor.CGColor; + _fillLayer.opacity = _fill.opacity.initialValue.floatValue; + [self addSublayer:_fillLayer]; + } - _strokeLayer = [CAShapeLayer layer]; - _strokeLayer.allowsEdgeAntialiasing = YES; - _strokeLayer.path = _path.shapePath.initialShape.CGPath; - _strokeLayer.strokeColor = _stroke.color.initialColor.CGColor; - _strokeLayer.opacity = _stroke.opacity.initialValue.floatValue; - _strokeLayer.lineWidth = _stroke.width.initialValue.floatValue; - _strokeLayer.fillColor = nil; - self.animationSublayers = @[_fillLayer, _strokeLayer]; + if (stroke) { + _strokeLayer = [CAShapeLayer layer]; + _strokeLayer.allowsEdgeAntialiasing = YES; + _strokeLayer.path = _path.shapePath.initialShape.CGPath; + _strokeLayer.strokeColor = _stroke.color.initialColor.CGColor; + _strokeLayer.opacity = _stroke.opacity.initialValue.floatValue; + _strokeLayer.lineWidth = _stroke.width.initialValue.floatValue; + _strokeLayer.lineDashPattern = _stroke.lineDashPattern; + if (trim) { + _strokeLayer.strokeStart = _trim.start.initialValue.floatValue; + _strokeLayer.strokeEnd = _trim.end.initialValue.floatValue; + } + _strokeLayer.fillColor = nil; + } + + self.animationSublayers = [NSArray arrayWithArray:self.sublayers]; [self addSublayer:_strokeLayer]; [self _buildAnimation]; [self pause]; - +// CALayer *anchorLayer = [CALayer new]; +// anchorLayer.bounds = CGRectMake(0, 0, 10, 10); +// anchorLayer.backgroundColor = [UIColor blueColor].CGColor; +// anchorLayer.anchorPoint = CGPointMake(0.5, 0.5); +// anchorLayer.position = CGPointZero; +// self.borderColor = [UIColor blueColor].CGColor; +// self.borderWidth = 2; +// [self addSublayer:anchorLayer]; } return self; } @@ -78,10 +98,15 @@ } if (_stroke) { - _strokeAnimation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:@{@"strokeColor" : _stroke.color, - @"opacity" : _stroke.opacity, - @"lineWidth" : _stroke.width, - @"path" : _path.shapePath}]; + NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary:@{@"strokeColor" : _stroke.color, + @"opacity" : _stroke.opacity, + @"lineWidth" : _stroke.width, + @"path" : _path.shapePath}]; + if (_trim) { + properties[@"strokeStart"] = _trim.start; + properties[@"strokeEnd"] = _trim.end; + } + _strokeAnimation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:properties]; [_strokeLayer addAnimation:_strokeAnimation forKey:@""]; } diff --git a/LotteAnimator/LAShapeStroke.h b/LotteAnimator/LAShapeStroke.h index f795df4cae..e181885ac6 100644 --- a/LotteAnimator/LAShapeStroke.h +++ b/LotteAnimator/LAShapeStroke.h @@ -19,5 +19,6 @@ @property (nonatomic, readonly) LAAnimatableColorValue *color; @property (nonatomic, readonly) LAAnimatableNumberValue *opacity; @property (nonatomic, readonly) LAAnimatableNumberValue *width; +@property (nonatomic, readonly) NSArray *lineDashPattern; @end diff --git a/LotteAnimator/LAShapeStroke.m b/LotteAnimator/LAShapeStroke.m index 299b2492e7..54410368b9 100644 --- a/LotteAnimator/LAShapeStroke.m +++ b/LotteAnimator/LAShapeStroke.m @@ -39,6 +39,20 @@ NSNumber *fillEnabled = jsonDictionary[@"fillEnabled"]; _fillEnabled = fillEnabled.boolValue; + + NSArray *dashes = jsonDictionary[@"d"]; + if (dashes) { + NSMutableArray *dashPattern = [NSMutableArray array]; + for (NSDictionary *dash in dashes) { + if ([dash[@"n"] isEqualToString:@"o"]) { + continue; + } + NSDictionary *value = dash[@"v"]; + LAAnimatableNumberValue *numberValue = [[LAAnimatableNumberValue alloc] initWithNumberValues:value frameRate:frameRate]; + [dashPattern addObject:[numberValue.initialValue copy]]; + } + _lineDashPattern = dashPattern; + } } @end diff --git a/LotteAnimator/LAShapeTrimPath.h b/LotteAnimator/LAShapeTrimPath.h new file mode 100644 index 0000000000..7e4d134bf7 --- /dev/null +++ b/LotteAnimator/LAShapeTrimPath.h @@ -0,0 +1,19 @@ +// +// LAShapeTrimPath.h +// LotteAnimator +// +// Created by brandon_withrow on 7/26/16. +// Copyright © 2016 Brandon Withrow. All rights reserved. +// + +#import +@class LAAnimatableNumberValue; + +@interface LAShapeTrimPath : NSObject + +- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate; + +@property (nonatomic, readonly) LAAnimatableNumberValue *start; +@property (nonatomic, readonly) LAAnimatableNumberValue *end; + +@end diff --git a/LotteAnimator/LAShapeTrimPath.m b/LotteAnimator/LAShapeTrimPath.m new file mode 100644 index 0000000000..6665548fe5 --- /dev/null +++ b/LotteAnimator/LAShapeTrimPath.m @@ -0,0 +1,35 @@ +// +// LAShapeTrimPath.m +// LotteAnimator +// +// Created by brandon_withrow on 7/26/16. +// Copyright © 2016 Brandon Withrow. All rights reserved. +// + +#import "LAShapeTrimPath.h" + +@implementation LAShapeTrimPath + +- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate { + self = [super init]; + if (self) { + [self _mapFromJSON:jsonDictionary frameRate:frameRate]; + } + return self; +} + +- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate { + NSDictionary *start = jsonDictionary[@"s"]; + if (start) { + _start = [[LAAnimatableNumberValue alloc] initWithNumberValues:start frameRate:frameRate]; + [_start remapValuesFromMin:@0 fromMax:@100 toMin:@0 toMax:@1]; + } + + NSDictionary *end = jsonDictionary[@"e"]; + if (end) { + _end = [[LAAnimatableNumberValue alloc] initWithNumberValues:end frameRate:frameRate]; + [_end remapValuesFromMin:@0 fromMax:@100 toMin:@0 toMax:@1]; + } +} + +@end diff --git a/LotteAnimator/UIColor+Expanded.m b/LotteAnimator/UIColor+Expanded.m index d735570f2a..513f7b983c 100644 --- a/LotteAnimator/UIColor+Expanded.m +++ b/LotteAnimator/UIColor+Expanded.m @@ -359,7 +359,8 @@ static NSMutableDictionary *colorNameCache = nil; // Returns a UIColor by scanning the string for a hex number and passing that to +[UIColor colorWithRGBHex:] // Skips any leading whitespace and ignores any trailing characters + (UIColor *)colorWithHexString:(NSString *)stringToConvert { - NSScanner *scanner = [NSScanner scannerWithString:stringToConvert]; + NSString *strippedString = [stringToConvert stringByReplacingOccurrencesOfString:@"#" withString:@""]; + NSScanner *scanner = [NSScanner scannerWithString:strippedString]; unsigned hexNum; if (![scanner scanHexInt:&hexNum]) return nil; return [UIColor colorWithRGBHex:hexNum]; diff --git a/LotteAnimator/circleTest.json b/LotteAnimator/circleTest.json new file mode 100644 index 0000000000..3299d1324c --- /dev/null +++ b/LotteAnimator/circleTest.json @@ -0,0 +1 @@ +{"assets":[],"v":"4.1.7","ddd":0,"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[0,0,0]},"s":{"k":[100,247.571,100]}},"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[140.039,147.461],"e":[28.039,29.525],"__fnct":[null,null]},{"t":98}]},"p":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0],"e":[-87,69],"to":[-14.5,11.5],"ti":[14.5,-11.5]},{"t":98}]},"nm":"Ellipse Path 1","closed":true},{"d":1,"ty":"el","s":{"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[140.039,147.461],"e":[28.039,29.525],"__fnct":[null,null]},{"t":98}]},"p":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0],"e":[-87,69],"to":[-14.5,11.5],"ti":[14.5,-11.5]},{"t":98}]},"nm":"Ellipse Path 1","closed":true},{"ty":"st","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"fl","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"nm":"Fill 1"},{"ty":"tr","p":{"k":[48.98,-45.27]},"a":{"k":[0,0]},"s":{"k":[100,100]},"r":{"k":0},"o":{"k":100},"sk":{"k":0},"sa":{"k":0}}],"nm":"Ellipse 1"}],"bounds":{"l":-121,"t":-147,"b":95,"r":146},"ip":0,"op":180,"st":0},{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[0,0,0]},"s":{"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[200,200]},"p":{"k":[0,0]},"nm":"Ellipse Path 1","closed":true},{"d":1,"ty":"el","s":{"k":[200,200]},"p":{"k":[0,0]},"nm":"Ellipse Path 1","closed":true},{"ty":"st","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"fl","fillEnabled":true,"c":{"k":[201,26,26,255]},"o":{"k":100},"nm":"Fill 1"},{"ty":"tr","p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"r":{"k":0},"o":{"k":100},"sk":{"k":0},"sa":{"k":0}}],"nm":"Ellipse 1"}],"bounds":{"l":-137,"t":-137,"b":137,"r":137},"ip":0,"op":180,"st":0}],"ip":0,"op":180,"fr":60,"w":600,"h":600} \ No newline at end of file diff --git a/LotteAnimator/masksAndSolids.json b/LotteAnimator/masksAndSolids.json new file mode 100644 index 0000000000..63b9bcb22c --- /dev/null +++ b/LotteAnimator/masksAndSolids.json @@ -0,0 +1 @@ +{"assets":[],"v":"4.1.7","ddd":0,"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Shape Layer 1","td":1,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[306,300,0]},"a":{"k":[0,0,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[51.741,51.741,100],"e":[122.667,122.667,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":90,"s":[122.667,122.667,100],"e":[70.07,70.07,100]},{"t":174}]}},"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[275.75,275.75]},"p":{"k":[0,0]},"nm":"Ellipse Path 1","closed":true},{"d":1,"ty":"el","s":{"k":[275.75,275.75]},"p":{"k":[0,0]},"nm":"Ellipse Path 1","closed":true},{"ty":"st","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"fl","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"nm":"Fill 1"},{"ty":"tr","p":{"k":[-4.789,-1.113]},"a":{"k":[0,0]},"s":{"k":[100,100]},"r":{"k":0},"o":{"k":100},"sk":{"k":0},"sa":{"k":0}}],"nm":"Ellipse 1"}],"bounds":{"l":-193,"t":-189,"b":187,"r":183},"ip":0,"op":180,"st":0},{"ddd":0,"ind":1,"ty":1,"nm":"Cyan Solid 1","tt":2,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[300,300,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100,100],"e":[59,59,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":90,"s":[59,59,100],"e":[108,108,100]},{"t":174}]}},"sw":600,"sh":600,"sc":"#00ffc7","ip":0,"op":180,"st":0},{"ddd":0,"ind":2,"ty":1,"nm":"Medium Purple Solid 2","td":1,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[300,300,0]},"s":{"k":[100,100,100]}},"sw":600,"sh":600,"sc":"#9f5eff","ip":0,"op":180,"st":0},{"ddd":0,"ind":3,"ty":1,"nm":"Medium Purple Solid 1","tt":1,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[300,300,0]},"s":{"k":[100,100,100]}},"sw":600,"sh":600,"sc":"#9f5eff","ip":0,"op":180,"st":0}],"ip":0,"op":180,"fr":60,"w":600,"h":600} \ No newline at end of file diff --git a/LotteAnimator/masktest.json b/LotteAnimator/masktest.json new file mode 100644 index 0000000000..6c7c047cf1 --- /dev/null +++ b/LotteAnimator/masktest.json @@ -0,0 +1 @@ +{"assets":[],"v":"4.1.7","ddd":0,"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[0,0,0]},"s":{"k":[100,100,100]}},"hasMask":true,"masksProperties":[{"cl":true,"inv":false,"mode":"a","pt":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-276,-245],[-201,111.355],[-208.645,-140.645],[30.355,-120]]}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-276,-245],[-253,177.355],[147.355,192.355],[64.355,-153]]}]},{"t":72}]},"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":30}]},"x":{"k":0},"nm":"Mask 1"},{"cl":true,"inv":false,"mode":"a","pt":{"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-152,-76],[-149,49.355],[-47.645,42.355],[-46.645,-72]]}},"o":{"k":100},"x":{"k":0},"nm":"Mask 2"}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"k":[231.355,231.355]},"p":{"k":[0,0]},"r":{"k":20},"nm":"Rectangle Path 1","closed":true},{"ty":"st","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"fl","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"nm":"Fill 1"},{"ty":"tr","p":{"k":[-85.322,-4.322]},"a":{"k":[0,0]},"s":{"k":[100,100]},"r":{"k":0},"o":{"k":100},"sk":{"k":0},"sa":{"k":0}}],"nm":"Rectangle 1"}],"bounds":{"l":-277,"t":-196,"b":187,"r":106},"ip":0,"op":180,"st":0}],"ip":0,"op":180,"fr":60,"w":600,"h":600} \ No newline at end of file