lottie-ios 3.4.4 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/.gitattributes +1 -0
  2. package/.github/workflows/main.yml +7 -7
  3. package/Gemfile.lock +1 -1
  4. package/Lottie.xcodeproj/project.pbxproj +286 -68
  5. package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +18 -0
  6. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  7. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +3 -24
  8. package/Package.swift +2 -2
  9. package/README.md +10 -3
  10. package/Rakefile +1 -1
  11. package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +6 -9
  12. package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +42 -3
  13. package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +5 -17
  14. package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +25 -17
  15. package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +2 -2
  16. package/Sources/Private/CoreAnimation/Animations/OpacityAnimation.swift +1 -1
  17. package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +9 -20
  18. package/Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift +39 -25
  19. package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +13 -32
  20. package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +4 -4
  21. package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +13 -13
  22. package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +4 -4
  23. package/Sources/Private/CoreAnimation/Extensions/KeyframeGroup+exactlyOneKeyframe.swift +4 -12
  24. package/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift +222 -0
  25. package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +1 -1
  26. package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +8 -6
  27. package/Sources/Private/CoreAnimation/Layers/GradientRenderLayer.swift +13 -10
  28. package/Sources/Private/CoreAnimation/Layers/InfiniteOpaqueAnimationLayer.swift +56 -0
  29. package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +1 -1
  30. package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +2 -3
  31. package/Sources/Private/CoreAnimation/Layers/RepeaterLayer.swift +9 -9
  32. package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +9 -3
  33. package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +7 -18
  34. package/Sources/Private/CoreAnimation/ValueProviderStore.swift +2 -3
  35. package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +5 -5
  36. package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +3 -3
  37. package/Sources/Private/MainThread/LayerContainers/CompLayers/SolidCompositionLayer.swift +2 -2
  38. package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +7 -6
  39. package/Sources/Private/MainThread/LayerContainers/Utility/InvertedMatteLayer.swift +1 -3
  40. package/Sources/Private/MainThread/LayerContainers/Utility/LayerTransformNode.swift +10 -10
  41. package/Sources/Private/MainThread/NodeRenderSystem/Extensions/ItemsExtension.swift +7 -0
  42. package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/GroupInterpolator.swift +2 -2
  43. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/RoundedCornersNode.swift +85 -0
  44. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +4 -4
  45. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +11 -12
  46. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientStrokeRenderer.swift +1 -1
  47. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift +10 -11
  48. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +1 -1
  49. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +2 -2
  50. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +5 -5
  51. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/RectNode.swift +3 -3
  52. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/StarNode.swift +9 -9
  53. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +14 -14
  54. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/FillNode.swift +2 -2
  55. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +3 -3
  56. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +10 -10
  57. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +14 -14
  58. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +11 -11
  59. package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +1 -1
  60. package/Sources/Private/Model/DotLottie/DotLottieAnimation.swift +52 -0
  61. package/Sources/Private/Model/DotLottie/DotLottieConfiguration.swift +15 -0
  62. package/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift +73 -0
  63. package/Sources/Private/Model/DotLottie/DotLottieManifest.swift +53 -0
  64. package/Sources/Private/Model/DotLottie/DotLottieUtils.swift +58 -0
  65. package/Sources/Private/Model/DotLottie/Zip/Data+Compression.swift +134 -0
  66. package/Sources/Private/Model/DotLottie/Zip/Data+Serialization.swift +87 -0
  67. package/Sources/Private/Model/DotLottie/Zip/FileManager+ZIP.swift +130 -0
  68. package/Sources/Private/Model/DotLottie/Zip/ZipArchive.swift +474 -0
  69. package/Sources/Private/Model/DotLottie/Zip/ZipEntry+Serialization.swift +189 -0
  70. package/Sources/Private/Model/DotLottie/Zip/ZipEntry+ZIP64.swift +179 -0
  71. package/Sources/Private/Model/DotLottie/Zip/ZipEntry.swift +227 -0
  72. package/Sources/Private/Model/Extensions/Bundle.swift +26 -0
  73. package/Sources/Private/Model/Keyframes/KeyframeData.swift +12 -12
  74. package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +9 -2
  75. package/Sources/Private/Model/Layers/LayerModel.swift +1 -1
  76. package/Sources/Private/Model/Layers/PreCompLayerModel.swift +3 -3
  77. package/Sources/Private/Model/Layers/TextLayerModel.swift +1 -1
  78. package/Sources/Private/Model/Objects/DashPattern.swift +2 -2
  79. package/Sources/Private/Model/Objects/Mask.swift +10 -8
  80. package/Sources/Private/Model/Objects/Transform.swift +39 -35
  81. package/Sources/Private/Model/ShapeItems/Ellipse.swift +6 -6
  82. package/Sources/Private/Model/ShapeItems/Fill.swift +6 -6
  83. package/Sources/Private/Model/ShapeItems/GradientFill.swift +15 -15
  84. package/Sources/Private/Model/ShapeItems/GradientStroke.swift +19 -19
  85. package/Sources/Private/Model/ShapeItems/Rectangle.swift +9 -9
  86. package/Sources/Private/Model/ShapeItems/Repeater.swift +37 -32
  87. package/Sources/Private/Model/ShapeItems/RoundedCorners.swift +47 -0
  88. package/Sources/Private/Model/ShapeItems/ShapeItem.swift +4 -0
  89. package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +34 -28
  90. package/Sources/Private/Model/ShapeItems/Star.swift +21 -21
  91. package/Sources/Private/Model/ShapeItems/Stroke.swift +10 -10
  92. package/Sources/Private/Model/ShapeItems/Trim.swift +9 -9
  93. package/Sources/Private/Model/Text/Font.swift +1 -1
  94. package/Sources/Private/Model/Text/TextAnimator.swift +33 -33
  95. package/Sources/Private/Model/Text/TextDocument.swift +8 -8
  96. package/Sources/Private/RootAnimationLayer.swift +4 -4
  97. package/Sources/Private/Utility/Debugging/LayerDebugging.swift +12 -18
  98. package/Sources/Private/Utility/Extensions/AnimationKeypathExtension.swift +2 -2
  99. package/Sources/Private/Utility/Extensions/CGColor+RGB.swift +12 -7
  100. package/Sources/Private/Utility/Interpolatable/InterpolatableExtensions.swift +1 -1
  101. package/Sources/Private/Utility/Interpolatable/KeyframeGroup+Extensions.swift +4 -4
  102. package/Sources/Private/Utility/Primitives/BezierPathRoundExtension.swift +147 -0
  103. package/Sources/Private/Utility/Primitives/ColorExtension.swift +8 -11
  104. package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +22 -22
  105. package/Sources/{Private/Model/Animation.swift → Public/Animation/LottieAnimation.swift} +8 -8
  106. package/Sources/Public/Animation/{AnimationPublic.swift → LottieAnimationHelpers.swift} +62 -27
  107. package/Sources/Public/Animation/{AnimationView.swift → LottieAnimationView.swift} +122 -26
  108. package/Sources/Public/Animation/LottieAnimationViewInitializers.swift +222 -0
  109. package/Sources/Public/AnimationCache/AnimationCacheProvider.swift +4 -4
  110. package/Sources/Public/AnimationCache/DefaultAnimationCache.swift +54 -0
  111. package/Sources/Public/AnimationCache/LRUAnimationCache.swift +4 -52
  112. package/Sources/Public/AnimationCache/LottieAnimationCache.swift +15 -0
  113. package/Sources/Public/DotLottie/Cache/DotLottieCache.swift +53 -0
  114. package/Sources/Public/DotLottie/Cache/DotLottieCacheProvider.swift +23 -0
  115. package/Sources/Public/DotLottie/DotLottieFile.swift +161 -0
  116. package/Sources/Public/DotLottie/DotLottieFileHelpers.swift +265 -0
  117. package/Sources/Public/DynamicProperties/AnimationKeypath.swift +3 -3
  118. package/Sources/Public/DynamicProperties/AnyValueProvider.swift +2 -2
  119. package/Sources/Public/DynamicProperties/ValueProviders/ColorValueProvider.swift +10 -10
  120. package/Sources/Public/DynamicProperties/ValueProviders/FloatValueProvider.swift +4 -4
  121. package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +5 -5
  122. package/Sources/Public/DynamicProperties/ValueProviders/PointValueProvider.swift +2 -2
  123. package/Sources/Public/DynamicProperties/ValueProviders/SizeValueProvider.swift +2 -2
  124. package/Sources/Public/FontProvider/AnimationFontProvider.swift +1 -1
  125. package/Sources/Public/ImageProvider/AnimationImageProvider.swift +2 -2
  126. package/Sources/Public/Keyframes/Interpolatable.swift +17 -17
  127. package/Sources/Public/Keyframes/Keyframe.swift +10 -10
  128. package/Sources/Public/LottieConfiguration.swift +25 -7
  129. package/Sources/Public/Primitives/{Color.swift → LottieColor.swift} +3 -3
  130. package/Sources/Public/Primitives/Vectors.swift +4 -4
  131. package/Sources/Public/TextProvider/AnimationTextProvider.swift +1 -1
  132. package/Sources/Public/iOS/AnimatedButton.swift +1 -1
  133. package/Sources/Public/iOS/AnimatedControl.swift +6 -6
  134. package/Sources/Public/iOS/AnimatedSwitch.swift +1 -1
  135. package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +8 -8
  136. package/Sources/Public/iOS/{AnimationViewBase.swift → LottieAnimationViewBase.swift} +4 -4
  137. package/Sources/Public/iOS/UIColorExtension.swift +2 -2
  138. package/Sources/Public/macOS/{AnimationViewBase.macOS.swift → LottieAnimationViewBase.macOS.swift} +4 -4
  139. package/Tests/AnimationCacheProviderTests.swift +40 -0
  140. package/Tests/AnimationKeypathTests.swift +20 -13
  141. package/Tests/AnimationViewTests.swift +64 -0
  142. package/Tests/AutomaticEngineTests.swift +11 -2
  143. package/Tests/ParsingTests.swift +4 -2
  144. package/Tests/PerformanceTests.swift +9 -9
  145. package/Tests/SnapshotConfiguration.swift +7 -7
  146. package/Tests/SnapshotTests.swift +57 -27
  147. package/Tests/ValueProvidersTests.swift +9 -6
  148. package/lottie-ios.podspec +4 -4
  149. package/package.json +2 -2
  150. package/script/test-carthage/Cartfile +1 -1
  151. package/script/test-carthage/CarthageTest/ViewController.swift +1 -1
  152. package/script/test-carthage/CarthageTest-macOS/ViewController.swift +1 -1
  153. package/Sources/Private/CoreAnimation/Extensions/Keyframes+combinedIfPossible.swift +0 -154
  154. package/Sources/Public/Animation/AnimationViewInitializers.swift +0 -109
  155. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -1
  156. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~7IO4FqH8-VUsSfuA0_wMGUgfGdV7MwzpkzjwWbiB50jXZKQRHtU4G0A7ZXTvsR4mDdrWiawpNC_eriOALfZ7Og== +0 -0
  157. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~ClRW5-6rvrgZHHbrPS1VEREaxelpVcKlERPzSa3f2rtFNXdoqATxFCsPge3a_nO4mhhtpmTmbYvyfI-obAu8Qg== +0 -0
  158. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Jr2dFGcJc1188nMoMha82z9wM99lCLm4MKzhjfVVjIxKeCZVGWGZH3HgJFNkTpozdk5p1u5o91dCiY4-cR1Zhg== +0 -0
  159. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~MBDeCFoahVzzmtSQrVhhy9VMJV6CmcnUkFya_qwe0XsMFscmY2nS8dxrTEYkY16sH68sEH7WVCCzTuW1z1Hocw== +0 -1
  160. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~U4plJajEDM_uSZdglhDyj6gQO63mbeKxYP9X94aIaOtL0yErtfQnGz5SgsqQ0ToSZcJj6Ao9Wx-nesZVwBTRuw== +0 -0
  161. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~UsLY5O-vDMEHEe3bF8XJvkKkYxdsKlIytgJW7zgNuetw53fG3SssfZiiMfbuYnOtvvvYBXTwpbz07V6Czp029Q== +0 -0
  162. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~cpg4cb7H0TaehHy4a-xINJMFfBM2_AEHal_0tIX8ymNVJPsjlCysi3-Cad0Ca_SvuGwVM7ONF55OBUuC9YKZvA== +0 -0
  163. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~cuHjdTCuciVumvEpvozxwDj2wAdgWe13bzd1pUAGN45-WOgY0kIid9aUlBX675OnS-xNEc_pyQWo0RO1dKAjcw== +0 -0
  164. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~f_-bfn-KRHHFg39_MtwgBulEAuWH6F05yqGYydXhil6kqZ51eAoRX6tsiqOr0Oa6eL3dK1tcCBD1bWX5orCZhw== +0 -1
  165. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~jdIx7vWS6ej1cqYcbCS4KyZErSMF13ELR95YwClVc98tIXcsglh7KuGvI1gIxEPDtPXQpfC3XijIAGn1quL8Dw== +0 -0
  166. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~lz3e0YeBa8TvMBSSymToh--gc6zznUIdH2jO0AJ4so5OPNdw6wpYmJebhaENGsRoD3beUXvlyD5f7_WeZrzyNQ== +0 -0
  167. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~u_5dWbliYJ__YkyUCDFjdxiFds9M8Epr_RvbU1rIRCbBQdhRJ_TUBXXcL_Qq-wVp4umNLTOzud4OpQItSpO6Rg== +0 -0
  168. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~v-YGzhC2l_icsAsyp1XAbEWYwxNook-rARAWlVZINioEsgT9LGvhg2oh78nYqoeH78m1fihr5HCcGNfF7SQj0g== +0 -0
  169. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -0
  170. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~7IO4FqH8-VUsSfuA0_wMGUgfGdV7MwzpkzjwWbiB50jXZKQRHtU4G0A7ZXTvsR4mDdrWiawpNC_eriOALfZ7Og== +0 -0
  171. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~ClRW5-6rvrgZHHbrPS1VEREaxelpVcKlERPzSa3f2rtFNXdoqATxFCsPge3a_nO4mhhtpmTmbYvyfI-obAu8Qg== +0 -0
  172. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Jr2dFGcJc1188nMoMha82z9wM99lCLm4MKzhjfVVjIxKeCZVGWGZH3HgJFNkTpozdk5p1u5o91dCiY4-cR1Zhg== +0 -0
  173. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~MBDeCFoahVzzmtSQrVhhy9VMJV6CmcnUkFya_qwe0XsMFscmY2nS8dxrTEYkY16sH68sEH7WVCCzTuW1z1Hocw== +0 -0
  174. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~U4plJajEDM_uSZdglhDyj6gQO63mbeKxYP9X94aIaOtL0yErtfQnGz5SgsqQ0ToSZcJj6Ao9Wx-nesZVwBTRuw== +0 -0
  175. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~UsLY5O-vDMEHEe3bF8XJvkKkYxdsKlIytgJW7zgNuetw53fG3SssfZiiMfbuYnOtvvvYBXTwpbz07V6Czp029Q== +0 -0
  176. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~cpg4cb7H0TaehHy4a-xINJMFfBM2_AEHal_0tIX8ymNVJPsjlCysi3-Cad0Ca_SvuGwVM7ONF55OBUuC9YKZvA== +0 -0
  177. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~cuHjdTCuciVumvEpvozxwDj2wAdgWe13bzd1pUAGN45-WOgY0kIid9aUlBX675OnS-xNEc_pyQWo0RO1dKAjcw== +0 -0
  178. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~f_-bfn-KRHHFg39_MtwgBulEAuWH6F05yqGYydXhil6kqZ51eAoRX6tsiqOr0Oa6eL3dK1tcCBD1bWX5orCZhw== +0 -0
  179. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~jdIx7vWS6ej1cqYcbCS4KyZErSMF13ELR95YwClVc98tIXcsglh7KuGvI1gIxEPDtPXQpfC3XijIAGn1quL8Dw== +0 -0
  180. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~lz3e0YeBa8TvMBSSymToh--gc6zznUIdH2jO0AJ4so5OPNdw6wpYmJebhaENGsRoD3beUXvlyD5f7_WeZrzyNQ== +0 -0
  181. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~u_5dWbliYJ__YkyUCDFjdxiFds9M8Epr_RvbU1rIRCbBQdhRJ_TUBXXcL_Qq-wVp4umNLTOzud4OpQItSpO6Rg== +0 -0
  182. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~v-YGzhC2l_icsAsyp1XAbEWYwxNook-rARAWlVZINioEsgT9LGvhg2oh78nYqoeH78m1fihr5HCcGNfF7SQj0g== +0 -0
  183. package/Tests/Artifacts/LottieTests.xcresult/Info.plist +0 -29
@@ -19,6 +19,24 @@
19
19
  "version": "0.7.0"
20
20
  }
21
21
  },
22
+ {
23
+ "package": "AirbnbSwift",
24
+ "repositoryURL": "https://github.com/airbnb/swift",
25
+ "state": {
26
+ "branch": null,
27
+ "revision": "7884f265499752cc5eccaa9eba08b4a2f8b73357",
28
+ "version": null
29
+ }
30
+ },
31
+ {
32
+ "package": "swift-argument-parser",
33
+ "repositoryURL": "https://github.com/apple/swift-argument-parser",
34
+ "state": {
35
+ "branch": null,
36
+ "revision": "fddd1c00396eed152c45a46bea9f47b98e59301d",
37
+ "version": "1.2.0"
38
+ }
39
+ },
22
40
  {
23
41
  "package": "swift-snapshot-testing",
24
42
  "repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git",
@@ -5,33 +5,12 @@
5
5
  version = "2.0">
6
6
  <Breakpoints>
7
7
  <BreakpointProxy
8
- BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
8
+ BreakpointExtensionID = "Xcode.Breakpoint.SwiftErrorBreakpoint">
9
9
  <BreakpointContent
10
- uuid = "8C528A5F-B345-4B34-BD67-A167DC41704A"
11
- shouldBeEnabled = "Yes"
12
- ignoreCount = "0"
13
- continueAfterRunningActions = "No"
14
- filePath = "Sources/Private/CoreAnimation/Animations/VisibilityAnimation.swift"
15
- startingColumnNumber = "9223372036854775807"
16
- endingColumnNumber = "9223372036854775807"
17
- startingLineNumber = "44"
18
- endingLineNumber = "44">
19
- </BreakpointContent>
20
- </BreakpointProxy>
21
- <BreakpointProxy
22
- BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
23
- <BreakpointContent
24
- uuid = "90B95B81-4B28-4BCD-AE7B-59ED8AA81AC1"
10
+ uuid = "C6EE3985-FE51-481D-807F-F4B9BE9FB067"
25
11
  shouldBeEnabled = "No"
26
12
  ignoreCount = "0"
27
- continueAfterRunningActions = "No"
28
- filePath = "Sources/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.swift"
29
- startingColumnNumber = "9223372036854775807"
30
- endingColumnNumber = "9223372036854775807"
31
- startingLineNumber = "49"
32
- endingLineNumber = "49"
33
- landmarkName = "update(frame:)"
34
- landmarkType = "7">
13
+ continueAfterRunningActions = "No">
35
14
  </BreakpointContent>
36
15
  </BreakpointProxy>
37
16
  </Breakpoints>
package/Package.swift CHANGED
@@ -1,8 +1,8 @@
1
- // swift-tools-version:5.3
1
+ // swift-tools-version:5.5
2
2
  import PackageDescription
3
3
 
4
4
  let package = Package(
5
5
  name: "Lottie",
6
6
  platforms: [.iOS("11.0"), .macOS("10.10"), .tvOS("11.0")],
7
7
  products: [.library(name: "Lottie", targets: ["Lottie"])],
8
- targets: [.target(name: "Lottie", path: "Sources")])
8
+ targets: [.target(name: "Lottie", path: "Sources")])
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Lottie for iOS
2
2
  [![Version](https://img.shields.io/cocoapods/v/lottie-ios.svg?style=flat)](https://cocoapods.org/pods/lottie-ios) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![SwiftPM](https://img.shields.io/badge/SPM-supported-DE5C43.svg?style=flat)](https://swift.org/package-manager/) [![License](https://img.shields.io/cocoapods/l/lottie-ios.svg?style=flat)](https://cocoapods.org/pods/lottie-ios) [![Platform](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fairbnb%2Flottie-ios%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/airbnb/lottie-ios) [![Swift Versions](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fairbnb%2Flottie-ios%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/airbnb/lottie-ios)
3
3
 
4
- **View documentation, FAQ, help, examples, and more at [airbnb.io/lottie](http://airbnb.io/lottie/)**
4
+ **View documentation, FAQ, help, examples, and more at [airbnb.io/lottie](https://airbnb.io/lottie/)**
5
5
 
6
- Lottie is a cross-platform library for iOS, macOS, tvOS, [Android](https://github.com/airbnb/lottie), and [Web](https://github.com/airbnb/lottie-web) that natively renders vector-based animations and art in realtime with minimal code.
6
+ Lottie is a cross-platform library for iOS, macOS, tvOS, [Android](https://github.com/airbnb/lottie-android), and [Web](https://github.com/airbnb/lottie-web) that natively renders vector-based animations and art in realtime with minimal code.
7
7
 
8
8
  Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with [bodymovin](https://github.com/bodymovin/bodymovin), Sketch with [Lottie Sketch Export](https://github.com/buba447/Lottie-Sketch-Export), and from [Haiku](https://www.haiku.ai).
9
9
 
10
- Designers can create **and ship** beautiful animations without an engineer painstakingly recreating it by hand.
10
+ Designers can create **and ship** beautiful animations without an engineer painstakingly recreating them by hand.
11
11
  Since the animation is backed by JSON they are extremely small in size but can be large in complexity!
12
12
  Animations can be played, resized, looped, sped up, slowed down, reversed, and even interactively scrubbed.
13
13
  Lottie can play or loop just a portion of the animation as well, the possibilities are endless!
@@ -75,6 +75,13 @@ We always appreciate contributions from the community. To make changes to the pr
75
75
  - unit tests and snapshot tests (for iOS, must be run on an iPhone 8 simulator)
76
76
  - an Example iOS app that lets you browse and test over 100 sample animations included in the repo
77
77
 
78
+ To reduce the size of the repository, snapshot images are stored using [Git Large File Storage](https://git-lfs.github.com/). Before running the snapshot tests, you'll need to install Git LFS:
79
+
80
+ ```bash
81
+ $ brew install git-lfs
82
+ $ git lfs install
83
+ ```
84
+
78
85
  All pull requests with new features or bug fixes that affect how animations render should include snapshot test cases that validate the included changes.
79
86
  - To add a new sample animation to the snapshot testing suite, you can add the `.json` file to `Tests/Samples`. Re-run the snapshot tests to generate the new snapshot image files.
80
87
  - To update existing snapshots after making changes, you can set `isRecording = true` in `SnapshotTests.swift` and then re-run the snapshot tests.
package/Rakefile CHANGED
@@ -136,7 +136,7 @@ def formatTool(command)
136
136
  url: "https://github.com/airbnb/swift",
137
137
  // Since we don't have a Package.resolved for this, we need to reference a specific commit
138
138
  // so changes to the style guide don't cause this repo's checks to start failing.
139
- .revision("cec29280c35dd6eccba415fa3bfc24c819eae887")))
139
+ .revision("7884f265499752cc5eccaa9eba08b4a2f8b73357")))
140
140
  #endif
141
141
  EOC
142
142
 
@@ -44,8 +44,7 @@ extension CALayer {
44
44
  keyframes: ContiguousArray<Keyframe<KeyframeValue>>,
45
45
  value keyframeValueMapping: (KeyframeValue) throws -> ValueRepresentation,
46
46
  context: LayerAnimationContext)
47
- throws
48
- -> CAAnimation?
47
+ throws -> CAAnimation?
49
48
  {
50
49
  guard !keyframes.isEmpty else { return nil }
51
50
 
@@ -82,13 +81,12 @@ extension CALayer {
82
81
 
83
82
  /// A `CAAnimation` that applies the custom value from the `AnyValueProvider`
84
83
  /// registered for this specific property's `AnimationKeypath`,
85
- /// if one has been registered using `AnimationView.setValueProvider(_:keypath:)`.
84
+ /// if one has been registered using `LottieAnimationView.setValueProvider(_:keypath:)`.
86
85
  @nonobjc
87
86
  private func customizedAnimation<ValueRepresentation>(
88
87
  for property: LayerProperty<ValueRepresentation>,
89
88
  context: LayerAnimationContext)
90
- throws
91
- -> CAPropertyAnimation?
89
+ throws -> CAPropertyAnimation?
92
90
  {
93
91
  guard
94
92
  let customizableProperty = property.customizableProperty,
@@ -162,8 +160,7 @@ extension CALayer {
162
160
  animationSegments: [[Keyframe<KeyframeValue>]],
163
161
  value keyframeValueMapping: (KeyframeValue) throws -> ValueRepresentation,
164
162
  context: LayerAnimationContext)
165
- throws
166
- -> CAAnimationGroup
163
+ throws -> CAAnimationGroup
167
164
  {
168
165
  // Build the `CAKeyframeAnimation` for each segment of keyframes
169
166
  // with the same `CAAnimationCalculationMode`.
@@ -233,8 +230,8 @@ extension CALayer {
233
230
  NSNumber(value: Float(context.progressTime(for: keyframeModel.time)))
234
231
  }
235
232
 
236
- var timingFunctions = self.timingFunctions(for: keyframes)
237
- let calculationMode = self.calculationMode(for: keyframes)
233
+ var timingFunctions = timingFunctions(for: keyframes)
234
+ let calculationMode = calculationMode(for: keyframes)
238
235
 
239
236
  let animation = CAKeyframeAnimation(keyPath: property.caLayerKeypath)
240
237
 
@@ -10,14 +10,24 @@ extension CAShapeLayer {
10
10
  for customPath: KeyframeGroup<BezierPath>,
11
11
  context: LayerAnimationContext,
12
12
  pathMultiplier: PathMultiplier = 1,
13
- transformPath: (CGPath) -> CGPath = { $0 })
13
+ transformPath: (CGPath) -> CGPath = { $0 },
14
+ roundedCorners: RoundedCorners? = nil)
14
15
  throws
15
16
  {
17
+ let combinedKeyframes = try BezierPathKeyframe.combining(
18
+ path: customPath,
19
+ cornerRadius: roundedCorners?.radius)
20
+
16
21
  try addAnimation(
17
22
  for: .path,
18
- keyframes: customPath.keyframes,
23
+ keyframes: combinedKeyframes.keyframes,
19
24
  value: { pathKeyframe in
20
- transformPath(pathKeyframe.cgPath().duplicated(times: pathMultiplier))
25
+ var path = pathKeyframe.path
26
+ if let cornerRadius = pathKeyframe.cornerRadius {
27
+ path = path.roundCorners(radius: cornerRadius.cgFloatValue)
28
+ }
29
+
30
+ return transformPath(path.cgPath().duplicated(times: pathMultiplier))
21
31
  },
22
32
  context: context)
23
33
  }
@@ -39,3 +49,32 @@ extension CGPath {
39
49
  return cgPath
40
50
  }
41
51
  }
52
+
53
+ // MARK: - BezierPathKeyframe
54
+
55
+ /// Data that represents how to render a bezier path at a specific point in time
56
+ struct BezierPathKeyframe {
57
+ let path: BezierPath
58
+ let cornerRadius: LottieVector1D?
59
+
60
+ /// Creates a single array of animatable keyframes from the given sets of keyframes
61
+ /// that can have different counts / timing parameters
62
+ static func combining(
63
+ path: KeyframeGroup<BezierPath>,
64
+ cornerRadius: KeyframeGroup<LottieVector1D>?) throws
65
+ -> KeyframeGroup<BezierPathKeyframe>
66
+ {
67
+ guard
68
+ let cornerRadius = cornerRadius,
69
+ cornerRadius.keyframes.contains(where: { $0.value.cgFloatValue > 0 })
70
+ else {
71
+ return path.map { path in
72
+ BezierPathKeyframe(path: path, cornerRadius: nil)
73
+ }
74
+ }
75
+
76
+ return Keyframes.combined(
77
+ path, cornerRadius,
78
+ makeCombinedResult: BezierPathKeyframe.init)
79
+ }
80
+ }
@@ -14,7 +14,7 @@ extension CAShapeLayer {
14
14
  {
15
15
  try addAnimation(
16
16
  for: .path,
17
- keyframes: ellipse.combinedKeyframes(context: context).keyframes,
17
+ keyframes: ellipse.combinedKeyframes().keyframes,
18
18
  value: { keyframe in
19
19
  BezierPath.ellipse(
20
20
  size: keyframe.size.sizeValue,
@@ -30,26 +30,14 @@ extension CAShapeLayer {
30
30
  extension Ellipse {
31
31
  /// Data that represents how to render an ellipse at a specific point in time
32
32
  struct Keyframe {
33
- let size: Vector3D
34
- let position: Vector3D
33
+ let size: LottieVector3D
34
+ let position: LottieVector3D
35
35
  }
36
36
 
37
37
  /// Creates a single array of animatable keyframes from the separate arrays of keyframes in this Ellipse
38
- func combinedKeyframes(context: LayerAnimationContext) throws-> KeyframeGroup<Ellipse.Keyframe> {
39
- let combinedKeyframes = Keyframes.combinedIfPossible(
38
+ func combinedKeyframes() throws -> KeyframeGroup<Ellipse.Keyframe> {
39
+ Keyframes.combined(
40
40
  size, position,
41
41
  makeCombinedResult: Ellipse.Keyframe.init)
42
-
43
- if let combinedKeyframes = combinedKeyframes {
44
- return combinedKeyframes
45
- } else {
46
- // If we weren't able to combine all of the keyframes, we have to take the timing values
47
- // from one property and use a fixed value for the other properties.
48
- return try size.map { sizeValue in
49
- Keyframe(
50
- size: sizeValue,
51
- position: try position.exactlyOneKeyframe(context: context, description: "ellipse position"))
52
- }
53
- }
54
42
  }
55
43
  }
@@ -7,8 +7,8 @@ import QuartzCore
7
7
 
8
8
  /// A `ShapeItem` that represents a gradient
9
9
  protocol GradientShapeItem: OpacityAnimationModel {
10
- var startPoint: KeyframeGroup<Vector3D> { get }
11
- var endPoint: KeyframeGroup<Vector3D> { get }
10
+ var startPoint: KeyframeGroup<LottieVector3D> { get }
11
+ var endPoint: KeyframeGroup<LottieVector3D> { get }
12
12
  var gradientType: GradientType { get }
13
13
  var numberOfColors: Int { get }
14
14
  var colors: KeyframeGroup<[Double]> { get }
@@ -111,23 +111,31 @@ extension GradientRenderLayer {
111
111
  private func addRadialGradientAnimations(for gradient: GradientShapeItem, context: LayerAnimationContext) throws {
112
112
  type = .radial
113
113
 
114
- // To draw the correct gradients, we have to derive a custom `endPoint`
115
- // relative to the `startPoint` value. Since calculating the `endPoint`
116
- // at any given time requires knowing the current `startPoint`,
117
- // we can't allow them to animate separately.
118
- let absoluteStartPoint = try gradient.startPoint
119
- .exactlyOneKeyframe(context: context, description: "gradient startPoint").pointValue
120
-
121
- let absoluteEndPoint = try gradient.endPoint
122
- .exactlyOneKeyframe(context: context, description: "gradient endPoint").pointValue
114
+ let combinedKeyframes = Keyframes.combined(
115
+ gradient.startPoint, gradient.endPoint,
116
+ makeCombinedResult: { absoluteStartPoint, absoluteEndPoint -> (startPoint: CGPoint, endPoint: CGPoint) in
117
+ // Convert the absolute start / end points to the relative structure used by Core Animation
118
+ let relativeStartPoint = percentBasedPointInBounds(from: absoluteStartPoint.pointValue)
119
+ let radius = absoluteStartPoint.pointValue.distanceTo(absoluteEndPoint.pointValue)
120
+ let relativeEndPoint = percentBasedPointInBounds(
121
+ from: CGPoint(
122
+ x: absoluteStartPoint.x + radius,
123
+ y: absoluteStartPoint.y + radius))
124
+
125
+ return (startPoint: relativeStartPoint, endPoint: relativeEndPoint)
126
+ })
123
127
 
124
- startPoint = percentBasedPointInBounds(from: absoluteStartPoint)
128
+ try addAnimation(
129
+ for: .startPoint,
130
+ keyframes: combinedKeyframes.keyframes,
131
+ value: \.startPoint,
132
+ context: context)
125
133
 
126
- let radius = absoluteStartPoint.distanceTo(absoluteEndPoint)
127
- endPoint = percentBasedPointInBounds(
128
- from: CGPoint(
129
- x: absoluteStartPoint.x + radius,
130
- y: absoluteStartPoint.y + radius))
134
+ try addAnimation(
135
+ for: .endPoint,
136
+ keyframes: combinedKeyframes.keyframes,
137
+ value: \.endPoint,
138
+ context: context)
131
139
  }
132
140
  }
133
141
 
@@ -28,7 +28,7 @@ struct LayerProperty<ValueRepresentation: Equatable> {
28
28
  // MARK: - CustomizableProperty
29
29
 
30
30
  /// A description of how a `CALayer` property can be customized dynamically
31
- /// at runtime using `AnimationView.setValueProvider(_:keypath:)`
31
+ /// at runtime using `LottieAnimationView.setValueProvider(_:keypath:)`
32
32
  struct CustomizableProperty<ValueRepresentation> {
33
33
  /// The name that `AnimationKeypath`s can use to refer to this property
34
34
  /// - When building an animation for this property that will be applied
@@ -219,7 +219,7 @@ extension CustomizableProperty {
219
219
  .init(
220
220
  name: [.color],
221
221
  conversion: { typeErasedValue in
222
- guard let color = typeErasedValue as? Color else {
222
+ guard let color = typeErasedValue as? LottieColor else {
223
223
  return nil
224
224
  }
225
225
 
@@ -7,7 +7,7 @@ import QuartzCore
7
7
 
8
8
  protocol OpacityAnimationModel {
9
9
  /// The opacity animation to apply to a `CALayer`
10
- var opacity: KeyframeGroup<Vector1D> { get }
10
+ var opacity: KeyframeGroup<LottieVector1D> { get }
11
11
  }
12
12
 
13
13
  // MARK: - Transform + OpacityAnimationModel
@@ -9,12 +9,13 @@ extension CAShapeLayer {
9
9
  func addAnimations(
10
10
  for rectangle: Rectangle,
11
11
  context: LayerAnimationContext,
12
- pathMultiplier: PathMultiplier)
12
+ pathMultiplier: PathMultiplier,
13
+ roundedCorners: RoundedCorners?)
13
14
  throws
14
15
  {
15
16
  try addAnimation(
16
17
  for: .path,
17
- keyframes: try rectangle.combinedKeyframes(context: context).keyframes,
18
+ keyframes: try rectangle.combinedKeyframes(roundedCorners: roundedCorners).keyframes,
18
19
  value: { keyframe in
19
20
  BezierPath.rectangle(
20
21
  position: keyframe.position.pointValue,
@@ -31,28 +32,16 @@ extension CAShapeLayer {
31
32
  extension Rectangle {
32
33
  /// Data that represents how to render a rectangle at a specific point in time
33
34
  struct Keyframe {
34
- let size: Vector3D
35
- let position: Vector3D
36
- let cornerRadius: Vector1D
35
+ let size: LottieVector3D
36
+ let position: LottieVector3D
37
+ let cornerRadius: LottieVector1D
37
38
  }
38
39
 
39
40
  /// Creates a single array of animatable keyframes from the separate arrays of keyframes in this Rectangle
40
- func combinedKeyframes(context: LayerAnimationContext) throws-> KeyframeGroup<Rectangle.Keyframe> {
41
- let combinedKeyframes = Keyframes.combinedIfPossible(
41
+ func combinedKeyframes(roundedCorners: RoundedCorners?) throws -> KeyframeGroup<Rectangle.Keyframe> {
42
+ let cornerRadius = roundedCorners?.radius ?? cornerRadius
43
+ return Keyframes.combined(
42
44
  size, position, cornerRadius,
43
45
  makeCombinedResult: Rectangle.Keyframe.init)
44
-
45
- if let combinedKeyframes = combinedKeyframes {
46
- return combinedKeyframes
47
- } else {
48
- // If we weren't able to combine all of the keyframes, we have to take the timing values
49
- // from one property and use a fixed value for the other properties.
50
- return try size.map { sizeValue in
51
- Keyframe(
52
- size: sizeValue,
53
- position: try position.exactlyOneKeyframe(context: context, description: "rectangle position"),
54
- cornerRadius: try cornerRadius.exactlyOneKeyframe(context: context, description: "rectangle cornerRadius"))
55
- }
56
- }
57
46
  }
58
47
  }
@@ -9,23 +9,38 @@ extension CAShapeLayer {
9
9
  func addAnimations(
10
10
  for shape: ShapeItem,
11
11
  context: LayerAnimationContext,
12
- pathMultiplier: PathMultiplier) throws
12
+ pathMultiplier: PathMultiplier,
13
+ roundedCorners: RoundedCorners?) throws
13
14
  {
14
15
  switch shape {
15
16
  case let customShape as Shape:
16
- try addAnimations(for: customShape.path, context: context, pathMultiplier: pathMultiplier)
17
+ try addAnimations(
18
+ for: customShape.path,
19
+ context: context,
20
+ pathMultiplier: pathMultiplier,
21
+ roundedCorners: roundedCorners)
17
22
 
18
23
  case let combinedShape as CombinedShapeItem:
19
24
  try addAnimations(for: combinedShape, context: context, pathMultiplier: pathMultiplier)
25
+ try context.compatibilityAssert(roundedCorners == nil, """
26
+ Rounded corners support is not currently implemented for combined shape items
27
+ """)
20
28
 
21
29
  case let ellipse as Ellipse:
22
30
  try addAnimations(for: ellipse, context: context, pathMultiplier: pathMultiplier)
23
31
 
24
32
  case let rectangle as Rectangle:
25
- try addAnimations(for: rectangle, context: context, pathMultiplier: pathMultiplier)
33
+ try addAnimations(
34
+ for: rectangle,
35
+ context: context,
36
+ pathMultiplier: pathMultiplier,
37
+ roundedCorners: roundedCorners)
26
38
 
27
39
  case let star as Star:
28
40
  try addAnimations(for: star, context: context, pathMultiplier: pathMultiplier)
41
+ try context.compatibilityAssert(roundedCorners == nil, """
42
+ Rounded corners support is currently not implemented for polygon items
43
+ """)
29
44
 
30
45
  default:
31
46
  // None of the other `ShapeItem` subclasses draw a `path`
@@ -51,7 +66,7 @@ extension CAShapeLayer {
51
66
  /// Adds animations for `strokeStart` and `strokeEnd` from the given `Trim` object
52
67
  @nonobjc
53
68
  func addAnimations(for trim: Trim, context: LayerAnimationContext) throws -> PathMultiplier {
54
- let (strokeStartKeyframes, strokeEndKeyframes, pathMultiplier) = try trim.caShapeLayerKeyframes(context: context)
69
+ let (strokeStartKeyframes, strokeEndKeyframes, pathMultiplier) = try trim.caShapeLayerKeyframes()
55
70
 
56
71
  try addAnimation(
57
72
  for: .strokeStart,
@@ -87,11 +102,12 @@ extension Trim {
87
102
  /// The `strokeStart` and `strokeEnd` keyframes to apply to a `CAShapeLayer`,
88
103
  /// plus a `pathMultiplier` that should be applied to the layer's `path` so that
89
104
  /// trim values larger than 100% can be displayed properly.
90
- fileprivate func caShapeLayerKeyframes(context: LayerAnimationContext) throws
91
- -> (strokeStart: KeyframeGroup<Vector1D>, strokeEnd: KeyframeGroup<Vector1D>, pathMultiplier: PathMultiplier)
105
+ fileprivate func caShapeLayerKeyframes()
106
+ throws
107
+ -> (strokeStart: KeyframeGroup<LottieVector1D>, strokeEnd: KeyframeGroup<LottieVector1D>, pathMultiplier: PathMultiplier)
92
108
  {
93
- let strokeStart: KeyframeGroup<Vector1D>
94
- let strokeEnd: KeyframeGroup<Vector1D>
109
+ let strokeStart: KeyframeGroup<LottieVector1D>
110
+ let strokeEnd: KeyframeGroup<LottieVector1D>
95
111
 
96
112
  // CAShapeLayer requires strokeStart to be less than strokeEnd. This
97
113
  // isn't required by the Lottie schema, so some animations may have
@@ -123,14 +139,12 @@ extension Trim {
123
139
  var adjustedStrokeStart = KeyframeGroup(
124
140
  keyframes: try adjustKeyframesForTrimOffsets(
125
141
  strokeKeyframes: interpolatedStrokeStart,
126
- offsetKeyframes: interpolatedStrokeOffset,
127
- context: context))
142
+ offsetKeyframes: interpolatedStrokeOffset))
128
143
 
129
144
  var adjustedStrokeEnd = KeyframeGroup(
130
145
  keyframes: try adjustKeyframesForTrimOffsets(
131
146
  strokeKeyframes: interpolatedStrokeEnd,
132
- offsetKeyframes: interpolatedStrokeOffset,
133
- context: context))
147
+ offsetKeyframes: interpolatedStrokeOffset))
134
148
 
135
149
  // If maximum stroke value is larger than 100%, then we have to create copies of the path
136
150
  // so the total path length includes the maximum stroke
@@ -142,8 +156,8 @@ extension Trim {
142
156
  if minimumStrokeMultiplier < 0 {
143
157
  // Core Animation doesn't support negative stroke offsets, so we have to
144
158
  // shift all of the offset values up by the minimum
145
- adjustedStrokeStart = adjustedStrokeStart.map { Vector1D($0.value + (abs(minimumStrokeMultiplier) * 100.0)) }
146
- adjustedStrokeEnd = adjustedStrokeEnd.map { Vector1D($0.value + (abs(minimumStrokeMultiplier) * 100.0)) }
159
+ adjustedStrokeStart = adjustedStrokeStart.map { LottieVector1D($0.value + (abs(minimumStrokeMultiplier) * 100.0)) }
160
+ adjustedStrokeEnd = adjustedStrokeEnd.map { LottieVector1D($0.value + (abs(minimumStrokeMultiplier) * 100.0)) }
147
161
  }
148
162
 
149
163
  return (
@@ -164,8 +178,8 @@ extension Trim {
164
178
 
165
179
  for keyframeTime in keyframeTimes {
166
180
  guard
167
- let startAtTime = startInterpolator.value(frame: keyframeTime) as? Vector1D,
168
- let endAtTime = endInterpolator.value(frame: keyframeTime) as? Vector1D
181
+ let startAtTime = startInterpolator.value(frame: keyframeTime) as? LottieVector1D,
182
+ let endAtTime = endInterpolator.value(frame: keyframeTime) as? LottieVector1D
169
183
  else { continue }
170
184
 
171
185
  if startAtTime.cgFloatValue < endAtTime.cgFloatValue {
@@ -184,9 +198,9 @@ extension Trim {
184
198
  ///
185
199
  /// - Precondition: The keyframes must be interpolated using `KeyframeGroup.manuallyInterpolateKeyframes()`
186
200
  private func adjustKeyframesForTrimOffsets(
187
- strokeKeyframes: ContiguousArray<Keyframe<Vector1D>>,
188
- offsetKeyframes: ContiguousArray<Keyframe<Vector1D>>,
189
- context _: LayerAnimationContext) throws -> ContiguousArray<Keyframe<Vector1D>>
201
+ strokeKeyframes: ContiguousArray<Keyframe<LottieVector1D>>,
202
+ offsetKeyframes: ContiguousArray<Keyframe<LottieVector1D>>)
203
+ throws -> ContiguousArray<Keyframe<LottieVector1D>>
190
204
  {
191
205
  guard
192
206
  !strokeKeyframes.isEmpty,
@@ -196,7 +210,7 @@ extension Trim {
196
210
  }
197
211
 
198
212
  // Map each time to its corresponding stroke/offset keyframe
199
- var timeMap = [AnimationFrameTime: [Keyframe<Vector1D>?]]()
213
+ var timeMap = [AnimationFrameTime: [Keyframe<LottieVector1D>?]]()
200
214
  for stroke in strokeKeyframes {
201
215
  timeMap[stroke.time] = [stroke, nil]
202
216
  }
@@ -210,9 +224,9 @@ extension Trim {
210
224
  }
211
225
 
212
226
  // Each time will be mapped to a new, adjusted keyframe
213
- var output = ContiguousArray<Keyframe<Vector1D>>()
214
- var lastKeyframe: Keyframe<Vector1D>?
215
- var lastOffset: Keyframe<Vector1D>?
227
+ var output = ContiguousArray<Keyframe<LottieVector1D>>()
228
+ var lastKeyframe: Keyframe<LottieVector1D>?
229
+ var lastOffset: Keyframe<LottieVector1D>?
216
230
 
217
231
  for (time, values) in timeMap.sorted(by: { $0.0 < $1.0 }) {
218
232
  // Extract keyframe/offset associated with this timestamp
@@ -240,8 +254,8 @@ extension Trim {
240
254
  let adjustedValue = strokeValue + (offsetValue / 360 * 100)
241
255
 
242
256
  // The tangent values are all `nil` as the keyframes should have been manually interpolated
243
- let adjustedKeyframe = Keyframe<Vector1D>(
244
- value: Vector1D(adjustedValue),
257
+ let adjustedKeyframe = Keyframe<LottieVector1D>(
258
+ value: LottieVector1D(adjustedValue),
245
259
  time: time,
246
260
  isHold: currentKeyframe.isHold,
247
261
  inTangent: nil,
@@ -36,7 +36,7 @@ extension CAShapeLayer {
36
36
  {
37
37
  try addAnimation(
38
38
  for: .path,
39
- keyframes: try star.combinedKeyframes(context: context).keyframes,
39
+ keyframes: try star.combinedKeyframes().keyframes,
40
40
  value: { keyframe in
41
41
  BezierPath.star(
42
42
  position: keyframe.position.pointValue,
@@ -62,7 +62,7 @@ extension CAShapeLayer {
62
62
  {
63
63
  try addAnimation(
64
64
  for: .path,
65
- keyframes: try star.combinedKeyframes(context: context).keyframes,
65
+ keyframes: try star.combinedKeyframes().keyframes,
66
66
  value: { keyframe in
67
67
  BezierPath.polygon(
68
68
  position: keyframe.position.pointValue,
@@ -81,44 +81,25 @@ extension CAShapeLayer {
81
81
  extension Star {
82
82
  /// Data that represents how to render a star at a specific point in time
83
83
  struct Keyframe {
84
- let position: Vector3D
85
- let outerRadius: Vector1D
86
- let innerRadius: Vector1D
87
- let outerRoundness: Vector1D
88
- let innerRoundness: Vector1D
89
- let points: Vector1D
90
- let rotation: Vector1D
84
+ let position: LottieVector3D
85
+ let outerRadius: LottieVector1D
86
+ let innerRadius: LottieVector1D
87
+ let outerRoundness: LottieVector1D
88
+ let innerRoundness: LottieVector1D
89
+ let points: LottieVector1D
90
+ let rotation: LottieVector1D
91
91
  }
92
92
 
93
93
  /// Creates a single array of animatable keyframes from the separate arrays of keyframes in this star/polygon
94
- func combinedKeyframes(context: LayerAnimationContext) throws -> KeyframeGroup<Keyframe> {
95
- let combinedKeyframes = Keyframes.combinedIfPossible(
94
+ func combinedKeyframes() throws -> KeyframeGroup<Keyframe> {
95
+ Keyframes.combined(
96
96
  position,
97
97
  outerRadius,
98
- innerRadius ?? KeyframeGroup(Vector1D(0)),
98
+ innerRadius ?? KeyframeGroup(LottieVector1D(0)),
99
99
  outerRoundness,
100
- innerRoundness ?? KeyframeGroup(Vector1D(0)),
100
+ innerRoundness ?? KeyframeGroup(LottieVector1D(0)),
101
101
  points,
102
102
  rotation,
103
103
  makeCombinedResult: Star.Keyframe.init)
104
-
105
- if let combinedKeyframes = combinedKeyframes {
106
- return combinedKeyframes
107
- } else {
108
- // If we weren't able to combine all of the keyframes, we have to take the timing values
109
- // from one property and use a fixed value for the other properties.
110
- return try position.map { positionValue in
111
- Keyframe(
112
- position: positionValue,
113
- outerRadius: try outerRadius.exactlyOneKeyframe(context: context, description: "star outerRadius"),
114
- innerRadius: try innerRadius?.exactlyOneKeyframe(context: context, description: "star innerRadius")
115
- ?? Vector1D(0),
116
- outerRoundness: try outerRoundness.exactlyOneKeyframe(context: context, description: "star outerRoundness"),
117
- innerRoundness: try innerRoundness?.exactlyOneKeyframe(context: context, description: "star innerRoundness")
118
- ?? Vector1D(0),
119
- points: try points.exactlyOneKeyframe(context: context, description: "star points"),
120
- rotation: try rotation.exactlyOneKeyframe(context: context, description: "star rotation"))
121
- }
122
- }
123
104
  }
124
105
  }