lottie-ios 3.2.2 → 3.4.1

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 (316) hide show
  1. package/.github/actions/setup/action.yml +32 -0
  2. package/.github/issue_template.md +6 -23
  3. package/.github/workflows/main.yml +98 -0
  4. package/.spi.yml +6 -0
  5. package/.swift-version +1 -0
  6. package/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +7 -0
  7. package/.swiftpm/xcode/package.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  8. package/.swiftpm/xcode/xcuserdata/{brandonwithrow.xcuserdatad → cal.xcuserdatad}/xcschemes/xcschememanagement.plist +25 -15
  9. package/.swiftpm/xcode/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  10. package/Gemfile +4 -0
  11. package/Gemfile.lock +102 -0
  12. package/Lottie.xcodeproj/project.pbxproj +2003 -1972
  13. package/Lottie.xcodeproj/project.xcworkspace/contents.xcworkspacedata +1 -1
  14. package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  15. package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_iOS.xcscheme → Lottie (iOS).xcscheme } +15 -18
  16. package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_macOS.xcscheme → Lottie (macOS).xcscheme } +7 -20
  17. package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_tvOS.xcscheme → Lottie (tvOS).xcscheme } +5 -18
  18. package/Lottie.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +37 -0
  19. package/Lottie.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +24 -0
  20. package/Lottie.xcworkspace/contents.xcworkspacedata +10 -0
  21. package/Lottie.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  22. package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +115 -0
  23. package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  24. package/{Lottie.xcodeproj/xcuserdata/brandonwithrow.xcuserdatad → Lottie.xcworkspace/xcuserdata/cal.xcuserdatad}/xcdebugger/Breakpoints_v2.xcbkptlist +2 -2
  25. package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/xcdebugger/Expressions.xcexplist +153 -0
  26. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  27. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +39 -0
  28. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +25 -0
  29. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +30 -0
  30. package/Package.resolved +88 -0
  31. package/Package.swift +10 -15
  32. package/README.md +40 -60
  33. package/Rakefile +121 -0
  34. package/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift +81 -0
  35. package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +448 -0
  36. package/Sources/Private/CoreAnimation/Animations/CombinedShapeAnimation.swift +53 -0
  37. package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +41 -0
  38. package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +28 -0
  39. package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +210 -0
  40. package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +229 -0
  41. package/Sources/Private/CoreAnimation/Animations/OpacityAnimation.swift +52 -0
  42. package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +31 -0
  43. package/Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift +246 -0
  44. package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +95 -0
  45. package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +70 -0
  46. package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +205 -0
  47. package/Sources/Private/CoreAnimation/Animations/VisibilityAnimation.swift +37 -0
  48. package/Sources/Private/CoreAnimation/CompatibilityTracker.swift +130 -0
  49. package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +492 -0
  50. package/Sources/Private/CoreAnimation/Extensions/CALayer+fillBounds.swift +35 -0
  51. package/Sources/Private/CoreAnimation/Extensions/KeyframeGroup+exactlyOneKeyframe.swift +37 -0
  52. package/Sources/Private/CoreAnimation/Extensions/Keyframes+combinedIfPossible.swift +73 -0
  53. package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +83 -0
  54. package/Sources/Private/CoreAnimation/Layers/BaseAnimationLayer.swift +33 -0
  55. package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +87 -0
  56. package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +131 -0
  57. package/Sources/Private/CoreAnimation/Layers/GradientRenderLayer.swift +94 -0
  58. package/Sources/Private/CoreAnimation/Layers/ImageLayer.swift +79 -0
  59. package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +60 -0
  60. package/Sources/Private/CoreAnimation/Layers/MaskCompositionLayer.swift +138 -0
  61. package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +140 -0
  62. package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +302 -0
  63. package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +319 -0
  64. package/Sources/Private/CoreAnimation/Layers/SolidLayer.swift +47 -0
  65. package/Sources/Private/CoreAnimation/Layers/TextLayer.swift +91 -0
  66. package/Sources/Private/CoreAnimation/Layers/TransformLayer.swift +11 -0
  67. package/Sources/Private/CoreAnimation/ValueProviderStore.swift +139 -0
  68. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/CompositionLayer.swift +93 -85
  69. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/ImageCompositionLayer.swift +24 -21
  70. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/MaskContainerLayer.swift +75 -54
  71. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/NullCompositionLayer.swift +5 -5
  72. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/PreCompositionLayer.swift +61 -44
  73. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/ShapeCompositionLayer.swift +22 -20
  74. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/SolidCompositionLayer.swift +26 -17
  75. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/TextCompositionLayer.swift +42 -36
  76. package/{lottie-swift/src/Private/LayerContainers/AnimationContainer.swift → Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift} +200 -140
  77. package/Sources/Private/MainThread/LayerContainers/Utility/CachedImageProvider.swift +47 -0
  78. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/CompositionLayersInitializer.swift +33 -24
  79. package/{lottie-swift/src/Private/LayerContainers/Utility/TextLayer.swift → Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift} +120 -106
  80. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/InvertedMatteLayer.swift +25 -24
  81. package/Sources/Private/MainThread/LayerContainers/Utility/LayerFontProvider.swift +41 -0
  82. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/LayerImageProvider.swift +20 -16
  83. package/Sources/Private/MainThread/LayerContainers/Utility/LayerTextProvider.swift +40 -0
  84. package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/LayerTransformNode.swift +82 -67
  85. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Extensions/ItemsExtension.swift +4 -4
  86. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/NodeProperty.swift +29 -21
  87. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.swift +16 -10
  88. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.swift +6 -6
  89. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.swift +5 -5
  90. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.swift +10 -8
  91. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueContainer.swift +25 -21
  92. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueProviders/GroupInterpolator.swift +23 -17
  93. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.swift +125 -108
  94. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.swift +22 -17
  95. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +110 -79
  96. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/GroupOutputNode.swift +22 -16
  97. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.swift +19 -15
  98. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/PathOutputNode.swift +22 -20
  99. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/Renderables/FillRenderer.swift +22 -23
  100. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +242 -0
  101. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientStrokeRenderer.swift +30 -24
  102. package/{lottie-swift/src/Private/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift → Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift} +93 -66
  103. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +23 -19
  104. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +139 -0
  105. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +170 -0
  106. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/PathNodes/RectNode.swift +95 -58
  107. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/PathNodes/ShapeNode.swift +42 -29
  108. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/PathNodes/StarNode.swift +108 -69
  109. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +155 -0
  110. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/FillNode.swift +51 -37
  111. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +54 -42
  112. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +65 -57
  113. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +84 -58
  114. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +138 -119
  115. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Protocols/AnimatorNode.swift +80 -79
  116. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Protocols/PathNode.swift +5 -3
  117. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Protocols/RenderNode.swift +22 -17
  118. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +27 -24
  119. package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/RenderLayers/ShapeRenderLayer.swift +34 -25
  120. package/Sources/Private/Model/Animation.swift +160 -0
  121. package/Sources/Private/Model/Assets/Asset.swift +43 -0
  122. package/{lottie-swift/src → Sources}/Private/Model/Assets/AssetLibrary.swift +40 -13
  123. package/Sources/Private/Model/Assets/ImageAsset.swift +112 -0
  124. package/{lottie-swift/src → Sources}/Private/Model/Assets/PrecompAsset.swift +20 -10
  125. package/Sources/Private/Model/DictionaryInitializable.swift +67 -0
  126. package/Sources/Private/Model/Extensions/Bundle.swift +34 -0
  127. package/{lottie-swift/src → Sources}/Private/Model/Extensions/KeyedDecodingContainerExtensions.swift +8 -4
  128. package/Sources/Private/Model/Keyframes/KeyframeData.swift +113 -0
  129. package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +197 -0
  130. package/{lottie-swift/src → Sources}/Private/Model/Layers/ImageLayerModel.swift +21 -11
  131. package/Sources/Private/Model/Layers/LayerModel.swift +228 -0
  132. package/{lottie-swift/src → Sources}/Private/Model/Layers/PreCompLayerModel.swift +39 -22
  133. package/{lottie-swift/src → Sources}/Private/Model/Layers/ShapeLayerModel.swift +23 -12
  134. package/{lottie-swift/src → Sources}/Private/Model/Layers/SolidLayerModel.swift +31 -19
  135. package/{lottie-swift/src → Sources}/Private/Model/Layers/TextLayerModel.swift +33 -19
  136. package/Sources/Private/Model/Objects/DashPattern.swift +44 -0
  137. package/Sources/Private/Model/Objects/Marker.swift +33 -0
  138. package/Sources/Private/Model/Objects/Mask.swift +80 -0
  139. package/Sources/Private/Model/Objects/Transform.swift +179 -0
  140. package/Sources/Private/Model/ShapeItems/Ellipse.swift +75 -0
  141. package/Sources/Private/Model/ShapeItems/Fill.swift +74 -0
  142. package/Sources/Private/Model/ShapeItems/GradientFill.swift +124 -0
  143. package/Sources/Private/Model/ShapeItems/GradientStroke.swift +186 -0
  144. package/Sources/Private/Model/ShapeItems/Group.swift +48 -0
  145. package/{lottie-swift/src → Sources}/Private/Model/ShapeItems/Merge.swift +29 -11
  146. package/Sources/Private/Model/ShapeItems/Rectangle.swift +73 -0
  147. package/Sources/Private/Model/ShapeItems/Repeater.swift +136 -0
  148. package/Sources/Private/Model/ShapeItems/Shape.swift +56 -0
  149. package/Sources/Private/Model/ShapeItems/ShapeItem.swift +163 -0
  150. package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +136 -0
  151. package/Sources/Private/Model/ShapeItems/Star.swift +132 -0
  152. package/Sources/Private/Model/ShapeItems/Stroke.swift +102 -0
  153. package/Sources/Private/Model/ShapeItems/Trim.swift +78 -0
  154. package/Sources/Private/Model/Text/Font.swift +61 -0
  155. package/{lottie-swift/src → Sources}/Private/Model/Text/Glyph.swift +63 -39
  156. package/Sources/Private/Model/Text/TextAnimator.swift +164 -0
  157. package/Sources/Private/Model/Text/TextDocument.swift +123 -0
  158. package/Sources/Private/RootAnimationLayer.swift +51 -0
  159. package/{lottie-swift/src → Sources}/Private/Utility/Debugging/AnimatorNodeDebugging.swift +7 -7
  160. package/{lottie-swift/src → Sources}/Private/Utility/Debugging/LayerDebugging.swift +72 -48
  161. package/Sources/Private/Utility/Debugging/TestHelpers.swift +10 -0
  162. package/{lottie-swift/src → Sources}/Private/Utility/Extensions/AnimationKeypathExtension.swift +69 -59
  163. package/Sources/Private/Utility/Extensions/BlendMode+Filter.swift +31 -0
  164. package/Sources/Private/Utility/Extensions/CGColor+RGB.swift +22 -0
  165. package/{lottie-swift/src → Sources}/Private/Utility/Extensions/CGFloatExtensions.swift +70 -67
  166. package/Sources/Private/Utility/Extensions/DataExtension.swift +27 -0
  167. package/Sources/Private/Utility/Extensions/MathKit.swift +450 -0
  168. package/Sources/Private/Utility/Extensions/StringExtensions.swift +38 -0
  169. package/{lottie-swift/src → Sources}/Private/Utility/Helpers/AnimationContext.swift +42 -16
  170. package/Sources/Private/Utility/Interpolatable/InterpolatableExtensions.swift +134 -0
  171. package/{lottie-swift/src → Sources}/Private/Utility/Interpolatable/KeyframeExtensions.swift +13 -10
  172. package/Sources/Private/Utility/Interpolatable/KeyframeGroup+Extensions.swift +59 -0
  173. package/{lottie-swift/src → Sources}/Private/Utility/Primitives/BezierPath.swift +229 -143
  174. package/Sources/Private/Utility/Primitives/CGPointExtension.swift +35 -0
  175. package/{lottie-swift/src → Sources}/Private/Utility/Primitives/ColorExtension.swift +46 -14
  176. package/{lottie-swift/src → Sources}/Private/Utility/Primitives/CompoundBezierPath.swift +58 -49
  177. package/Sources/Private/Utility/Primitives/CurveVertex.swift +184 -0
  178. package/Sources/Private/Utility/Primitives/PathElement.swift +75 -0
  179. package/Sources/Private/Utility/Primitives/UnitBezier.swift +115 -0
  180. package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +341 -0
  181. package/Sources/Public/Animation/AnimationPublic.swift +266 -0
  182. package/Sources/Public/Animation/AnimationView.swift +1335 -0
  183. package/Sources/Public/Animation/AnimationViewInitializers.swift +109 -0
  184. package/Sources/Public/AnimationCache/AnimationCacheProvider.swift +22 -0
  185. package/{lottie-swift/src → Sources}/Public/AnimationCache/LRUAnimationCache.swift +22 -18
  186. package/Sources/Public/DynamicProperties/AnimationKeypath.swift +49 -0
  187. package/Sources/Public/DynamicProperties/AnyValueProvider.swift +132 -0
  188. package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/ColorValueProvider.swift +54 -36
  189. package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/FloatValueProvider.swift +40 -36
  190. package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +123 -0
  191. package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/PointValueProvider.swift +40 -35
  192. package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/SizeValueProvider.swift +40 -35
  193. package/{lottie-swift/src → Sources}/Public/FontProvider/AnimationFontProvider.swift +15 -8
  194. package/Sources/Public/ImageProvider/AnimationImageProvider.swift +21 -0
  195. package/Sources/Public/Keyframes/Interpolatable.swift +253 -0
  196. package/Sources/Public/Keyframes/Keyframe.swift +92 -0
  197. package/Sources/Public/Logging/LottieLogger.swift +137 -0
  198. package/Sources/Public/LottieConfiguration.swift +143 -0
  199. package/{lottie-swift/src → Sources}/Public/Primitives/AnimationTime.swift +1 -1
  200. package/{lottie-swift/src → Sources}/Public/Primitives/Color.swift +10 -6
  201. package/{lottie-swift/src → Sources}/Public/Primitives/Vectors.swift +13 -12
  202. package/Sources/Public/TextProvider/AnimationTextProvider.swift +53 -0
  203. package/{lottie-swift/src → Sources}/Public/iOS/AnimatedButton.swift +42 -26
  204. package/{lottie-swift/src → Sources}/Public/iOS/AnimatedControl.swift +100 -91
  205. package/{lottie-swift/src → Sources}/Public/iOS/AnimatedSwitch.swift +128 -94
  206. package/{lottie-swift/src → Sources}/Public/iOS/AnimationSubview.swift +3 -3
  207. package/Sources/Public/iOS/AnimationViewBase.swift +78 -0
  208. package/{lottie-swift/src → Sources}/Public/iOS/BundleImageProvider.swift +36 -34
  209. package/{lottie-swift/src → Sources}/Public/iOS/Compatibility/CompatibleAnimationKeypath.swift +4 -0
  210. package/{lottie-swift/src → Sources}/Public/iOS/Compatibility/CompatibleAnimationView.swift +38 -29
  211. package/{lottie-swift/src → Sources}/Public/iOS/FilepathImageProvider.swift +24 -21
  212. package/{lottie-swift/src → Sources}/Public/iOS/UIColorExtension.swift +4 -4
  213. package/{lottie-swift/src/Public/MacOS/AnimationSubview.swift → Sources/Public/macOS/AnimationSubview.macOS.swift} +4 -5
  214. package/{lottie-swift/src/Public/MacOS/LottieView.swift → Sources/Public/macOS/AnimationViewBase.macOS.swift} +58 -50
  215. package/{lottie-swift/src/Public/MacOS/BundleImageProvider.swift → Sources/Public/macOS/BundleImageProvider.macOS.swift} +31 -32
  216. package/Sources/Public/macOS/FilepathImageProvider.macOS.swift +67 -0
  217. package/Tests/AnimationKeypathTests.swift +94 -0
  218. package/Tests/AutomaticEngineTests.swift +57 -0
  219. package/Tests/BundleTests.swift +25 -0
  220. package/Tests/DataURLTests.swift +64 -0
  221. package/Tests/ParsingTests.swift +43 -0
  222. package/Tests/PerformanceTests.swift +215 -0
  223. package/Tests/SnapshotConfiguration.swift +153 -0
  224. package/Tests/SnapshotTests.swift +265 -0
  225. package/Tests/Utils/Bundle+Module.swift +30 -0
  226. package/Tests/Utils/HardcodedFontProvider.swift +19 -0
  227. package/Tests/Utils/HardcodedImageProvider.swift +23 -0
  228. package/Tests/Utils/Snapshotting+presentationLayer.swift +47 -0
  229. package/Tests/ValueProvidersTests.swift +27 -0
  230. package/lottie-ios.podspec +11 -12
  231. package/package.json +1 -1
  232. package/script/test-carthage/Cartfile +1 -0
  233. package/script/test-carthage/Cartfile.resolved +1 -0
  234. package/script/test-carthage/CarthageTest/AppDelegate.swift +26 -0
  235. package/script/test-carthage/CarthageTest/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  236. package/script/test-carthage/CarthageTest/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
  237. package/script/test-carthage/CarthageTest/Assets.xcassets/Contents.json +6 -0
  238. package/script/test-carthage/CarthageTest/Base.lproj/LaunchScreen.storyboard +25 -0
  239. package/script/test-carthage/CarthageTest/Base.lproj/Main.storyboard +24 -0
  240. package/script/test-carthage/CarthageTest/Info.plist +66 -0
  241. package/script/test-carthage/CarthageTest/SceneDelegate.swift +10 -0
  242. package/script/test-carthage/CarthageTest/ViewController.swift +15 -0
  243. package/script/test-carthage/CarthageTest-macOS/AppDelegate.swift +7 -0
  244. package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  245. package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json +58 -0
  246. package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/Contents.json +6 -0
  247. package/script/test-carthage/CarthageTest-macOS/Base.lproj/Main.storyboard +717 -0
  248. package/script/test-carthage/CarthageTest-macOS/CarthageTest_macOS.entitlements +10 -0
  249. package/script/test-carthage/CarthageTest-macOS/ViewController.swift +15 -0
  250. package/script/test-carthage/CarthageTest.xcodeproj/project.pbxproj +532 -0
  251. package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  252. package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  253. package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  254. package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  255. package/script/test-carthage/CarthageTest.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  256. package/script/test-carthage/CarthageTest.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +19 -0
  257. package/script/test-carthage/Mintfile +1 -0
  258. package/script/test-spm/LottieSPM.xcworkspace/contents.xcworkspacedata +7 -0
  259. package/script/test-spm/LottieSPM.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  260. package/script/test-spm/Mintfile +1 -0
  261. package/.swiftpm/xcode/package.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  262. package/Lottie/Info.plist +0 -22
  263. package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  264. package/Lottie.xcodeproj/xcuserdata/brandonwithrow.xcuserdatad/xcschemes/LottieLibraryMacOS.xcscheme +0 -80
  265. package/Lottie.xcodeproj/xcuserdata/brandonwithrow.xcuserdatad/xcschemes/xcschememanagement.plist +0 -57
  266. package/lottie-swift/Assets/.gitkeep +0 -0
  267. package/lottie-swift/src/Private/LayerContainers/Utility/LayerFontProvider.swift +0 -37
  268. package/lottie-swift/src/Private/LayerContainers/Utility/LayerTextProvider.swift +0 -36
  269. package/lottie-swift/src/Private/Model/Animation.swift +0 -107
  270. package/lottie-swift/src/Private/Model/Assets/Asset.swift +0 -27
  271. package/lottie-swift/src/Private/Model/Assets/ImageAsset.swift +0 -48
  272. package/lottie-swift/src/Private/Model/Keyframes/Keyframe.swift +0 -128
  273. package/lottie-swift/src/Private/Model/Keyframes/KeyframeGroup.swift +0 -108
  274. package/lottie-swift/src/Private/Model/Layers/LayerModel.swift +0 -150
  275. package/lottie-swift/src/Private/Model/Objects/DashPattern.swift +0 -24
  276. package/lottie-swift/src/Private/Model/Objects/Marker.swift +0 -23
  277. package/lottie-swift/src/Private/Model/Objects/Mask.swift +0 -48
  278. package/lottie-swift/src/Private/Model/Objects/Transform.swift +0 -105
  279. package/lottie-swift/src/Private/Model/ShapeItems/Ellipse.swift +0 -50
  280. package/lottie-swift/src/Private/Model/ShapeItems/FillI.swift +0 -49
  281. package/lottie-swift/src/Private/Model/ShapeItems/GradientFill.swift +0 -86
  282. package/lottie-swift/src/Private/Model/ShapeItems/GradientStroke.swift +0 -125
  283. package/lottie-swift/src/Private/Model/ShapeItems/Group.swift +0 -32
  284. package/lottie-swift/src/Private/Model/ShapeItems/Rectangle.swift +0 -50
  285. package/lottie-swift/src/Private/Model/ShapeItems/Repeater.swift +0 -80
  286. package/lottie-swift/src/Private/Model/ShapeItems/Shape.swift +0 -37
  287. package/lottie-swift/src/Private/Model/ShapeItems/ShapeItem.swift +0 -95
  288. package/lottie-swift/src/Private/Model/ShapeItems/ShapeTransform.swift +0 -68
  289. package/lottie-swift/src/Private/Model/ShapeItems/Star.swift +0 -86
  290. package/lottie-swift/src/Private/Model/ShapeItems/Stroke.swift +0 -67
  291. package/lottie-swift/src/Private/Model/ShapeItems/Trim.swift +0 -53
  292. package/lottie-swift/src/Private/Model/Text/Font.swift +0 -35
  293. package/lottie-swift/src/Private/Model/Text/TextAnimator.swift +0 -99
  294. package/lottie-swift/src/Private/Model/Text/TextDocument.swift +0 -70
  295. package/lottie-swift/src/Private/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +0 -109
  296. package/lottie-swift/src/Private/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +0 -132
  297. package/lottie-swift/src/Private/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +0 -141
  298. package/lottie-swift/src/Private/Utility/Extensions/MathKit.swift +0 -539
  299. package/lottie-swift/src/Private/Utility/Extensions/StringExtensions.swift +0 -32
  300. package/lottie-swift/src/Private/Utility/Interpolatable/Interpolatable.swift +0 -18
  301. package/lottie-swift/src/Private/Utility/Interpolatable/InterpolatableExtensions.swift +0 -170
  302. package/lottie-swift/src/Private/Utility/Primitives/CurveVertex.swift +0 -177
  303. package/lottie-swift/src/Private/Utility/Primitives/PathElement.swift +0 -68
  304. package/lottie-swift/src/Private/Utility/Primitives/VectorsExtensions.swift +0 -218
  305. package/lottie-swift/src/Public/Animation/AnimationPublic.swift +0 -196
  306. package/lottie-swift/src/Public/Animation/AnimationView.swift +0 -1006
  307. package/lottie-swift/src/Public/Animation/AnimationViewInitializers.swift +0 -83
  308. package/lottie-swift/src/Public/AnimationCache/AnimationCacheProvider.swift +0 -24
  309. package/lottie-swift/src/Public/DynamicProperties/AnimationKeypath.swift +0 -46
  310. package/lottie-swift/src/Public/DynamicProperties/AnyValueProvider.swift +0 -29
  311. package/lottie-swift/src/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +0 -114
  312. package/lottie-swift/src/Public/ImageProvider/AnimationImageProvider.swift +0 -23
  313. package/lottie-swift/src/Public/MacOS/FilepathImageProvider.swift +0 -67
  314. package/lottie-swift/src/Public/TextProvider/AnimationTextProvider.swift +0 -39
  315. package/lottie-swift/src/Public/iOS/LottieView.swift +0 -62
  316. package/lottie-swift-testing.podspec +0 -32
@@ -0,0 +1,210 @@
1
+ // Created by Cal Stephens on 1/7/22.
2
+ // Copyright © 2022 Airbnb Inc. All rights reserved.
3
+
4
+ import QuartzCore
5
+
6
+ // MARK: - GradientShapeItem
7
+
8
+ /// A `ShapeItem` that represents a gradient
9
+ protocol GradientShapeItem: OpacityAnimationModel {
10
+ var startPoint: KeyframeGroup<Vector3D> { get }
11
+ var endPoint: KeyframeGroup<Vector3D> { get }
12
+ var gradientType: GradientType { get }
13
+ var numberOfColors: Int { get }
14
+ var colors: KeyframeGroup<[Double]> { get }
15
+ }
16
+
17
+ // MARK: - GradientFill + GradientShapeItem
18
+
19
+ extension GradientFill: GradientShapeItem { }
20
+
21
+ // MARK: - GradientStroke + GradientShapeItem
22
+
23
+ extension GradientStroke: GradientShapeItem { }
24
+
25
+ // MARK: - GradientRenderLayer + GradientShapeItem
26
+
27
+ extension GradientRenderLayer {
28
+
29
+ // MARK: Internal
30
+
31
+ /// Adds gradient-related animations to this layer, from the given `GradientFill`
32
+ /// - The RGB components and alpha components can have different color stops / locations,
33
+ /// so have to be rendered in separate `CAGradientLayer`s.
34
+ func addGradientAnimations(
35
+ for gradient: GradientShapeItem,
36
+ type: GradientContentType,
37
+ context: LayerAnimationContext) throws
38
+ {
39
+ // We have to set `colors` to a non-nil value with some valid number of colors
40
+ // for the color animation below to have any effect
41
+ colors = .init(
42
+ repeating: CGColor.rgb(0, 0, 0),
43
+ count: gradient.numberOfColors)
44
+
45
+ try addAnimation(
46
+ for: .colors,
47
+ keyframes: gradient.colors.keyframes,
48
+ value: { colorComponents in
49
+ gradient.colorConfiguration(from: colorComponents, type: type).map { $0.color }
50
+ },
51
+ context: context)
52
+
53
+ try addAnimation(
54
+ for: .locations,
55
+ keyframes: gradient.colors.keyframes,
56
+ value: { colorComponents in
57
+ gradient.colorConfiguration(from: colorComponents, type: type).map { $0.location }
58
+ },
59
+ context: context)
60
+
61
+ try addOpacityAnimation(for: gradient, context: context)
62
+
63
+ switch gradient.gradientType {
64
+ case .linear:
65
+ try addLinearGradientAnimations(for: gradient, context: context)
66
+ case .radial:
67
+ try addRadialGradientAnimations(for: gradient, context: context)
68
+ case .none:
69
+ break
70
+ }
71
+ }
72
+
73
+ // MARK: Private
74
+
75
+ private func addLinearGradientAnimations(
76
+ for gradient: GradientShapeItem,
77
+ context: LayerAnimationContext)
78
+ throws
79
+ {
80
+ type = .axial
81
+
82
+ try addAnimation(
83
+ for: .startPoint,
84
+ keyframes: gradient.startPoint.keyframes,
85
+ value: { absoluteStartPoint in
86
+ percentBasedPointInBounds(from: absoluteStartPoint.pointValue)
87
+ },
88
+ context: context)
89
+
90
+ try addAnimation(
91
+ for: .endPoint,
92
+ keyframes: gradient.endPoint.keyframes,
93
+ value: { absoluteEndPoint in
94
+ percentBasedPointInBounds(from: absoluteEndPoint.pointValue)
95
+ },
96
+ context: context)
97
+ }
98
+
99
+ private func addRadialGradientAnimations(for gradient: GradientShapeItem, context: LayerAnimationContext) throws {
100
+ type = .radial
101
+
102
+ // To draw the correct gradients, we have to derive a custom `endPoint`
103
+ // relative to the `startPoint` value. Since calculating the `endPoint`
104
+ // at any given time requires knowing the current `startPoint`,
105
+ // we can't allow them to animate separately.
106
+ let absoluteStartPoint = try gradient.startPoint
107
+ .exactlyOneKeyframe(context: context, description: "gradient startPoint").value.pointValue
108
+
109
+ let absoluteEndPoint = try gradient.endPoint
110
+ .exactlyOneKeyframe(context: context, description: "gradient endPoint").value.pointValue
111
+
112
+ startPoint = percentBasedPointInBounds(from: absoluteStartPoint)
113
+
114
+ let radius = absoluteStartPoint.distanceTo(absoluteEndPoint)
115
+ endPoint = percentBasedPointInBounds(
116
+ from: CGPoint(
117
+ x: absoluteStartPoint.x + radius,
118
+ y: absoluteStartPoint.y + radius))
119
+ }
120
+ }
121
+
122
+ // MARK: - GradientContentType
123
+
124
+ /// Each type of gradient that can be constructed from a `GradientShapeItem`
125
+ enum GradientContentType {
126
+ case rgb
127
+ case alpha
128
+ }
129
+
130
+ /// `colors` and `locations` configuration for a `CAGradientLayer`
131
+ typealias GradientColorConfiguration = [(color: CGColor, location: CGFloat)]
132
+
133
+ extension GradientShapeItem {
134
+
135
+ // MARK: Internal
136
+
137
+ /// Whether or not this `GradientShapeItem` includes an alpha component
138
+ /// that has to be rendered as a separate `CAGradientLayer` from the
139
+ /// layer that renders the rgb color components
140
+ var hasAlphaComponent: Bool {
141
+ for colorComponentsKeyframe in colors.keyframes {
142
+ let colorComponents = colorComponentsKeyframe.value
143
+ let alphaConfiguration = colorConfiguration(from: colorComponents, type: .alpha)
144
+
145
+ let notFullyOpaque = alphaConfiguration.contains(where: { color, _ in
146
+ color.alpha < 0.999
147
+ })
148
+
149
+ if notFullyOpaque {
150
+ return true
151
+ }
152
+ }
153
+
154
+ return false
155
+ }
156
+
157
+ // MARK: Fileprivate
158
+
159
+ /// Converts the compact `[Double]` color components representation
160
+ /// into an array of `CGColor`s and the location of those colors within the gradient.
161
+ /// - The color components array is a repeating list of `[location, red, green, blue]` values
162
+ /// for each color in the gradient, followed by an optional repeating list of
163
+ /// `[location, alpha]` values that control the colors' alpha values.
164
+ /// - The RGB and alpha values can have different color stops / locations,
165
+ /// so each has to be rendered in a separate `CAGradientLayer`.
166
+ fileprivate func colorConfiguration(
167
+ from colorComponents: [Double],
168
+ type: GradientContentType)
169
+ -> GradientColorConfiguration
170
+ {
171
+ switch type {
172
+ case .rgb:
173
+ precondition(
174
+ colorComponents.count >= numberOfColors * 4,
175
+ "Each color must have RGB components and a location component")
176
+
177
+ // Each group of four `Double` values represents a single `CGColor`,
178
+ // and its relative location within the gradient.
179
+ var colors = GradientColorConfiguration()
180
+
181
+ for colorIndex in 0..<numberOfColors {
182
+ let colorStartIndex = colorIndex * 4
183
+
184
+ let colorLocation = CGFloat(colorComponents[colorStartIndex])
185
+
186
+ let color = CGColor.rgb(
187
+ CGFloat(colorComponents[colorStartIndex + 1]),
188
+ CGFloat(colorComponents[colorStartIndex + 2]),
189
+ CGFloat(colorComponents[colorStartIndex + 3]))
190
+
191
+ colors.append((color: color, location: colorLocation))
192
+ }
193
+
194
+ return colors
195
+
196
+ case .alpha:
197
+ // After the rgb color components, there can be arbitrary number of repeating
198
+ // `[alphaLocation, alphaValue]` pairs that define a separate alpha gradient.
199
+ var alphaValues = GradientColorConfiguration()
200
+
201
+ for alphaIndex in stride(from: numberOfColors * 4, to: colorComponents.endIndex, by: 2) {
202
+ let alphaLocation = CGFloat(colorComponents[alphaIndex])
203
+ let alphaValue = CGFloat(colorComponents[alphaIndex + 1])
204
+ alphaValues.append((color: .rgba(0, 0, 0, alphaValue), location: alphaLocation))
205
+ }
206
+
207
+ return alphaValues
208
+ }
209
+ }
210
+ }
@@ -0,0 +1,229 @@
1
+ // Created by Cal Stephens on 1/11/22.
2
+ // Copyright © 2022 Airbnb Inc. All rights reserved.
3
+
4
+ import QuartzCore
5
+
6
+ // MARK: - LayerProperty
7
+
8
+ /// A strongly typed value that can be used as the `keyPath` of a `CAAnimation`
9
+ ///
10
+ /// Supported key paths and their expected value types are described
11
+ /// at https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/AnimatableProperties/AnimatableProperties.html#//apple_ref/doc/uid/TP40004514-CH11-SW1
12
+ /// and https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/Key-ValueCodingExtensions/Key-ValueCodingExtensions.html
13
+ struct LayerProperty<ValueRepresentation: Equatable> {
14
+ /// The `CALayer` KVC key path that this value should be assigned to
15
+ let caLayerKeypath: String
16
+
17
+ /// The default value of this property on a `CALayer`
18
+ /// - If the keyframe values are just equal to the default value,
19
+ /// then we can improve performance a bit by just not creating
20
+ /// a CAAnimation (since it would be redundant).
21
+ let defaultValue: ValueRepresentation?
22
+
23
+ /// A description of how this property can be customized dynamically
24
+ /// at runtime using `AnimationView.setValueProvider(_:keypath:)`
25
+ let customizableProperty: CustomizableProperty<ValueRepresentation>?
26
+ }
27
+
28
+ // MARK: - CustomizableProperty
29
+
30
+ /// A description of how a `CALayer` property can be customized dynamically
31
+ /// at runtime using `AnimationView.setValueProvider(_:keypath:)`
32
+ struct CustomizableProperty<ValueRepresentation> {
33
+ /// The name that `AnimationKeypath`s can use to refer to this property
34
+ /// - When building an animation for this property that will be applied
35
+ /// to a specific layer, this `name` is appended to the end of that
36
+ /// layer's `AnimationKeypath`. The combined keypath is used to query
37
+ /// the `ValueProviderStore`.
38
+ let name: [PropertyName]
39
+
40
+ /// A closure that coverts the type-erased value of an `AnyValueProvider`
41
+ /// to the strongly-typed representation used by this property, if possible.
42
+ let conversion: (Any) -> ValueRepresentation?
43
+ }
44
+
45
+ // MARK: - PropertyName
46
+
47
+ /// The name of a customizable property that can be used in an `AnimationKeypath`
48
+ /// - These values should be shared between the two rendering engines,
49
+ /// since they form the public API of the `AnimationKeypath` system.
50
+ enum PropertyName: String {
51
+ case color = "Color"
52
+ }
53
+
54
+ // MARK: CALayer properties
55
+
56
+ extension LayerProperty {
57
+ static var position: LayerProperty<CGPoint> {
58
+ .init(
59
+ caLayerKeypath: "transform.translation",
60
+ defaultValue: CGPoint(x: 0, y: 0),
61
+ customizableProperty: nil /* currently unsupported */ )
62
+ }
63
+
64
+ static var positionX: LayerProperty<CGFloat> {
65
+ .init(
66
+ caLayerKeypath: "transform.translation.x",
67
+ defaultValue: 0,
68
+ customizableProperty: nil /* currently unsupported */ )
69
+ }
70
+
71
+ static var positionY: LayerProperty<CGFloat> {
72
+ .init(
73
+ caLayerKeypath: "transform.translation.y",
74
+ defaultValue: 0,
75
+ customizableProperty: nil /* currently unsupported */ )
76
+ }
77
+
78
+ static var scale: LayerProperty<CGFloat> {
79
+ .init(
80
+ caLayerKeypath: "transform.scale",
81
+ defaultValue: 1,
82
+ customizableProperty: nil /* currently unsupported */ )
83
+ }
84
+
85
+ static var scaleX: LayerProperty<CGFloat> {
86
+ .init(
87
+ caLayerKeypath: "transform.scale.x",
88
+ defaultValue: 1,
89
+ customizableProperty: nil /* currently unsupported */ )
90
+ }
91
+
92
+ static var scaleY: LayerProperty<CGFloat> {
93
+ .init(
94
+ caLayerKeypath: "transform.scale.y",
95
+ defaultValue: 1,
96
+ customizableProperty: nil /* currently unsupported */ )
97
+ }
98
+
99
+ static var rotation: LayerProperty<CGFloat> {
100
+ .init(
101
+ caLayerKeypath: "transform.rotation",
102
+ defaultValue: 0,
103
+ customizableProperty: nil /* currently unsupported */ )
104
+ }
105
+
106
+ static var rotationY: LayerProperty<CGFloat> {
107
+ .init(
108
+ caLayerKeypath: "transform.rotation.y",
109
+ defaultValue: 0,
110
+ customizableProperty: nil /* currently unsupported */ )
111
+ }
112
+
113
+ static var anchorPoint: LayerProperty<CGPoint> {
114
+ .init(
115
+ caLayerKeypath: #keyPath(CALayer.anchorPoint),
116
+ // This is intentionally not `GGPoint(x: 0.5, y: 0.5)` (the actual default)
117
+ // to opt `anchorPoint` out of the KVC `setValue` flow, which causes issues.
118
+ defaultValue: nil,
119
+ customizableProperty: nil /* currently unsupported */ )
120
+ }
121
+
122
+ static var opacity: LayerProperty<CGFloat> {
123
+ .init(
124
+ caLayerKeypath: #keyPath(CALayer.opacity),
125
+ defaultValue: 1,
126
+ customizableProperty: nil /* currently unsupported */ )
127
+ }
128
+ }
129
+
130
+ // MARK: CAShapeLayer properties
131
+
132
+ extension LayerProperty {
133
+ static var path: LayerProperty<CGPath> {
134
+ .init(
135
+ caLayerKeypath: #keyPath(CAShapeLayer.path),
136
+ defaultValue: nil,
137
+ customizableProperty: nil /* currently unsupported */ )
138
+ }
139
+
140
+ static var fillColor: LayerProperty<CGColor> {
141
+ .init(
142
+ caLayerKeypath: #keyPath(CAShapeLayer.fillColor),
143
+ defaultValue: nil,
144
+ customizableProperty: .color)
145
+ }
146
+
147
+ static var lineWidth: LayerProperty<CGFloat> {
148
+ .init(
149
+ caLayerKeypath: #keyPath(CAShapeLayer.lineWidth),
150
+ defaultValue: 1,
151
+ customizableProperty: nil /* currently unsupported */ )
152
+ }
153
+
154
+ static var lineDashPhase: LayerProperty<CGFloat> {
155
+ .init(
156
+ caLayerKeypath: #keyPath(CAShapeLayer.lineDashPhase),
157
+ defaultValue: 0,
158
+ customizableProperty: nil /* currently unsupported */ )
159
+ }
160
+
161
+ static var strokeColor: LayerProperty<CGColor> {
162
+ .init(
163
+ caLayerKeypath: #keyPath(CAShapeLayer.strokeColor),
164
+ defaultValue: nil,
165
+ customizableProperty: .color)
166
+ }
167
+
168
+ static var strokeStart: LayerProperty<CGFloat> {
169
+ .init(
170
+ caLayerKeypath: #keyPath(CAShapeLayer.strokeStart),
171
+ defaultValue: 0,
172
+ customizableProperty: nil /* currently unsupported */ )
173
+ }
174
+
175
+ static var strokeEnd: LayerProperty<CGFloat> {
176
+ .init(
177
+ caLayerKeypath: #keyPath(CAShapeLayer.strokeEnd),
178
+ defaultValue: 1,
179
+ customizableProperty: nil /* currently unsupported */ )
180
+ }
181
+ }
182
+
183
+ // MARK: CAGradientLayer properties
184
+
185
+ extension LayerProperty {
186
+ static var colors: LayerProperty<[CGColor]> {
187
+ .init(
188
+ caLayerKeypath: #keyPath(CAGradientLayer.colors),
189
+ defaultValue: nil,
190
+ customizableProperty: nil /* currently unsupported */ )
191
+ }
192
+
193
+ static var locations: LayerProperty<[CGFloat]> {
194
+ .init(
195
+ caLayerKeypath: #keyPath(CAGradientLayer.locations),
196
+ defaultValue: nil,
197
+ customizableProperty: nil /* currently unsupported */ )
198
+ }
199
+
200
+ static var startPoint: LayerProperty<CGPoint> {
201
+ .init(
202
+ caLayerKeypath: #keyPath(CAGradientLayer.startPoint),
203
+ defaultValue: nil,
204
+ customizableProperty: nil /* currently unsupported */ )
205
+ }
206
+
207
+ static var endPoint: LayerProperty<CGPoint> {
208
+ .init(
209
+ caLayerKeypath: #keyPath(CAGradientLayer.endPoint),
210
+ defaultValue: nil,
211
+ customizableProperty: nil /* currently unsupported */ )
212
+ }
213
+ }
214
+
215
+ // MARK: - CustomizableProperty types
216
+
217
+ extension CustomizableProperty {
218
+ static var color: CustomizableProperty<CGColor> {
219
+ .init(
220
+ name: [.color],
221
+ conversion: { typeErasedValue in
222
+ guard let color = typeErasedValue as? Color else {
223
+ return nil
224
+ }
225
+
226
+ return .rgba(CGFloat(color.r), CGFloat(color.g), CGFloat(color.b), CGFloat(color.a))
227
+ })
228
+ }
229
+ }
@@ -0,0 +1,52 @@
1
+ // Created by Cal Stephens on 5/17/22.
2
+ // Copyright © 2022 Airbnb Inc. All rights reserved.
3
+
4
+ import QuartzCore
5
+
6
+ // MARK: - OpacityAnimationModel
7
+
8
+ protocol OpacityAnimationModel {
9
+ /// The opacity animation to apply to a `CALayer`
10
+ var opacity: KeyframeGroup<Vector1D> { get }
11
+ }
12
+
13
+ // MARK: - Transform + OpacityAnimationModel
14
+
15
+ extension Transform: OpacityAnimationModel { }
16
+
17
+ // MARK: - ShapeTransform + OpacityAnimationModel
18
+
19
+ extension ShapeTransform: OpacityAnimationModel { }
20
+
21
+ // MARK: - Fill + OpacityAnimationModel
22
+
23
+ extension Fill: OpacityAnimationModel { }
24
+
25
+ // MARK: - GradientFill + OpacityAnimationModel
26
+
27
+ extension GradientFill: OpacityAnimationModel { }
28
+
29
+ // MARK: - Stroke + OpacityAnimationModel
30
+
31
+ extension Stroke: OpacityAnimationModel { }
32
+
33
+ // MARK: - GradientStroke + OpacityAnimationModel
34
+
35
+ extension GradientStroke: OpacityAnimationModel { }
36
+
37
+ extension CALayer {
38
+ /// Adds the opacity animation from the given `OpacityAnimationModel` to this layer
39
+ @nonobjc
40
+ func addOpacityAnimation(for opacity: OpacityAnimationModel, context: LayerAnimationContext) throws {
41
+ try addAnimation(
42
+ for: .opacity,
43
+ keyframes: opacity.opacity.keyframes,
44
+ value: {
45
+ // Lottie animation files express opacity as a numerical percentage value
46
+ // (e.g. 0%, 50%, 100%) so we divide by 100 to get the decimal values
47
+ // expected by Core Animation (e.g. 0.0, 0.5, 1.0).
48
+ $0.cgFloatValue / 100
49
+ },
50
+ context: context)
51
+ }
52
+ }
@@ -0,0 +1,31 @@
1
+ // Created by Cal Stephens on 12/21/21.
2
+ // Copyright © 2021 Airbnb Inc. All rights reserved.
3
+
4
+ import QuartzCore
5
+
6
+ extension CAShapeLayer {
7
+ /// Adds animations for the given `Rectangle` to this `CALayer`
8
+ @nonobjc
9
+ func addAnimations(
10
+ for rectangle: Rectangle,
11
+ context: LayerAnimationContext,
12
+ pathMultiplier: PathMultiplier)
13
+ throws
14
+ {
15
+ try addAnimation(
16
+ for: .path,
17
+ keyframes: rectangle.size.keyframes,
18
+ value: { sizeKeyframe in
19
+ BezierPath.rectangle(
20
+ position: try rectangle.position
21
+ .exactlyOneKeyframe(context: context, description: "rectangle position").value.pointValue,
22
+ size: sizeKeyframe.sizeValue,
23
+ cornerRadius: try rectangle.cornerRadius
24
+ .exactlyOneKeyframe(context: context, description: "rectangle cornerRadius").value.cgFloatValue,
25
+ direction: rectangle.direction)
26
+ .cgPath()
27
+ .duplicated(times: pathMultiplier)
28
+ },
29
+ context: context)
30
+ }
31
+ }