From 6dc8e37392fd89c91dc88f776e6ff7c1ac1e47b9 Mon Sep 17 00:00:00 2001 From: Brandon Withrow Date: Fri, 17 Feb 2017 11:43:13 -0800 Subject: [PATCH] Refactor layers for precomps --- Example/Pods/Pods.xcodeproj/project.pbxproj | 24 +++++ Lottie.xcodeproj/project.pbxproj | 26 +++++ .../AnimatableLayers/LOTAnimatableLayer.h | 4 +- .../AnimatableLayers/LOTAnimatableLayer.m | 4 +- .../AnimatableLayers/LOTEllipseShapeLayer.h | 2 +- .../AnimatableLayers/LOTEllipseShapeLayer.m | 4 +- .../AnimatableLayers/LOTGroupLayerView.h | 2 +- .../AnimatableLayers/LOTGroupLayerView.m | 12 +-- .../Classes/AnimatableLayers/LOTLayerView.h | 2 +- .../Classes/AnimatableLayers/LOTLayerView.m | 63 ++++++------ .../Classes/AnimatableLayers/LOTMaskLayer.h | 2 +- .../Classes/AnimatableLayers/LOTMaskLayer.m | 8 +- .../AnimatableLayers/LOTRectShapeLayer.h | 2 +- .../AnimatableLayers/LOTRectShapeLayer.m | 4 +- .../AnimatableLayers/LOTShapeLayerView.h | 2 +- .../AnimatableLayers/LOTShapeLayerView.m | 4 +- .../Extensions/CGGeometry+LOTAdditions.h | 1 + .../Extensions/CGGeometry+LOTAdditions.m | 1 + lottie-ios/Classes/Models/LOTAsset.h | 30 ++++++ lottie-ios/Classes/Models/LOTAsset.m | 54 +++++++++++ lottie-ios/Classes/Models/LOTComposition.h | 7 +- lottie-ios/Classes/Models/LOTComposition.m | 31 +++--- lottie-ios/Classes/Models/LOTLayer.h | 23 ++--- lottie-ios/Classes/Models/LOTLayer.m | 97 ++++++++++--------- lottie-ios/Classes/Models/LOTLayerGroup.h | 25 +++++ lottie-ios/Classes/Models/LOTLayerGroup.m | 58 +++++++++++ lottie-ios/Classes/Models/LOTModels.h | 2 + lottie-ios/Classes/Private/LOTAnimationView.m | 20 ++-- .../Private/LOTAnimationView_Internal.h | 2 +- 29 files changed, 375 insertions(+), 141 deletions(-) create mode 100644 lottie-ios/Classes/Models/LOTAsset.h create mode 100644 lottie-ios/Classes/Models/LOTAsset.m create mode 100644 lottie-ios/Classes/Models/LOTLayerGroup.h create mode 100644 lottie-ios/Classes/Models/LOTLayerGroup.m diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index d9e40e8831..eadac0987d 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -64,6 +64,14 @@ 48183C981E54E1B60039F121 /* CGGeometry+LOTAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 48183C951E54E1B60039F121 /* CGGeometry+LOTAdditions.m */; }; 48183C991E54E1B60039F121 /* CGGeometry+LOTAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 48183C951E54E1B60039F121 /* CGGeometry+LOTAdditions.m */; }; 4833D2BD0666884F509A85C031D7CBCE /* LOTComposition.h in Headers */ = {isa = PBXBuildFile; fileRef = B758F16C1930B57D432706DF7B9D2107 /* LOTComposition.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 484EBA101E5656DD00D4CAD9 /* LOTAsset.h in Headers */ = {isa = PBXBuildFile; fileRef = 484EBA0E1E5656DD00D4CAD9 /* LOTAsset.h */; }; + 484EBA111E5656DD00D4CAD9 /* LOTAsset.h in Headers */ = {isa = PBXBuildFile; fileRef = 484EBA0E1E5656DD00D4CAD9 /* LOTAsset.h */; }; + 484EBA121E5656DD00D4CAD9 /* LOTAsset.m in Sources */ = {isa = PBXBuildFile; fileRef = 484EBA0F1E5656DD00D4CAD9 /* LOTAsset.m */; }; + 484EBA131E5656DD00D4CAD9 /* LOTAsset.m in Sources */ = {isa = PBXBuildFile; fileRef = 484EBA0F1E5656DD00D4CAD9 /* LOTAsset.m */; }; + 484EBA1D1E567CF500D4CAD9 /* LOTLayerGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 484EBA1B1E567CF500D4CAD9 /* LOTLayerGroup.h */; }; + 484EBA1E1E567CF500D4CAD9 /* LOTLayerGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 484EBA1B1E567CF500D4CAD9 /* LOTLayerGroup.h */; }; + 484EBA1F1E567CF500D4CAD9 /* LOTLayerGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 484EBA1C1E567CF500D4CAD9 /* LOTLayerGroup.m */; }; + 484EBA201E567CF500D4CAD9 /* LOTLayerGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 484EBA1C1E567CF500D4CAD9 /* LOTLayerGroup.m */; }; 484FF8CA1E4A972500B2B4FF /* LOTStrokeShapeLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 484FF8C81E4A972500B2B4FF /* LOTStrokeShapeLayer.h */; }; 484FF8CB1E4A972500B2B4FF /* LOTStrokeShapeLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 484FF8C81E4A972500B2B4FF /* LOTStrokeShapeLayer.h */; }; 484FF8CC1E4A972500B2B4FF /* LOTStrokeShapeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 484FF8C91E4A972500B2B4FF /* LOTStrokeShapeLayer.m */; }; @@ -243,6 +251,10 @@ 3FC6C122778B882931A442F9B6AAE024 /* lottie-ios-OSX-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "lottie-ios-OSX-prefix.pch"; sourceTree = ""; }; 48183C941E54E1B60039F121 /* CGGeometry+LOTAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CGGeometry+LOTAdditions.h"; sourceTree = ""; }; 48183C951E54E1B60039F121 /* CGGeometry+LOTAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CGGeometry+LOTAdditions.m"; sourceTree = ""; }; + 484EBA0E1E5656DD00D4CAD9 /* LOTAsset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOTAsset.h; sourceTree = ""; }; + 484EBA0F1E5656DD00D4CAD9 /* LOTAsset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOTAsset.m; sourceTree = ""; }; + 484EBA1B1E567CF500D4CAD9 /* LOTLayerGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOTLayerGroup.h; sourceTree = ""; }; + 484EBA1C1E567CF500D4CAD9 /* LOTLayerGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOTLayerGroup.m; sourceTree = ""; }; 484FF8C81E4A972500B2B4FF /* LOTStrokeShapeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOTStrokeShapeLayer.h; sourceTree = ""; }; 484FF8C91E4A972500B2B4FF /* LOTStrokeShapeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOTStrokeShapeLayer.m; sourceTree = ""; }; 4897935C31F44A855C225490165F579E /* CAAnimationGroup+LOTAnimatableGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CAAnimationGroup+LOTAnimatableGroup.m"; sourceTree = ""; }; @@ -593,6 +605,10 @@ children = ( B758F16C1930B57D432706DF7B9D2107 /* LOTComposition.h */, 914E38365E034D0D2874EAB4410B0ED0 /* LOTComposition.m */, + 484EBA0E1E5656DD00D4CAD9 /* LOTAsset.h */, + 484EBA0F1E5656DD00D4CAD9 /* LOTAsset.m */, + 484EBA1B1E567CF500D4CAD9 /* LOTLayerGroup.h */, + 484EBA1C1E567CF500D4CAD9 /* LOTLayerGroup.m */, 91320FA54A945B0D6F0DA1360E66F4EA /* LOTLayer.h */, 0D575B6A057045C18575B20F98F4D18A /* LOTLayer.m */, CCFB05FD8351F6DF6D9DB1678426591E /* LOTMask.h */, @@ -723,10 +739,12 @@ 4D0C60F8C4A252367B7C4875F9B0BDB0 /* LOTEllipseShapeLayer.h in Headers */, 29CA4EE59B08D1ED8109B415457D3CDC /* LOTGroupLayerView.h in Headers */, 3A31C00DAD5EE96060356B8229A0F880 /* LOTHelpers.h in Headers */, + 484EBA111E5656DD00D4CAD9 /* LOTAsset.h in Headers */, 759E46CB49AAE25993A70A2DE97D266E /* LOTLayer.h in Headers */, 87A26BF6CC45ADCB0FBC7D764C5A3947 /* LOTLayerView.h in Headers */, 23FF5E1FEC9F357DEEC6BFE5563C10F1 /* LOTMask.h in Headers */, 7299688E73D2B61F3361281ACBB4660E /* LOTMaskLayer.h in Headers */, + 484EBA1E1E567CF500D4CAD9 /* LOTLayerGroup.h in Headers */, 579F11312EA02E2DCFF81BE25F51DB39 /* LOTModels.h in Headers */, 48183C971E54E1B60039F121 /* CGGeometry+LOTAdditions.h in Headers */, 1B7AD1DB3B240B3F6075DAC7A2C60327 /* LOTPlatformCompat.h in Headers */, @@ -774,10 +792,12 @@ 838D6155DE51A16593725CE970CA6C90 /* LOTEllipseShapeLayer.h in Headers */, 573C01EC3D0F512491BCF3DEB5AAB748 /* LOTGroupLayerView.h in Headers */, BD0CE52E57F950D3E084CF4C5F8A8B2F /* LOTHelpers.h in Headers */, + 484EBA101E5656DD00D4CAD9 /* LOTAsset.h in Headers */, 20DEFD8C1B7E76272B928C15B18B68B0 /* LOTLayer.h in Headers */, 46F17145DD61E422E878E2625D0588FA /* LOTLayerView.h in Headers */, 2CDB9C2783AEFB59BD0E027E2E0F88A7 /* LOTMask.h in Headers */, 7EDB7B9FA909F0E056D34EEEFD73D9EF /* LOTMaskLayer.h in Headers */, + 484EBA1D1E567CF500D4CAD9 /* LOTLayerGroup.h in Headers */, E2D5868DEC6CBB929B419FB3285731B1 /* LOTModels.h in Headers */, 48183C961E54E1B60039F121 /* CGGeometry+LOTAdditions.h in Headers */, 019EB390040200530FBD33CFCE1C6C0C /* LOTPlatformCompat.h in Headers */, @@ -965,6 +985,7 @@ 484FF8CC1E4A972500B2B4FF /* LOTStrokeShapeLayer.m in Sources */, 4732ECB066C837C3484D9DB2F226773D /* LOTComposition.m in Sources */, 4EFC87278E4E7401727B49678BD95620 /* LOTEllipseShapeLayer.m in Sources */, + 484EBA1F1E567CF500D4CAD9 /* LOTLayerGroup.m in Sources */, 6AECE84D2606A6EB774D90B68BF02FBE /* LOTGroupLayerView.m in Sources */, ED8BD061B14A26E55DA40C65C1FA9E45 /* LOTLayer.m in Sources */, E1E7AB1C22FF3517808A0F359915D1DE /* LOTLayerView.m in Sources */, @@ -973,6 +994,7 @@ BF134B98B1B9D10C25342E2C29FB8765 /* LOTRectShapeLayer.m in Sources */, FC2DFB5A3D8CA54CB00264F7DF5DBCA7 /* LOTShapeCircle.m in Sources */, 48183C981E54E1B60039F121 /* CGGeometry+LOTAdditions.m in Sources */, + 484EBA121E5656DD00D4CAD9 /* LOTAsset.m in Sources */, 7979D3A6E47E7449AC865C57DD35F839 /* LOTShapeFill.m in Sources */, 1C1FD4859F03CD5975789890C67FDE5B /* LOTShapeGroup.m in Sources */, 4F0B2D6C49741327F6B439F355B73E51 /* LOTShapeLayerView.m in Sources */, @@ -1025,6 +1047,7 @@ 484FF8CD1E4A972500B2B4FF /* LOTStrokeShapeLayer.m in Sources */, 951641D26236D9DD1D8497D421AB0F99 /* LOTComposition.m in Sources */, 362836E5A94EEC788130DAB3D72E04E8 /* LOTEllipseShapeLayer.m in Sources */, + 484EBA201E567CF500D4CAD9 /* LOTLayerGroup.m in Sources */, 0075B6488FF197D8668F10AF357C0521 /* LOTGroupLayerView.m in Sources */, A0FAA7BFF3B0DDAA8533821938A60B22 /* LOTLayer.m in Sources */, A79AFADC19D70226BACF2E8ED2CBB9D3 /* LOTLayerView.m in Sources */, @@ -1033,6 +1056,7 @@ ECFF0DF0D7D8168BC81B98D4FFE56BAE /* LOTRectShapeLayer.m in Sources */, DA138E1AC245BB30E51CE90933818034 /* LOTShapeCircle.m in Sources */, 48183C991E54E1B60039F121 /* CGGeometry+LOTAdditions.m in Sources */, + 484EBA131E5656DD00D4CAD9 /* LOTAsset.m in Sources */, 15EF53F42565FBC7BBF78E742576D83E /* LOTShapeFill.m in Sources */, FCF6945890A6ECE3E662EAD107349713 /* LOTShapeGroup.m in Sources */, 0B29280A9ADDDD0EE1FA1575967AC5BD /* LOTShapeLayerView.m in Sources */, diff --git a/Lottie.xcodeproj/project.pbxproj b/Lottie.xcodeproj/project.pbxproj index ef65303565..58c8060bed 100644 --- a/Lottie.xcodeproj/project.pbxproj +++ b/Lottie.xcodeproj/project.pbxproj @@ -145,6 +145,15 @@ 481A4AEE1E4A78A5003CF62B /* LOTPlatformCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 481A4ADC1E4A78A0003CF62B /* LOTPlatformCompat.h */; }; 4883E4E31E5F9EE400027E57 /* LOTStrokeShapeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 489F8E111E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.m */; }; 4883E4E41E5F9EE400027E57 /* CGGeometry+LOTAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 48183C9B1E54E20B0039F121 /* CGGeometry+LOTAdditions.m */; }; + 484EBA161E565AF700D4CAD9 /* LOTAsset.h in Headers */ = {isa = PBXBuildFile; fileRef = 484EBA141E565AF700D4CAD9 /* LOTAsset.h */; }; + 484EBA171E565AF700D4CAD9 /* LOTAsset.h in Headers */ = {isa = PBXBuildFile; fileRef = 484EBA141E565AF700D4CAD9 /* LOTAsset.h */; }; + 484EBA181E565AF700D4CAD9 /* LOTAsset.m in Sources */ = {isa = PBXBuildFile; fileRef = 484EBA151E565AF700D4CAD9 /* LOTAsset.m */; }; + 484EBA191E565AF700D4CAD9 /* LOTAsset.m in Sources */ = {isa = PBXBuildFile; fileRef = 484EBA151E565AF700D4CAD9 /* LOTAsset.m */; }; + 484EBA1A1E565AF700D4CAD9 /* LOTAsset.m in Sources */ = {isa = PBXBuildFile; fileRef = 484EBA151E565AF700D4CAD9 /* LOTAsset.m */; }; + 484EBA251E57898D00D4CAD9 /* LOTLayerGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 484EBA231E57898D00D4CAD9 /* LOTLayerGroup.h */; }; + 484EBA261E57898D00D4CAD9 /* LOTLayerGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 484EBA231E57898D00D4CAD9 /* LOTLayerGroup.h */; }; + 484EBA271E57898D00D4CAD9 /* LOTLayerGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 484EBA241E57898D00D4CAD9 /* LOTLayerGroup.m */; }; + 484EBA281E57898D00D4CAD9 /* LOTLayerGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 484EBA241E57898D00D4CAD9 /* LOTLayerGroup.m */; }; 489F8E121E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 489F8E101E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.h */; }; 489F8E131E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 489F8E101E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.h */; }; 489F8E141E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 489F8E111E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.m */; }; @@ -282,6 +291,10 @@ 481A4AE01E4A78A0003CF62B /* UIBezierPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIBezierPath.m; sourceTree = ""; }; 481A4AE11E4A78A0003CF62B /* UIColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIColor.h; sourceTree = ""; }; 481A4AE21E4A78A0003CF62B /* UIColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIColor.m; sourceTree = ""; }; + 484EBA141E565AF700D4CAD9 /* LOTAsset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOTAsset.h; sourceTree = ""; }; + 484EBA151E565AF700D4CAD9 /* LOTAsset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOTAsset.m; sourceTree = ""; }; + 484EBA231E57898D00D4CAD9 /* LOTLayerGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOTLayerGroup.h; sourceTree = ""; }; + 484EBA241E57898D00D4CAD9 /* LOTLayerGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOTLayerGroup.m; sourceTree = ""; }; 489F8E101E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LOTStrokeShapeLayer.h; sourceTree = ""; }; 489F8E111E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LOTStrokeShapeLayer.m; sourceTree = ""; }; 62CA59B81E3C173B002D7188 /* Lottie.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Lottie.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -399,6 +412,10 @@ 481A4A441E4A7885003CF62B /* LOTMask.h */, 481A4A451E4A7885003CF62B /* LOTMask.m */, 481A4A461E4A7885003CF62B /* LOTModels.h */, + 484EBA141E565AF700D4CAD9 /* LOTAsset.h */, + 484EBA151E565AF700D4CAD9 /* LOTAsset.m */, + 484EBA231E57898D00D4CAD9 /* LOTLayerGroup.h */, + 484EBA241E57898D00D4CAD9 /* LOTLayerGroup.m */, 481A4A471E4A7885003CF62B /* LOTShapeCircle.h */, 481A4A481E4A7885003CF62B /* LOTShapeCircle.m */, 481A4A491E4A7885003CF62B /* LOTShapeFill.h */, @@ -526,6 +543,7 @@ 481A4A5F1E4A7885003CF62B /* LOTEllipseShapeLayer.h in Headers */, 481A4ACD1E4A7885003CF62B /* LOTShapeTrimPath.h in Headers */, 489F8E121E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.h in Headers */, + 484EBA251E57898D00D4CAD9 /* LOTLayerGroup.h in Headers */, 481A4A671E4A7885003CF62B /* LOTLayerView.h in Headers */, 481A4AC11E4A7885003CF62B /* LOTShapeRectangle.h in Headers */, 481A4AC51E4A7885003CF62B /* LOTShapeStroke.h in Headers */, @@ -537,6 +555,7 @@ 481A4A771E4A7885003CF62B /* LOTAnimatableBoundsValue.h in Headers */, 481A4AB11E4A7885003CF62B /* LOTShapeCircle.h in Headers */, 481A4A8B1E4A7885003CF62B /* LOTAnimatableShapeValue.h in Headers */, + 484EBA161E565AF700D4CAD9 /* LOTAsset.h in Headers */, 481A4AAB1E4A7885003CF62B /* LOTMask.h in Headers */, 481A4A871E4A7885003CF62B /* LOTAnimatableScaleValue.h in Headers */, 481A4A951E4A7885003CF62B /* CAAnimationGroup+LOTAnimatableGroup.h in Headers */, @@ -568,6 +587,7 @@ 481A4A601E4A7885003CF62B /* LOTEllipseShapeLayer.h in Headers */, 481A4ACA1E4A7885003CF62B /* LOTShapeTransform.h in Headers */, 481A4AE51E4A78A0003CF62B /* CALayer+Compat.h in Headers */, + 484EBA171E565AF700D4CAD9 /* LOTAsset.h in Headers */, 489F8E131E4CF3BE00F2DEB7 /* LOTStrokeShapeLayer.h in Headers */, 48183C9D1E54E20B0039F121 /* CGGeometry+LOTAdditions.h in Headers */, 481A4A701E4A7885003CF62B /* LOTRectShapeLayer.h in Headers */, @@ -582,6 +602,7 @@ 481A4AC61E4A7885003CF62B /* LOTShapeStroke.h in Headers */, 481A4AA41E4A7885003CF62B /* LOTComposition.h in Headers */, 481A4A801E4A7885003CF62B /* LOTAnimatableNumberValue.h in Headers */, + 484EBA261E57898D00D4CAD9 /* LOTLayerGroup.h in Headers */, 481A4ACE1E4A7885003CF62B /* LOTShapeTrimPath.h in Headers */, 481A4AA01E4A7885003CF62B /* UIColor+Expanded.h in Headers */, FAE1F7CE1E428CBE002E0974 /* LOTAnimationTransitionController.h in Headers */, @@ -712,6 +733,7 @@ buildActionMask = 2147483647; files = ( 481A4ACB1E4A7885003CF62B /* LOTShapeTransform.m in Sources */, + 484EBA271E57898D00D4CAD9 /* LOTLayerGroup.m in Sources */, 481A4A6D1E4A7885003CF62B /* LOTMaskLayer.m in Sources */, 481A4A971E4A7885003CF62B /* CAAnimationGroup+LOTAnimatableGroup.m in Sources */, 481A4A811E4A7885003CF62B /* LOTAnimatableNumberValue.m in Sources */, @@ -731,6 +753,7 @@ 481A4A5D1E4A7885003CF62B /* LOTAnimatableLayer.m in Sources */, 481A4ABB1E4A7885003CF62B /* LOTShapeGroup.m in Sources */, 481A4AAD1E4A7885003CF62B /* LOTMask.m in Sources */, + 484EBA181E565AF700D4CAD9 /* LOTAsset.m in Sources */, 481A4A8D1E4A7885003CF62B /* LOTAnimatableShapeValue.m in Sources */, 481A4AB31E4A7885003CF62B /* LOTShapeCircle.m in Sources */, 481A4A711E4A7885003CF62B /* LOTRectShapeLayer.m in Sources */, @@ -767,6 +790,7 @@ 84FE13051E4C1553009B157C /* LOTAnimationCache.m in Sources */, 84FE13061E4C1553009B157C /* CAAnimationGroup+LOTAnimatableGroup.m in Sources */, 84FE13081E4C1553009B157C /* UIColor+Expanded.m in Sources */, + 484EBA1A1E565AF700D4CAD9 /* LOTAsset.m in Sources */, 84FE13091E4C1553009B157C /* LOTComposition.m in Sources */, 84FE130A1E4C1553009B157C /* LOTLayer.m in Sources */, 84FE130B1E4C1553009B157C /* LOTMask.m in Sources */, @@ -804,7 +828,9 @@ 481A4A5E1E4A7885003CF62B /* LOTAnimatableLayer.m in Sources */, 481A4A8A1E4A7885003CF62B /* LOTAnimatableScaleValue.m in Sources */, 481A4A861E4A7885003CF62B /* LOTAnimatablePointValue.m in Sources */, + 484EBA191E565AF700D4CAD9 /* LOTAsset.m in Sources */, 481A4A621E4A7885003CF62B /* LOTEllipseShapeLayer.m in Sources */, + 484EBA281E57898D00D4CAD9 /* LOTLayerGroup.m in Sources */, 481A4A821E4A7885003CF62B /* LOTAnimatableNumberValue.m in Sources */, 481A4AE41E4A78A0003CF62B /* CADisplayLink.m in Sources */, 481A4A981E4A7885003CF62B /* CAAnimationGroup+LOTAnimatableGroup.m in Sources */, diff --git a/lottie-ios/Classes/AnimatableLayers/LOTAnimatableLayer.h b/lottie-ios/Classes/AnimatableLayers/LOTAnimatableLayer.h index 944d006473..41a23a0b76 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTAnimatableLayer.h +++ b/lottie-ios/Classes/AnimatableLayers/LOTAnimatableLayer.h @@ -10,8 +10,8 @@ @interface LOTAnimatableLayer : CALayer -- (instancetype)initWithDuration:(NSTimeInterval)duration NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithLayerDuration:(NSTimeInterval)duration NS_DESIGNATED_INITIALIZER; -@property (nonatomic, readonly) NSTimeInterval laAnimationDuration; +@property (nonatomic, readonly) NSTimeInterval layerDuration; @end diff --git a/lottie-ios/Classes/AnimatableLayers/LOTAnimatableLayer.m b/lottie-ios/Classes/AnimatableLayers/LOTAnimatableLayer.m index c16e01b07b..0e31c24961 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTAnimatableLayer.m +++ b/lottie-ios/Classes/AnimatableLayers/LOTAnimatableLayer.m @@ -10,10 +10,10 @@ @implementation LOTAnimatableLayer -- (instancetype)initWithDuration:(NSTimeInterval)duration { +- (instancetype)initWithLayerDuration:(NSTimeInterval)duration { self = [super init]; if (self) { - _laAnimationDuration = duration; + _layerDuration = duration; } return self; } diff --git a/lottie-ios/Classes/AnimatableLayers/LOTEllipseShapeLayer.h b/lottie-ios/Classes/AnimatableLayers/LOTEllipseShapeLayer.h index 5d6ea1d4d3..043158c677 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTEllipseShapeLayer.h +++ b/lottie-ios/Classes/AnimatableLayers/LOTEllipseShapeLayer.h @@ -16,6 +16,6 @@ stroke:(LOTShapeStroke *)stroke trim:(LOTShapeTrimPath *)trim transform:(LOTShapeTransform *)transform - withDuration:(NSTimeInterval)duration; + withLayerDuration:(NSTimeInterval)duration; @end diff --git a/lottie-ios/Classes/AnimatableLayers/LOTEllipseShapeLayer.m b/lottie-ios/Classes/AnimatableLayers/LOTEllipseShapeLayer.m index aa23648608..cdd89e5619 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTEllipseShapeLayer.m +++ b/lottie-ios/Classes/AnimatableLayers/LOTEllipseShapeLayer.m @@ -123,8 +123,8 @@ const CGFloat kEllipseControlPointPercentage = 0.55228; stroke:(LOTShapeStroke *)stroke trim:(LOTShapeTrimPath *)trim transform:(LOTShapeTransform *)transform - withDuration:(NSTimeInterval)duration { - self = [super initWithDuration:duration]; + withLayerDuration:(NSTimeInterval)duration { + self = [super initWithLayerDuration:duration]; if (self) { _circle = circleShape; _stroke = stroke; diff --git a/lottie-ios/Classes/AnimatableLayers/LOTGroupLayerView.h b/lottie-ios/Classes/AnimatableLayers/LOTGroupLayerView.h index c19444ff26..b4c0c98cc0 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTGroupLayerView.h +++ b/lottie-ios/Classes/AnimatableLayers/LOTGroupLayerView.h @@ -22,7 +22,7 @@ fill:(LOTShapeFill *)previousFill stroke:(LOTShapeStroke *)previousStroke trimPath:(LOTShapeTrimPath *)previousTrimPath - withDuration:(NSTimeInterval)duration; + withLayerDuration:(NSTimeInterval)duration; @property (nonatomic, readonly) LOTShapeGroup *shapeGroup; @property (nonatomic, readonly) LOTShapeTransform *shapeTransform; diff --git a/lottie-ios/Classes/AnimatableLayers/LOTGroupLayerView.m b/lottie-ios/Classes/AnimatableLayers/LOTGroupLayerView.m index da87d25ad9..248de0acd1 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTGroupLayerView.m +++ b/lottie-ios/Classes/AnimatableLayers/LOTGroupLayerView.m @@ -24,8 +24,8 @@ fill:(LOTShapeFill *)previousFill stroke:(LOTShapeStroke *)previousStroke trimPath:(LOTShapeTrimPath *)previousTrimPath - withDuration:(NSTimeInterval)duration { - self = [super initWithDuration:duration]; + withLayerDuration:(NSTimeInterval)duration { + self = [super initWithLayerDuration:duration]; if (self) { _shapeGroup = shapeGroup; _shapeTransform = previousTransform; @@ -73,7 +73,7 @@ stroke:currentStroke trim:currentTrim transform:currentTransform - withDuration:self.laAnimationDuration]; + withLayerDuration:self.layerDuration]; [shapeLayers addObject:shapeLayer]; [self addSublayer:shapeLayer]; } else if ([item isKindOfClass:[LOTShapeRectangle class]]) { @@ -83,7 +83,7 @@ stroke:currentStroke trim:currentTrim transform:currentTransform - withDuration:self.laAnimationDuration]; + withLayerDuration:self.layerDuration]; [shapeLayers addObject:shapeLayer]; [self addSublayer:shapeLayer]; } else if ([item isKindOfClass:[LOTShapeCircle class]]) { @@ -93,7 +93,7 @@ stroke:currentStroke trim:currentTrim transform:currentTransform - withDuration:self.laAnimationDuration]; + withLayerDuration:self.layerDuration]; [shapeLayers addObject:shapeLayer]; [self addSublayer:shapeLayer]; } else if ([item isKindOfClass:[LOTShapeGroup class]]) { @@ -103,7 +103,7 @@ fill:currentFill stroke:currentStroke trimPath:currentTrim - withDuration:self.laAnimationDuration]; + withLayerDuration:self.layerDuration]; [groupLayers addObject:groupLayer]; [self addSublayer:groupLayer]; } diff --git a/lottie-ios/Classes/AnimatableLayers/LOTLayerView.h b/lottie-ios/Classes/AnimatableLayers/LOTLayerView.h index 5ebcbf3b28..75ddea3fd8 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTLayerView.h +++ b/lottie-ios/Classes/AnimatableLayers/LOTLayerView.h @@ -13,7 +13,7 @@ @interface LOTLayerView : LOTAnimatableLayer -- (instancetype)initWithModel:(LOTLayer *)model inComposition:(LOTComposition *)comp; +- (instancetype)initWithModel:(LOTLayer *)model inLayerGroup:(LOTLayerGroup *)layerGroup; @property (nonatomic, readonly) LOTLayer *layerModel; @property (nonatomic, assign) BOOL debugModeOn; diff --git a/lottie-ios/Classes/AnimatableLayers/LOTLayerView.m b/lottie-ios/Classes/AnimatableLayers/LOTLayerView.m index 95492aa4f2..5bd5209fd5 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTLayerView.m +++ b/lottie-ios/Classes/AnimatableLayers/LOTLayerView.m @@ -17,7 +17,7 @@ @interface LOTParentLayer : LOTAnimatableLayer -- (instancetype)initWithParentModel:(LOTLayer *)parent inComposition:(LOTComposition *)comp; +- (instancetype)initWithParentModel:(LOTLayer *)parent; @end @@ -26,10 +26,10 @@ CAAnimationGroup *_animation; } -- (instancetype)initWithParentModel:(LOTLayer *)parent inComposition:(LOTComposition *)comp { - self = [super initWithDuration:comp.timeDuration]; +- (instancetype)initWithParentModel:(LOTLayer *)parent { + self = [super initWithLayerDuration:parent.layerDuration]; if (self) { - self.bounds = parent.compBounds; + self.bounds = parent.layerBounds; _parentModel = parent; [self _setupLayerFromModel]; } @@ -90,23 +90,21 @@ CAAnimationGroup *_animation; CAKeyframeAnimation *_inOutAnimation; NSArray *_parentLayers; - LOTComposition *_composition; LOTMaskLayer *_maskLayer; } -- (instancetype)initWithModel:(LOTLayer *)model inComposition:(LOTComposition *)comp { - self = [super initWithDuration:comp.timeDuration]; +- (instancetype)initWithModel:(LOTLayer *)model inLayerGroup:(LOTLayerGroup *)layerGroup { + self = [super initWithLayerDuration:model.layerDuration]; if (self) { _layerModel = model; - _composition = comp; - [self _setupViewFromModel]; + [self _setupViewFromModelWithLayerGroup:layerGroup]; } return self; } -- (void)_setupViewFromModel { +- (void)_setupViewFromModelWithLayerGroup:(LOTLayerGroup *)layersGroup { self.backgroundColor = nil; - self.bounds = _composition.compBounds; + self.bounds = _layerModel.layerBounds; self.anchorPoint = CGPointZero; _childContainerLayer = [CALayer new]; @@ -114,7 +112,7 @@ _childContainerLayer.backgroundColor = _layerModel.solidColor.CGColor; if (_layerModel.layerType == LOTLayerTypeSolid) { - _childContainerLayer.bounds = CGRectMake(0, 0, _layerModel.solidWidth.floatValue, _layerModel.solidHeight.floatValue); + _childContainerLayer.bounds = CGRectMake(0, 0, _layerModel.layerWidth.floatValue, _layerModel.layerHeight.floatValue); _childContainerLayer.backgroundColor = nil; _childContainerLayer.masksToBounds = NO; @@ -130,8 +128,8 @@ NSMutableArray *parentLayers = [NSMutableArray array]; if (parentID) { while (parentID != nil) { - LOTLayer *parentModel = [_composition layerModelForID:parentID]; - LOTParentLayer *parentLayer = [[LOTParentLayer alloc] initWithParentModel:parentModel inComposition:_composition]; + LOTLayer *parentModel = [layersGroup layerModelForID:parentID]; + LOTParentLayer *parentLayer = [[LOTParentLayer alloc] initWithParentModel:parentModel]; [parentLayer addSublayer:currentChild]; [parentLayers addObject:parentLayer]; currentChild = parentLayer; @@ -164,7 +162,7 @@ NSArray *groupItems = _layerModel.shapes; NSArray *reversedItems = [[groupItems reverseObjectEnumerator] allObjects]; - LOTShapeTransform *currentTransform = [LOTShapeTransform transformIdentityWithCompBounds:_composition.compBounds]; + LOTShapeTransform *currentTransform = [LOTShapeTransform transformIdentityWithCompBounds:_layerModel.layerBounds]; LOTShapeTrimPath *currentTrimPath = nil; LOTShapeFill *currentFill = nil; LOTShapeStroke *currentStroke = nil; @@ -178,7 +176,7 @@ fill:currentFill stroke:currentStroke trimPath:currentTrimPath - withDuration:self.laAnimationDuration]; + withLayerDuration:self.layerDuration]; [_childContainerLayer addSublayer:groupLayer]; [shapeLayers addObject:groupLayer]; } else if ([item isKindOfClass:[LOTShapePath class]]) { @@ -188,7 +186,7 @@ stroke:currentStroke trim:currentTrimPath transform:currentTransform - withDuration:self.laAnimationDuration]; + withLayerDuration:self.layerDuration]; [shapeLayers addObject:shapeLayer]; [_childContainerLayer addSublayer:shapeLayer]; } else if ([item isKindOfClass:[LOTShapeRectangle class]]) { @@ -198,7 +196,7 @@ stroke:currentStroke trim:currentTrimPath transform:currentTransform - withDuration:self.laAnimationDuration]; + withLayerDuration:self.layerDuration]; [shapeLayers addObject:shapeLayer]; [_childContainerLayer addSublayer:shapeLayer]; } else if ([item isKindOfClass:[LOTShapeCircle class]]) { @@ -208,7 +206,7 @@ stroke:currentStroke trim:currentTrimPath transform:currentTransform - withDuration:self.laAnimationDuration]; + withLayerDuration:self.layerDuration]; [shapeLayers addObject:shapeLayer]; [_childContainerLayer addSublayer:shapeLayer]; } else if ([item isKindOfClass:[LOTShapeTransform class]]) { @@ -225,7 +223,7 @@ _shapeLayers = shapeLayers; if (_layerModel.masks) { - _maskLayer = [[LOTMaskLayer alloc] initWithMasks:_layerModel.masks inComposition:_composition]; + _maskLayer = [[LOTMaskLayer alloc] initWithMasks:_layerModel.masks inLayer:_layerModel]; _childContainerLayer.mask = _maskLayer; } @@ -270,19 +268,20 @@ [_childContainerLayer addAnimation:_animation forKey:@"LottieAnimation"]; } - if (_layerModel.hasInOutAnimation) { - CAKeyframeAnimation *inOutAnimation = [CAKeyframeAnimation animationWithKeyPath:@"hidden"]; - inOutAnimation.keyTimes = _layerModel.inOutKeyTimes; - inOutAnimation.values = _layerModel.inOutKeyframes; - inOutAnimation.duration = _layerModel.compDuration; - inOutAnimation.calculationMode = kCAAnimationDiscrete; - inOutAnimation.fillMode = kCAFillModeForwards; - inOutAnimation.removedOnCompletion = NO; - _inOutAnimation = inOutAnimation; - _inOutAnimation.duration = self.laAnimationDuration; - [self addAnimation:_inOutAnimation forKey:@""]; - } + CAKeyframeAnimation *inOutAnimation = [CAKeyframeAnimation animationWithKeyPath:@"hidden"]; + inOutAnimation.keyTimes = _layerModel.inOutKeyTimes; + inOutAnimation.values = _layerModel.inOutKeyframes; + inOutAnimation.duration = _layerModel.layerDuration; + inOutAnimation.calculationMode = kCAAnimationDiscrete; + inOutAnimation.fillMode = kCAFillModeBoth; + inOutAnimation.removedOnCompletion = NO; + + _inOutAnimation = inOutAnimation; + _inOutAnimation.duration = self.layerDuration; + [self addAnimation:_inOutAnimation forKey:@"inout"]; + self.duration = self.layerDuration + LOT_singleFrameTimeValue; + } - (void)setDebugModeOn:(BOOL)debugModeOn { diff --git a/lottie-ios/Classes/AnimatableLayers/LOTMaskLayer.h b/lottie-ios/Classes/AnimatableLayers/LOTMaskLayer.h index c4d61e7123..fc9f1295e7 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTMaskLayer.h +++ b/lottie-ios/Classes/AnimatableLayers/LOTMaskLayer.h @@ -11,7 +11,7 @@ @interface LOTMaskLayer : LOTAnimatableLayer -- (instancetype)initWithMasks:(NSArray *)masks inComposition:(LOTComposition *)comp; +- (instancetype)initWithMasks:(NSArray *)masks inLayer:(LOTLayer *)layer; @property (nonatomic, readonly) NSArray *masks; diff --git a/lottie-ios/Classes/AnimatableLayers/LOTMaskLayer.m b/lottie-ios/Classes/AnimatableLayers/LOTMaskLayer.m index 4d68aa3e92..dda144da3c 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTMaskLayer.m +++ b/lottie-ios/Classes/AnimatableLayers/LOTMaskLayer.m @@ -10,15 +10,15 @@ #import "CAAnimationGroup+LOTAnimatableGroup.h" @implementation LOTMaskLayer { - LOTComposition *_composition; + LOTLayer *_layer; NSArray *_maskLayers; } -- (instancetype)initWithMasks:(NSArray *)masks inComposition:(LOTComposition *)comp { - self = [super initWithDuration:comp.timeDuration]; +- (instancetype)initWithMasks:(NSArray *)masks inLayer:(LOTLayer *)layer { + self = [super initWithLayerDuration:layer.layerDuration]; if (self) { _masks = masks; - _composition = comp; + _layer = layer; [self _setupViewFromModel]; } return self; diff --git a/lottie-ios/Classes/AnimatableLayers/LOTRectShapeLayer.h b/lottie-ios/Classes/AnimatableLayers/LOTRectShapeLayer.h index fdedc65e0c..7a9016a2c6 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTRectShapeLayer.h +++ b/lottie-ios/Classes/AnimatableLayers/LOTRectShapeLayer.h @@ -17,6 +17,6 @@ stroke:(LOTShapeStroke *)stroke trim:(LOTShapeTrimPath *)trim transform:(LOTShapeTransform *)transform - withDuration:(NSTimeInterval)duration; + withLayerDuration:(NSTimeInterval)duration; @end diff --git a/lottie-ios/Classes/AnimatableLayers/LOTRectShapeLayer.m b/lottie-ios/Classes/AnimatableLayers/LOTRectShapeLayer.m index c7e60c3fe9..29a8b0782f 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTRectShapeLayer.m +++ b/lottie-ios/Classes/AnimatableLayers/LOTRectShapeLayer.m @@ -155,8 +155,8 @@ stroke:(LOTShapeStroke *)stroke trim:(LOTShapeTrimPath *)trim transform:(LOTShapeTransform *)transform - withDuration:(NSTimeInterval)duration { - self = [super initWithDuration:duration]; + withLayerDuration:(NSTimeInterval)duration { + self = [super initWithLayerDuration:duration]; if (self) { _rectangle = rectShape; _stroke = stroke; diff --git a/lottie-ios/Classes/AnimatableLayers/LOTShapeLayerView.h b/lottie-ios/Classes/AnimatableLayers/LOTShapeLayerView.h index 59afd9aa11..efdd7c245f 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTShapeLayerView.h +++ b/lottie-ios/Classes/AnimatableLayers/LOTShapeLayerView.h @@ -16,6 +16,6 @@ stroke:(LOTShapeStroke *)stroke trim:(LOTShapeTrimPath *)trim transform:(LOTShapeTransform *)transform - withDuration:(NSTimeInterval)duration; + withLayerDuration:(NSTimeInterval)duration; @end diff --git a/lottie-ios/Classes/AnimatableLayers/LOTShapeLayerView.m b/lottie-ios/Classes/AnimatableLayers/LOTShapeLayerView.m index f64bf75f4d..820f9dac36 100644 --- a/lottie-ios/Classes/AnimatableLayers/LOTShapeLayerView.m +++ b/lottie-ios/Classes/AnimatableLayers/LOTShapeLayerView.m @@ -30,8 +30,8 @@ stroke:(LOTShapeStroke *)stroke trim:(LOTShapeTrimPath *)trim transform:(LOTShapeTransform *)transform - withDuration:(NSTimeInterval)duration { - self = [super initWithDuration:duration]; + withLayerDuration:(NSTimeInterval)duration { + self = [super initWithLayerDuration:duration]; if (self) { _path = shape; _stroke = stroke; diff --git a/lottie-ios/Classes/Extensions/CGGeometry+LOTAdditions.h b/lottie-ios/Classes/Extensions/CGGeometry+LOTAdditions.h index 4b6fc82a91..4397205eed 100644 --- a/lottie-ios/Classes/Extensions/CGGeometry+LOTAdditions.h +++ b/lottie-ios/Classes/Extensions/CGGeometry+LOTAdditions.h @@ -8,6 +8,7 @@ // extern const CGSize CGSizeMax; +extern const NSTimeInterval LOT_singleFrameTimeValue; CGRect LOT_RectIntegral(CGRect rect); diff --git a/lottie-ios/Classes/Extensions/CGGeometry+LOTAdditions.m b/lottie-ios/Classes/Extensions/CGGeometry+LOTAdditions.m index 47c1e06283..fe570260f0 100644 --- a/lottie-ios/Classes/Extensions/CGGeometry+LOTAdditions.m +++ b/lottie-ios/Classes/Extensions/CGGeometry+LOTAdditions.m @@ -2,6 +2,7 @@ #import "CGGeometry+LOTAdditions.h" const CGSize CGSizeMax = {CGFLOAT_MAX, CGFLOAT_MAX}; +const NSTimeInterval LOT_singleFrameTimeValue = 1.0 / 60.0; // // Core Graphics Geometry Additions // diff --git a/lottie-ios/Classes/Models/LOTAsset.h b/lottie-ios/Classes/Models/LOTAsset.h new file mode 100644 index 0000000000..6f2c8975c4 --- /dev/null +++ b/lottie-ios/Classes/Models/LOTAsset.h @@ -0,0 +1,30 @@ +// +// LOTAsset.h +// Pods +// +// Created by Brandon Withrow on 2/16/17. +// +// + +#import +#import + +@class LOTLayerGroup; +@class LOTLayer; + +@interface LOTAsset : NSObject + +- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary + withBounds:(CGRect)bounds + withFramerate:(NSNumber *)framerate; + +@property (nonatomic, readonly) NSString *referenceID; +@property (nonatomic, readonly) NSNumber *assetWidth; +@property (nonatomic, readonly) NSNumber *assetHeight; + +@property (nonatomic, readonly) NSString *imageName; +@property (nonatomic, readonly) NSString *imageDirectory; + +@property (nonatomic, readonly) LOTLayerGroup *layerGroup; + +@end diff --git a/lottie-ios/Classes/Models/LOTAsset.m b/lottie-ios/Classes/Models/LOTAsset.m new file mode 100644 index 0000000000..0918797ac6 --- /dev/null +++ b/lottie-ios/Classes/Models/LOTAsset.m @@ -0,0 +1,54 @@ +// +// LOTAsset.m +// Pods +// +// Created by Brandon Withrow on 2/16/17. +// +// + +#import "LOTAsset.h" +#import "LOTLayer.h" +#import "LOTLayerGroup.h" + +@implementation LOTAsset + +- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary + withBounds:(CGRect)bounds + withFramerate:(NSNumber *)framerate { + self = [super init]; + if (self) { + [self _mapFromJSON:jsonDictionary withBounds:bounds withFramerate:framerate]; + } + return self; +} + + +- (void)_mapFromJSON:(NSDictionary *)jsonDictionary + withBounds:(CGRect)bounds + withFramerate:(NSNumber *)framerate { + _referenceID = [jsonDictionary[@"id"] copy]; + + if (jsonDictionary[@"w"]) { + _assetWidth = [jsonDictionary[@"w"] copy]; + } + + if (jsonDictionary[@"h"]) { + _assetHeight = [jsonDictionary[@"h"] copy]; + } + + if (jsonDictionary[@"u"]) { + _imageDirectory = [jsonDictionary[@"u"] copy]; + } + + if (jsonDictionary[@"p"]) { + _imageName = [jsonDictionary[@"p"] copy]; + } + + NSArray *layersJSON = jsonDictionary[@"layers"]; + if (layersJSON) { + _layerGroup = [[LOTLayerGroup alloc] initWithLayerJSON:layersJSON withBounds:bounds withFramerate:framerate]; + } + +} + +@end diff --git a/lottie-ios/Classes/Models/LOTComposition.h b/lottie-ios/Classes/Models/LOTComposition.h index 8332508242..61833d9c92 100644 --- a/lottie-ios/Classes/Models/LOTComposition.h +++ b/lottie-ios/Classes/Models/LOTComposition.h @@ -9,19 +9,22 @@ #import #import +@class LOTLayerGroup; @class LOTLayer; +@class LOTAsset; @interface LOTComposition : NSObject - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary; -@property (nonatomic, readonly) NSArray *layers; + @property (nonatomic, readonly) CGRect compBounds; @property (nonatomic, readonly) NSNumber *startFrame; @property (nonatomic, readonly) NSNumber *endFrame; @property (nonatomic, readonly) NSNumber *framerate; @property (nonatomic, readonly) NSTimeInterval timeDuration; +@property (nonatomic, readonly) LOTLayerGroup *layerGroup; -- (LOTLayer *)layerModelForID:(NSNumber *)layerID; +- (LOTAsset *)assetModelForID:(NSNumber *)assetID; @end diff --git a/lottie-ios/Classes/Models/LOTComposition.m b/lottie-ios/Classes/Models/LOTComposition.m index 5326adf0b8..641df4a2db 100644 --- a/lottie-ios/Classes/Models/LOTComposition.m +++ b/lottie-ios/Classes/Models/LOTComposition.m @@ -8,9 +8,11 @@ #import "LOTComposition.h" #import "LOTLayer.h" +#import "LOTAsset.h" +#import "LOTLayerGroup.h" @implementation LOTComposition { - NSDictionary *_modelMap; + NSDictionary *_assetMap; } - (instancetype)initWithJSON:(NSDictionary *)jsonDictionary { @@ -40,21 +42,26 @@ } NSArray *layersJSON = jsonDictionary[@"layers"]; - NSMutableArray *layers = [NSMutableArray array]; - NSMutableDictionary *modelMap = [NSMutableDictionary dictionary]; - - for (NSDictionary *layerJSON in layersJSON) { - LOTLayer *layer = [[LOTLayer alloc] initWithJSON:layerJSON fromComposition:self]; - [layers addObject:layer]; - modelMap[layer.layerID] = layer; + if (layersJSON) { + _layerGroup = [[LOTLayerGroup alloc] initWithLayerJSON:layersJSON withBounds:_compBounds withFramerate:_framerate]; } - _modelMap = modelMap; - _layers = layers; + NSMutableDictionary *assets = [NSMutableDictionary dictionary]; + NSArray *assetArray = jsonDictionary[@"assets"]; + + for (NSDictionary *assetDictionary in assetArray) { + NSString *referenceID = assetDictionary[@"id"]; + LOTLayer *layer = [_layerGroup layerForReferenceID:referenceID]; + if (layer) { + LOTAsset *asset = [[LOTAsset alloc] initWithJSON:assetDictionary withBounds:layer.layerBounds withFramerate:layer.framerate]; + assets[asset.referenceID] = asset; + } + } + _assetMap = assets; } -- (LOTLayer *)layerModelForID:(NSNumber *)layerID { - return _modelMap[layerID]; +- (LOTAsset *)assetModelForID:(NSNumber *)assetID { + return _assetMap[assetID]; } @end diff --git a/lottie-ios/Classes/Models/LOTLayer.h b/lottie-ios/Classes/Models/LOTLayer.h index c3e5842ab5..0c61ab97fa 100644 --- a/lottie-ios/Classes/Models/LOTLayer.h +++ b/lottie-ios/Classes/Models/LOTLayer.h @@ -15,14 +15,14 @@ @class LOTAnimatablePointValue; @class LOTAnimatableNumberValue; @class LOTAnimatableScaleValue; -@class LOTComposition; typedef enum : NSInteger { - LOTLayerTypeNone, + LOTLayerTypePrecomp, LOTLayerTypeSolid, - LOTLayerTypeUnknown, + LOTLayerTypeImage, LOTLayerTypeNull, - LOTLayerTypeShape + LOTLayerTypeShape, + LOTLayerTypeUnknown } LOTLayerType; typedef enum : NSInteger { @@ -34,22 +34,25 @@ typedef enum : NSInteger { @interface LOTLayer : NSObject -- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary fromComposition:(LOTComposition *)composition; +- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary + withCompBounds:(CGRect)compBounds + withFramerate:(NSNumber *)framerate; @property (nonatomic, readonly) NSString *layerName; +@property (nonatomic, readonly) NSString *referenceID; @property (nonatomic, readonly) NSNumber *layerID; @property (nonatomic, readonly) LOTLayerType layerType; @property (nonatomic, readonly) NSNumber *parentID; @property (nonatomic, readonly) NSNumber *inFrame; @property (nonatomic, readonly) NSNumber *outFrame; -@property (nonatomic, readonly) CGRect compBounds; +@property (nonatomic, readonly) CGRect layerBounds; @property (nonatomic, readonly) NSNumber *framerate; @property (nonatomic, readonly) NSArray *shapes; @property (nonatomic, readonly) NSArray *masks; -@property (nonatomic, readonly) NSNumber *solidWidth; -@property (nonatomic, readonly) NSNumber *solidHeight; +@property (nonatomic, readonly) NSNumber *layerWidth; +@property (nonatomic, readonly) NSNumber *layerHeight; @property (nonatomic, readonly) UIColor *solidColor; @property (nonatomic, readonly) LOTAnimatableNumberValue *opacity; @@ -62,12 +65,10 @@ typedef enum : NSInteger { @property (nonatomic, readonly) LOTAnimatablePointValue *anchor; @property (nonatomic, readonly) LOTAnimatableScaleValue *scale; -@property (nonatomic, readonly) BOOL hasOutAnimation; @property (nonatomic, readonly) BOOL hasInAnimation; -@property (nonatomic, readonly) BOOL hasInOutAnimation; @property (nonatomic, readonly) NSArray *inOutKeyframes; @property (nonatomic, readonly) NSArray *inOutKeyTimes; -@property (nonatomic, readonly) NSTimeInterval compDuration; +@property (nonatomic, readonly) NSTimeInterval layerDuration; @property (nonatomic, readonly) LOTMatteType matteType; diff --git a/lottie-ios/Classes/Models/LOTLayer.m b/lottie-ios/Classes/Models/LOTLayer.m index b39a038c1b..2c8966d798 100644 --- a/lottie-ios/Classes/Models/LOTLayer.m +++ b/lottie-ios/Classes/Models/LOTLayer.m @@ -15,41 +15,53 @@ #import "LOTComposition.h" #import "LOTHelpers.h" #import "LOTMask.h" +#import "LOTHelpers.h" @implementation LOTLayer -- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary fromComposition:(LOTComposition *)composition { +- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary + withCompBounds:(CGRect)compBounds + withFramerate:(NSNumber *)framerate { self = [super init]; if (self) { - [self _mapFromJSON:jsonDictionary fromComposition:composition]; + [self _mapFromJSON:jsonDictionary withCompBounds:compBounds withFramerate:framerate]; } return self; } -- (void)_mapFromJSON:(NSDictionary *)jsonDictionary fromComposition:(LOTComposition *)composition { +- (void)_mapFromJSON:(NSDictionary *)jsonDictionary + withCompBounds:(CGRect)compBounds + withFramerate:(NSNumber *)framerate { + _layerName = [jsonDictionary[@"nm"] copy]; _layerID = [jsonDictionary[@"ind"] copy]; - _compBounds = composition.compBounds; - _framerate = composition.framerate; + _layerBounds = compBounds; + _framerate = framerate; NSNumber *layerType = jsonDictionary[@"ty"]; - if (layerType.integerValue <= LOTLayerTypeShape) { - _layerType = layerType.integerValue; - } else { - _layerType = LOTLayerTypeUnknown; + _layerType = layerType.integerValue; + + if (jsonDictionary[@"refID"]) { + _referenceID = [jsonDictionary[@"refID"] copy]; } _parentID = [jsonDictionary[@"parent"] copy]; _inFrame = [jsonDictionary[@"ip"] copy]; _outFrame = [jsonDictionary[@"op"] copy]; + if (_layerType == LOTLayerTypePrecomp) { + _layerHeight = [jsonDictionary[@"h"] copy]; + _layerWidth = [jsonDictionary[@"w"] copy]; + } + if (_layerType == LOTLayerTypeSolid) { - _solidWidth = jsonDictionary[@"sw"]; - _solidHeight = jsonDictionary[@"sh"]; - _compBounds = CGRectMake(0, 0, _solidWidth.floatValue, _solidHeight.floatValue); + _layerWidth = jsonDictionary[@"sw"]; + _layerHeight = jsonDictionary[@"sh"]; + _layerBounds = CGRectMake(0, 0, _layerWidth.floatValue, _layerHeight.floatValue); NSString *solidColor = jsonDictionary[@"sc"]; _solidColor = [UIColor LOT_colorWithHexString:solidColor]; } + NSDictionary *ks = jsonDictionary[@"ks"]; NSDictionary *opacity = ks[@"o"]; @@ -81,7 +93,7 @@ NSDictionary *anchor = ks[@"a"]; if (anchor) { _anchor = [[LOTAnimatablePointValue alloc] initWithPointValues:anchor frameRate:_framerate]; - [_anchor remapPointsFromBounds:_compBounds toBounds:CGRectMake(0, 0, 1, 1)]; + [_anchor remapPointsFromBounds:_layerBounds toBounds:CGRectMake(0, 0, 1, 1)]; _anchor.usePathAnimation = NO; } @@ -102,47 +114,38 @@ NSMutableArray *shapes = [NSMutableArray array]; for (NSDictionary *shapeJSON in jsonDictionary[@"shapes"]) { - id shapeItem = [LOTShapeGroup shapeItemWithJSON:shapeJSON frameRate:_framerate compBounds:_compBounds]; + id shapeItem = [LOTShapeGroup shapeItemWithJSON:shapeJSON frameRate:_framerate compBounds:_layerBounds]; if (shapeItem) { [shapes addObject:shapeItem]; } } _shapes = shapes; - _hasInAnimation = (_inFrame.integerValue > composition.startFrame.integerValue); - _hasOutAnimation = (_outFrame.integerValue < composition.endFrame.integerValue); - _hasInOutAnimation = _hasInAnimation || _hasOutAnimation; - if (_hasInOutAnimation) { - NSMutableArray *keys = [NSMutableArray array]; - NSMutableArray *keyTimes = [NSMutableArray array]; - CGFloat compLength = composition.endFrame.floatValue - composition.startFrame.floatValue; - - if (_hasInAnimation) { - [keys addObject:@1]; - [keyTimes addObject:@0]; - [keys addObject:@0]; - CGFloat inTime = _inFrame.floatValue / compLength; - [keyTimes addObject:@(inTime)]; - } else { - [keys addObject:@0]; - [keyTimes addObject:@0]; - } - - if (_hasOutAnimation) { - [keys addObject:@1]; - CGFloat outTime = _outFrame.floatValue / compLength; - [keyTimes addObject:@(outTime)]; - [keys addObject:@1]; - [keyTimes addObject:@1]; - } else { - [keys addObject:@0]; - [keyTimes addObject:@1]; - } - - _compDuration = composition.timeDuration; - _inOutKeyTimes = keyTimes; - _inOutKeyframes = keys; + _hasInAnimation = _inFrame.integerValue > 0; + + NSMutableArray *keys = [NSMutableArray array]; + NSMutableArray *keyTimes = [NSMutableArray array]; + CGFloat layerLength = _outFrame.integerValue; + _layerDuration = (layerLength / _framerate.floatValue); + + if (_hasInAnimation) { + [keys addObject:@1]; + [keyTimes addObject:@0]; + [keys addObject:@0]; + CGFloat inTime = _inFrame.floatValue / layerLength; + [keyTimes addObject:@(inTime)]; + } else { + [keys addObject:@0]; + [keyTimes addObject:@0]; } + + [keys addObject:@1]; + [keyTimes addObject:@1]; + + + + _inOutKeyTimes = keyTimes; + _inOutKeyframes = keys; } @end diff --git a/lottie-ios/Classes/Models/LOTLayerGroup.h b/lottie-ios/Classes/Models/LOTLayerGroup.h new file mode 100644 index 0000000000..5aca90c36f --- /dev/null +++ b/lottie-ios/Classes/Models/LOTLayerGroup.h @@ -0,0 +1,25 @@ +// +// LOTLayerGroup.h +// Pods +// +// Created by Brandon Withrow on 2/16/17. +// +// + +#import +#import + +@class LOTLayer; + +@interface LOTLayerGroup : NSObject + +- (instancetype)initWithLayerJSON:(NSArray *)layersJSON + withBounds:(CGRect)bounds + withFramerate:(NSNumber *)framerate; + +@property (nonatomic, readonly) NSArray *layers; + +- (LOTLayer *)layerModelForID:(NSNumber *)layerID; +- (LOTLayer *)layerForReferenceID:(NSString *)referenceID; + +@end diff --git a/lottie-ios/Classes/Models/LOTLayerGroup.m b/lottie-ios/Classes/Models/LOTLayerGroup.m new file mode 100644 index 0000000000..c2a3ff0c34 --- /dev/null +++ b/lottie-ios/Classes/Models/LOTLayerGroup.m @@ -0,0 +1,58 @@ +// +// LOTLayerGroup.m +// Pods +// +// Created by Brandon Withrow on 2/16/17. +// +// + +#import "LOTLayerGroup.h" +#import "LOTLayer.h" + +@implementation LOTLayerGroup { + CGRect _bounds; + NSNumber *_framerate; + NSDictionary *_modelMap; + NSDictionary *_referenceIDMap; +} + +- (instancetype)initWithLayerJSON:(NSArray *)layersJSON + withBounds:(CGRect)bounds + withFramerate:(NSNumber *)framerate { + self = [super init]; + if (self) { + _framerate = framerate; + _bounds = bounds; + [self _mapFromJSON:layersJSON]; + } + return self; +} + +- (void)_mapFromJSON:(NSArray *)layersJSON { + NSMutableArray *layers = [NSMutableArray array]; + NSMutableDictionary *modelMap = [NSMutableDictionary dictionary]; + NSMutableDictionary *referenceMap = [NSMutableDictionary dictionary]; + + for (NSDictionary *layerJSON in layersJSON) { + LOTLayer *layer = [[LOTLayer alloc] initWithJSON:layerJSON withCompBounds:_bounds withFramerate:_framerate]; + [layers addObject:layer]; + modelMap[layer.layerID] = layer; + if (layer.referenceID) { + referenceMap[layer.referenceID] = layer; + } + } + + _referenceIDMap = referenceMap; + _modelMap = modelMap; + _layers = layers; +} + +- (LOTLayer *)layerModelForID:(NSNumber *)layerID { + return _modelMap[layerID]; +} + +- (LOTLayer *)layerForReferenceID:(NSString *)referenceID { + return _referenceIDMap[referenceID]; +} + +@end diff --git a/lottie-ios/Classes/Models/LOTModels.h b/lottie-ios/Classes/Models/LOTModels.h index b35f0c3aa5..8d2ec9e1da 100644 --- a/lottie-ios/Classes/Models/LOTModels.h +++ b/lottie-ios/Classes/Models/LOTModels.h @@ -28,5 +28,7 @@ #import "LOTShapeStroke.h" #import "LOTShapeTransform.h" #import "LOTShapeTrimPath.h" +#import "LOTLayerGroup.h" +#import "LOTAsset.h" #endif /* LOTModels_h */ diff --git a/lottie-ios/Classes/Private/LOTAnimationView.m b/lottie-ios/Classes/Private/LOTAnimationView.m index a9dd38aaa8..9645b2249d 100644 --- a/lottie-ios/Classes/Private/LOTAnimationView.m +++ b/lottie-ios/Classes/Private/LOTAnimationView.m @@ -14,19 +14,19 @@ #import "LOTAnimationView_Internal.h" #import "LOTAnimationCache.h" -const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0; - @implementation LOTAnimationState { BOOL _needsAnimationUpdate; BOOL _animationIsPlaying; BOOL _playFromBeginning; CFTimeInterval _previousLocalTime; CGFloat _animatedProgress; + NSNumber *_framerate; } -- (id)initWithDuration:(CGFloat)duration layer:(CALayer *)layer{ +- (id)initWithDuration:(CGFloat)duration layer:(CALayer *)layer frameRate:(NSNumber *)framerate { self = [super init]; if (self) { + _framerate = framerate; _layer = layer; _needsAnimationUpdate = NO; _animationIsPlaying = NO; @@ -117,7 +117,7 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0; } _animatedProgress = animatedProgress > 1 ? fmod(animatedProgress, 1) : MAX(animatedProgress, 0); _animationIsPlaying = NO; - CFTimeInterval offset = _animatedProgress == 1 ? _animationDuration - singleFrameTimeValue : _animatedProgress * _animationDuration; + CFTimeInterval offset = _animatedProgress == 1 ? _animationDuration - LOT_singleFrameTimeValue : _animatedProgress * _animationDuration; CFTimeInterval clock = CACurrentMediaTime(); [self updateAnimationLayerClockTime:clock timeOffset:offset]; } @@ -163,8 +163,8 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0; - (void)logStats:(NSString *)logName { CFTimeInterval localTime = [_layer convertTime:CACurrentMediaTime() fromLayer:nil]; - NSLog(@"LOTAnimationState %@ || Is Playing %@ || Duration %f || Speed %lf || Progress %lf || Local Time %lf || ", - logName, (_animationIsPlaying ? @"YES" : @"NO"), self.animationDuration, _layer.speed, self.animatedProgress, localTime); + NSLog(@"LOTAnimationState %@ || Is Playing %@ || Duration %f || Speed %lf || Progress %lf || Local Time %lf || Frame %i ", + logName, (_animationIsPlaying ? @"YES" : @"NO"), self.animationDuration, _layer.speed, self.animatedProgress, localTime, (int)(localTime * _framerate.integerValue)); } @end @@ -231,7 +231,7 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0; [self _initializeAnimationContainer]; [self _setupWithSceneModel:laScene restoreAnimationState:NO]; } else { - _animationState = [[LOTAnimationState alloc] initWithDuration:singleFrameTimeValue layer:nil]; + _animationState = [[LOTAnimationState alloc] initWithDuration:LOT_singleFrameTimeValue layer:nil frameRate:@1]; dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ NSData *animationData = [NSData dataWithContentsOfURL:url]; if (!animationData) { @@ -291,7 +291,7 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0; _sceneModel = model; [self _buildSubviewsFromModel]; LOTAnimationState *oldState = _animationState; - _animationState = [[LOTAnimationState alloc] initWithDuration:_sceneModel.timeDuration layer:_animationContainer]; + _animationState = [[LOTAnimationState alloc] initWithDuration:_sceneModel.timeDuration layer:_animationContainer frameRate:_sceneModel.framerate]; if (restoreAnimation && oldState) { [self setLoopAnimation:oldState.loopAnimation]; @@ -331,11 +331,11 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0; NSMutableDictionary *layerMap = [NSMutableDictionary dictionary]; NSMutableDictionary *layerNameMap = [NSMutableDictionary dictionary]; - NSArray *reversedItems = [[_sceneModel.layers reverseObjectEnumerator] allObjects]; + NSArray *reversedItems = [[_sceneModel.layerGroup.layers reverseObjectEnumerator] allObjects]; LOTLayerView *maskedLayer = nil; for (LOTLayer *layer in reversedItems) { - LOTLayerView *layerView = [[LOTLayerView alloc] initWithModel:layer inComposition:_sceneModel]; + LOTLayerView *layerView = [[LOTLayerView alloc] initWithModel:layer inLayerGroup:_sceneModel.layerGroup]; layerMap[layer.layerID] = layerView; layerNameMap[layer.layerName] = layerView; if (maskedLayer) { diff --git a/lottie-ios/Classes/Private/LOTAnimationView_Internal.h b/lottie-ios/Classes/Private/LOTAnimationView_Internal.h index 28a04223df..ef3ccdc209 100644 --- a/lottie-ios/Classes/Private/LOTAnimationView_Internal.h +++ b/lottie-ios/Classes/Private/LOTAnimationView_Internal.h @@ -16,7 +16,7 @@ typedef enum : NSUInteger { @interface LOTAnimationState : NSObject -- (_Nonnull instancetype)initWithDuration:(CGFloat)duration layer:( CALayer * _Nullable)layer; +- (_Nonnull instancetype)initWithDuration:(CGFloat)duration layer:( CALayer * _Nullable)layer framerate:(NSNumber *)framerate; - (void)setAnimationIsPlaying:(BOOL)animationIsPlaying; - (void)setAnimationDoesLoop:(BOOL)loopAnimation;