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
@@ -5,53 +5,58 @@
5
5
  // Created by Brandon Withrow on 1/17/19.
6
6
  //
7
7
 
8
- import Foundation
9
8
  import CoreGraphics
9
+ import Foundation
10
10
  import QuartzCore
11
11
 
12
+ // MARK: - RenderNode
13
+
12
14
  /// A protocol that defines a node that holds render instructions
13
15
  protocol RenderNode {
14
16
  var renderer: Renderable & NodeOutput { get }
15
17
  }
16
18
 
19
+ // MARK: - Renderable
20
+
17
21
  /// A protocol that defines anything with render instructions
18
22
  protocol Renderable {
19
-
23
+
20
24
  /// The last frame in which this node was updated.
21
25
  var hasUpdate: Bool { get }
22
-
26
+
23
27
  func hasRenderUpdates(_ forFrame: CGFloat) -> Bool
24
-
25
- /**
26
- Determines if the renderer requires a custom context for drawing.
27
- If yes the shape layer will perform a custom drawing pass.
28
- If no the shape layer will be a standard CAShapeLayer
29
- */
28
+
29
+ /// Determines if the renderer requires a custom context for drawing.
30
+ /// If yes the shape layer will perform a custom drawing pass.
31
+ /// If no the shape layer will be a standard CAShapeLayer
30
32
  var shouldRenderInContext: Bool { get }
31
-
33
+
32
34
  /// Passes in the CAShapeLayer to update
33
35
  func updateShapeLayer(layer: CAShapeLayer)
34
-
36
+
35
37
  /// Asks the renderer what the renderable bounds is for the given box.
36
38
  func renderBoundsFor(_ boundingBox: CGRect) -> CGRect
37
-
39
+
40
+ /// Opportunity for renderers to inject sublayers
41
+ func setupSublayers(layer: CAShapeLayer)
42
+
38
43
  /// Renders the shape in a custom context
39
44
  func render(_ inContext: CGContext)
40
45
  }
41
46
 
42
47
  extension RenderNode where Self: AnimatorNode {
43
-
48
+
44
49
  var outputNode: NodeOutput {
45
- return renderer
50
+ renderer
46
51
  }
47
-
52
+
48
53
  }
49
54
 
50
55
  extension Renderable {
51
56
 
52
57
  func renderBoundsFor(_ boundingBox: CGRect) -> CGRect {
53
58
  /// Optional
54
- return boundingBox
59
+ boundingBox
55
60
  }
56
-
61
+
57
62
  }
@@ -8,16 +8,14 @@
8
8
  import Foundation
9
9
  import QuartzCore
10
10
 
11
- /**
12
- The base layer that holds Shapes and Shape Renderers
13
- */
11
+ /// The base layer that holds Shapes and Shape Renderers
14
12
  class ShapeContainerLayer: CALayer {
15
-
16
- private(set) var renderLayers: [ShapeContainerLayer] = []
17
-
13
+
14
+ // MARK: Lifecycle
15
+
18
16
  override init() {
19
17
  super.init()
20
- self.actions = [
18
+ actions = [
21
19
  "position" : NSNull(),
22
20
  "bounds" : NSNull(),
23
21
  "anchorPoint" : NSNull(),
@@ -26,47 +24,52 @@ class ShapeContainerLayer: CALayer {
26
24
  "hidden" : NSNull(),
27
25
  ]
28
26
  }
29
-
30
- required init?(coder aDecoder: NSCoder) {
27
+
28
+ required init?(coder _: NSCoder) {
31
29
  fatalError("init(coder:) has not been implemented")
32
30
  }
33
-
31
+
34
32
  override init(layer: Any) {
35
33
  guard let layer = layer as? ShapeContainerLayer else {
36
34
  fatalError("init(layer:) wrong class.")
37
35
  }
38
36
  super.init(layer: layer)
39
37
  }
40
-
38
+
39
+ // MARK: Internal
40
+
41
+ private(set) var renderLayers: [ShapeContainerLayer] = []
42
+
41
43
  var renderScale: CGFloat = 1 {
42
44
  didSet {
43
45
  updateRenderScale()
44
46
  }
45
47
  }
46
-
48
+
47
49
  func insertRenderLayer(_ layer: ShapeContainerLayer) {
48
50
  renderLayers.append(layer)
49
51
  insertSublayer(layer, at: 0)
50
52
  }
51
-
53
+
52
54
  func markRenderUpdates(forFrame: CGFloat) {
53
- if self.hasRenderUpdate(forFrame: forFrame) {
54
- self.rebuildContents(forFrame: forFrame)
55
+ if hasRenderUpdate(forFrame: forFrame) {
56
+ rebuildContents(forFrame: forFrame)
55
57
  }
56
- guard self.isHidden == false else { return }
58
+ guard isHidden == false else { return }
57
59
  renderLayers.forEach { $0.markRenderUpdates(forFrame: forFrame) }
58
60
  }
59
-
60
- func hasRenderUpdate(forFrame: CGFloat) -> Bool {
61
- return false
61
+
62
+ func hasRenderUpdate(forFrame _: CGFloat) -> Bool {
63
+ false
62
64
  }
63
-
64
- func rebuildContents(forFrame: CGFloat) {
65
+
66
+ func rebuildContents(forFrame _: CGFloat) {
65
67
  /// Override
66
68
  }
67
-
69
+
68
70
  func updateRenderScale() {
69
- renderLayers.forEach( { $0.renderScale = renderScale } )
71
+ contentsScale = renderScale
72
+ renderLayers.forEach({ $0.renderScale = renderScale })
70
73
  }
71
-
74
+
72
75
  }
@@ -8,20 +8,16 @@
8
8
  import Foundation
9
9
  import QuartzCore
10
10
 
11
- /**
12
- The layer responsible for rendering shape objects
13
- */
11
+ /// The layer responsible for rendering shape objects
14
12
  final class ShapeRenderLayer: ShapeContainerLayer {
15
-
16
- fileprivate(set) var renderer: Renderable & NodeOutput
17
-
18
- let shapeLayer: CAShapeLayer = CAShapeLayer()
19
-
13
+
14
+ // MARK: Lifecycle
15
+
20
16
  init(renderer: Renderable & NodeOutput) {
21
17
  self.renderer = renderer
22
18
  super.init()
23
- self.anchorPoint = .zero
24
- self.actions = [
19
+ anchorPoint = .zero
20
+ actions = [
25
21
  "position" : NSNull(),
26
22
  "bounds" : NSNull(),
27
23
  "anchorPoint" : NSNull(),
@@ -40,45 +36,53 @@ final class ShapeRenderLayer: ShapeContainerLayer {
40
36
  "lineWidth" : NSNull(),
41
37
  "miterLimit" : NSNull(),
42
38
  "lineDashPhase" : NSNull(),
39
+ "opacity": NSNull(),
43
40
  "hidden" : NSNull(),
44
41
  ]
45
42
  addSublayer(shapeLayer)
43
+
44
+ renderer.setupSublayers(layer: shapeLayer)
46
45
  }
47
-
46
+
48
47
  override init(layer: Any) {
49
48
  guard let layer = layer as? ShapeRenderLayer else {
50
49
  fatalError("init(layer:) wrong class.")
51
50
  }
52
- self.renderer = layer.renderer
51
+ renderer = layer.renderer
53
52
  super.init(layer: layer)
54
53
  }
55
-
56
- required init?(coder aDecoder: NSCoder) {
54
+
55
+ required init?(coder _: NSCoder) {
57
56
  fatalError("init(coder:) has not been implemented")
58
57
  }
59
-
58
+
59
+ // MARK: Internal
60
+
61
+ fileprivate(set) var renderer: Renderable & NodeOutput
62
+
63
+ let shapeLayer = CAShapeLayer()
64
+
60
65
  override func hasRenderUpdate(forFrame: CGFloat) -> Bool {
61
- self.isHidden = !renderer.isEnabled
62
- guard self.isHidden == false else { return false }
66
+ isHidden = !renderer.isEnabled
67
+ guard isHidden == false else { return false }
63
68
  return renderer.hasRenderUpdates(forFrame)
64
69
  }
65
-
66
- override func rebuildContents(forFrame: CGFloat) {
67
-
70
+
71
+ override func rebuildContents(forFrame _: CGFloat) {
68
72
  if renderer.shouldRenderInContext {
69
73
  if let newPath = renderer.outputPath {
70
- self.bounds = renderer.renderBoundsFor(newPath.boundingBox)
74
+ bounds = renderer.renderBoundsFor(newPath.boundingBox)
71
75
  } else {
72
- self.bounds = .zero
76
+ bounds = .zero
73
77
  }
74
- self.position = bounds.origin
75
- self.setNeedsDisplay()
78
+ position = bounds.origin
79
+ setNeedsDisplay()
76
80
  } else {
77
81
  shapeLayer.path = renderer.outputPath
78
82
  renderer.updateShapeLayer(layer: shapeLayer)
79
83
  }
80
84
  }
81
-
85
+
82
86
  override func draw(in ctx: CGContext) {
83
87
  if let path = renderer.outputPath {
84
88
  if !path.isEmpty {
@@ -87,4 +91,9 @@ final class ShapeRenderLayer: ShapeContainerLayer {
87
91
  }
88
92
  renderer.render(ctx)
89
93
  }
94
+
95
+ override func updateRenderScale() {
96
+ super.updateRenderScale()
97
+ shapeLayer.contentsScale = renderScale
98
+ }
90
99
  }
@@ -0,0 +1,160 @@
1
+ //
2
+ // Animation.swift
3
+ // lottie-swift
4
+ //
5
+ // Created by Brandon Withrow on 1/7/19.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ // MARK: - CoordinateSpace
11
+
12
+ public enum CoordinateSpace: Int, Codable {
13
+ case type2d
14
+ case type3d
15
+ }
16
+
17
+ // MARK: - Animation
18
+
19
+ /// The `Animation` model is the top level model object in Lottie.
20
+ ///
21
+ /// An `Animation` holds all of the animation data backing a Lottie Animation.
22
+ /// Codable, see JSON schema [here](https://github.com/airbnb/lottie-web/tree/master/docs/json).
23
+ public final class Animation: Codable, DictionaryInitializable {
24
+
25
+ // MARK: Lifecycle
26
+
27
+ required public init(from decoder: Decoder) throws {
28
+ let container = try decoder.container(keyedBy: Animation.CodingKeys.self)
29
+ version = try container.decode(String.self, forKey: .version)
30
+ type = try container.decodeIfPresent(CoordinateSpace.self, forKey: .type) ?? .type2d
31
+ startFrame = try container.decode(AnimationFrameTime.self, forKey: .startFrame)
32
+ endFrame = try container.decode(AnimationFrameTime.self, forKey: .endFrame)
33
+ framerate = try container.decode(Double.self, forKey: .framerate)
34
+ width = try container.decode(Int.self, forKey: .width)
35
+ height = try container.decode(Int.self, forKey: .height)
36
+ layers = try container.decode([LayerModel].self, ofFamily: LayerType.self, forKey: .layers)
37
+ glyphs = try container.decodeIfPresent([Glyph].self, forKey: .glyphs)
38
+ fonts = try container.decodeIfPresent(FontList.self, forKey: .fonts)
39
+ assetLibrary = try container.decodeIfPresent(AssetLibrary.self, forKey: .assetLibrary)
40
+ markers = try container.decodeIfPresent([Marker].self, forKey: .markers)
41
+
42
+ if let markers = markers {
43
+ var markerMap: [String: Marker] = [:]
44
+ for marker in markers {
45
+ markerMap[marker.name] = marker
46
+ }
47
+ self.markerMap = markerMap
48
+ } else {
49
+ markerMap = nil
50
+ }
51
+ }
52
+
53
+ public init(dictionary: [String: Any]) throws {
54
+ version = try dictionary.value(for: CodingKeys.version)
55
+ if
56
+ let typeRawValue = dictionary[CodingKeys.type.rawValue] as? Int,
57
+ let type = CoordinateSpace(rawValue: typeRawValue)
58
+ {
59
+ self.type = type
60
+ } else {
61
+ type = .type2d
62
+ }
63
+ startFrame = try dictionary.value(for: CodingKeys.startFrame)
64
+ endFrame = try dictionary.value(for: CodingKeys.endFrame)
65
+ framerate = try dictionary.value(for: CodingKeys.framerate)
66
+ width = try dictionary.value(for: CodingKeys.width)
67
+ height = try dictionary.value(for: CodingKeys.height)
68
+ let layerDictionaries: [[String: Any]] = try dictionary.value(for: CodingKeys.layers)
69
+ layers = try [LayerModel].fromDictionaries(layerDictionaries)
70
+ if let glyphDictionaries = dictionary[CodingKeys.glyphs.rawValue] as? [[String: Any]] {
71
+ glyphs = try glyphDictionaries.map({ try Glyph(dictionary: $0) })
72
+ } else {
73
+ glyphs = nil
74
+ }
75
+ if let fontsDictionary = dictionary[CodingKeys.fonts.rawValue] as? [String: Any] {
76
+ fonts = try FontList(dictionary: fontsDictionary)
77
+ } else {
78
+ fonts = nil
79
+ }
80
+ if let assetLibraryDictionaries = dictionary[CodingKeys.assetLibrary.rawValue] as? [[String: Any]] {
81
+ assetLibrary = try AssetLibrary(value: assetLibraryDictionaries)
82
+ } else {
83
+ assetLibrary = nil
84
+ }
85
+ if let markerDictionaries = dictionary[CodingKeys.markers.rawValue] as? [[String: Any]] {
86
+ let markers = try markerDictionaries.map({ try Marker(dictionary: $0) })
87
+ var markerMap: [String: Marker] = [:]
88
+ for marker in markers {
89
+ markerMap[marker.name] = marker
90
+ }
91
+ self.markers = markers
92
+ self.markerMap = markerMap
93
+ } else {
94
+ markers = nil
95
+ markerMap = nil
96
+ }
97
+ }
98
+
99
+ // MARK: Public
100
+
101
+ /// The start time of the composition in frameTime.
102
+ public let startFrame: AnimationFrameTime
103
+
104
+ /// The end time of the composition in frameTime.
105
+ public let endFrame: AnimationFrameTime
106
+
107
+ /// The frame rate of the composition.
108
+ public let framerate: Double
109
+
110
+ /// Return all marker names, in order, or an empty list if none are specified
111
+ public var markerNames: [String] {
112
+ guard let markers = markers else { return [] }
113
+ return markers.map { $0.name }
114
+ }
115
+
116
+ // MARK: Internal
117
+
118
+ enum CodingKeys: String, CodingKey {
119
+ case version = "v"
120
+ case type = "ddd"
121
+ case startFrame = "ip"
122
+ case endFrame = "op"
123
+ case framerate = "fr"
124
+ case width = "w"
125
+ case height = "h"
126
+ case layers
127
+ case glyphs = "chars"
128
+ case fonts
129
+ case assetLibrary = "assets"
130
+ case markers
131
+ }
132
+
133
+ /// The version of the JSON Schema.
134
+ let version: String
135
+
136
+ /// The coordinate space of the composition.
137
+ let type: CoordinateSpace
138
+
139
+ /// The height of the composition in points.
140
+ let width: Int
141
+
142
+ /// The width of the composition in points.
143
+ let height: Int
144
+
145
+ /// The list of animation layers
146
+ let layers: [LayerModel]
147
+
148
+ /// The list of glyphs used for text rendering
149
+ let glyphs: [Glyph]?
150
+
151
+ /// The list of fonts used for text rendering
152
+ let fonts: FontList?
153
+
154
+ /// Asset Library
155
+ let assetLibrary: AssetLibrary?
156
+
157
+ /// Markers
158
+ let markers: [Marker]?
159
+ let markerMap: [String: Marker]?
160
+ }
@@ -0,0 +1,43 @@
1
+ //
2
+ // Asset.swift
3
+ // lottie-swift
4
+ //
5
+ // Created by Brandon Withrow on 1/9/19.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ public class Asset: Codable, DictionaryInitializable {
11
+
12
+ // MARK: Lifecycle
13
+
14
+ required public init(from decoder: Decoder) throws {
15
+ let container = try decoder.container(keyedBy: Asset.CodingKeys.self)
16
+ if let id = try? container.decode(String.self, forKey: .id) {
17
+ self.id = id
18
+ } else {
19
+ id = String(try container.decode(Int.self, forKey: .id))
20
+ }
21
+ }
22
+
23
+ required init(dictionary: [String: Any]) throws {
24
+ if let id = dictionary[CodingKeys.id.rawValue] as? String {
25
+ self.id = id
26
+ } else if let id = dictionary[CodingKeys.id.rawValue] as? Int {
27
+ self.id = String(id)
28
+ } else {
29
+ throw InitializableError.invalidInput
30
+ }
31
+ }
32
+
33
+ // MARK: Public
34
+
35
+ /// The ID of the asset
36
+ public let id: String
37
+
38
+ // MARK: Private
39
+
40
+ private enum CodingKeys: String, CodingKey {
41
+ case id
42
+ }
43
+ }
@@ -7,23 +7,19 @@
7
7
 
8
8
  import Foundation
9
9
 
10
- final class AssetLibrary: Codable {
11
-
12
- /// The Assets
13
- let assets: [String : Asset]
14
-
15
- let imageAssets: [String : ImageAsset]
16
- let precompAssets: [String : PrecompAsset]
17
-
10
+ final class AssetLibrary: Codable, AnyInitializable {
11
+
12
+ // MARK: Lifecycle
13
+
18
14
  required init(from decoder: Decoder) throws {
19
15
  var container = try decoder.unkeyedContainer()
20
16
  var containerForKeys = container
21
-
17
+
22
18
  var decodedAssets = [String : Asset]()
23
-
19
+
24
20
  var imageAssets = [String : ImageAsset]()
25
21
  var precompAssets = [String : PrecompAsset]()
26
-
22
+
27
23
  while !container.isAtEnd {
28
24
  let keyContainer = try containerForKeys.nestedContainer(keyedBy: PrecompAsset.CodingKeys.self)
29
25
  if keyContainer.contains(.layers) {
@@ -36,11 +32,42 @@ final class AssetLibrary: Codable {
36
32
  imageAssets[imageAsset.id] = imageAsset
37
33
  }
38
34
  }
39
- self.assets = decodedAssets
35
+ assets = decodedAssets
36
+ self.precompAssets = precompAssets
37
+ self.imageAssets = imageAssets
38
+ }
39
+
40
+ init(value: Any) throws {
41
+ guard let dictionaries = value as? [[String: Any]] else {
42
+ throw InitializableError.invalidInput
43
+ }
44
+ var decodedAssets = [String : Asset]()
45
+ var imageAssets = [String : ImageAsset]()
46
+ var precompAssets = [String : PrecompAsset]()
47
+ try dictionaries.forEach { dictionary in
48
+ if dictionary[PrecompAsset.CodingKeys.layers.rawValue] != nil {
49
+ let asset = try PrecompAsset(dictionary: dictionary)
50
+ decodedAssets[asset.id] = asset
51
+ precompAssets[asset.id] = asset
52
+ } else {
53
+ let asset = try ImageAsset(dictionary: dictionary)
54
+ decodedAssets[asset.id] = asset
55
+ imageAssets[asset.id] = asset
56
+ }
57
+ }
58
+ assets = decodedAssets
40
59
  self.precompAssets = precompAssets
41
60
  self.imageAssets = imageAssets
42
61
  }
43
-
62
+
63
+ // MARK: Internal
64
+
65
+ /// The Assets
66
+ let assets: [String: Asset]
67
+
68
+ let imageAssets: [String: ImageAsset]
69
+ let precompAssets: [String: PrecompAsset]
70
+
44
71
  func encode(to encoder: Encoder) throws {
45
72
  var container = encoder.unkeyedContainer()
46
73
  try container.encode(contentsOf: Array(assets.values))
@@ -0,0 +1,112 @@
1
+ //
2
+ // ImageAsset.swift
3
+ // lottie-swift
4
+ //
5
+ // Created by Brandon Withrow on 1/9/19.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ // MARK: - ImageAsset
11
+
12
+ public final class ImageAsset: Asset {
13
+
14
+ // MARK: Lifecycle
15
+
16
+ required init(from decoder: Decoder) throws {
17
+ let container = try decoder.container(keyedBy: ImageAsset.CodingKeys.self)
18
+ name = try container.decode(String.self, forKey: .name)
19
+ directory = try container.decode(String.self, forKey: .directory)
20
+ width = try container.decode(Double.self, forKey: .width)
21
+ height = try container.decode(Double.self, forKey: .height)
22
+ try super.init(from: decoder)
23
+ }
24
+
25
+ required init(dictionary: [String: Any]) throws {
26
+ name = try dictionary.value(for: CodingKeys.name)
27
+ directory = try dictionary.value(for: CodingKeys.directory)
28
+ width = try dictionary.value(for: CodingKeys.width)
29
+ height = try dictionary.value(for: CodingKeys.height)
30
+ try super.init(dictionary: dictionary)
31
+ }
32
+
33
+ // MARK: Public
34
+
35
+ /// Image name
36
+ public let name: String
37
+
38
+ /// Image Directory
39
+ public let directory: String
40
+
41
+ /// Image Size
42
+ public let width: Double
43
+
44
+ public let height: Double
45
+
46
+ override public func encode(to encoder: Encoder) throws {
47
+ try super.encode(to: encoder)
48
+ var container = encoder.container(keyedBy: CodingKeys.self)
49
+ try container.encode(name, forKey: .name)
50
+ try container.encode(directory, forKey: .directory)
51
+ try container.encode(width, forKey: .width)
52
+ try container.encode(height, forKey: .height)
53
+ }
54
+
55
+ // MARK: Internal
56
+
57
+ enum CodingKeys: String, CodingKey {
58
+ case name = "p"
59
+ case directory = "u"
60
+ case width = "w"
61
+ case height = "h"
62
+ }
63
+ }
64
+
65
+ extension Data {
66
+
67
+ // MARK: Lifecycle
68
+
69
+ /// Initializes `Data` from an `ImageAsset`.
70
+ ///
71
+ /// Returns nil when the input is not recognized as valid Data URL.
72
+ /// - parameter imageAsset: The image asset that contains Data URL.
73
+ internal init?(imageAsset: ImageAsset) {
74
+ self.init(dataString: imageAsset.name)
75
+ }
76
+
77
+ /// Initializes `Data` from a [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) String.
78
+ ///
79
+ /// Returns nil when the input is not recognized as valid Data URL.
80
+ /// - parameter dataString: The data string to parse.
81
+ /// - parameter options: Options for the string parsing. Default value is `[]`.
82
+ internal init?(dataString: String, options: DataURLReadOptions = []) {
83
+ guard
84
+ dataString.hasPrefix("data:"),
85
+ let url = URL(string: dataString)
86
+ else {
87
+ return nil
88
+ }
89
+ // The code below is needed because Data(contentsOf:) floods logs
90
+ // with messages since url doesn't have a host. This only fixes flooding logs
91
+ // when data inside Data URL is base64 encoded.
92
+ if
93
+ let base64Range = dataString.range(of: ";base64,"),
94
+ !options.contains(DataURLReadOptions.legacy)
95
+ {
96
+ let encodedString = String(dataString[base64Range.upperBound...])
97
+ self.init(base64Encoded: encodedString)
98
+ } else {
99
+ try? self.init(contentsOf: url)
100
+ }
101
+ }
102
+
103
+ // MARK: Internal
104
+
105
+ internal struct DataURLReadOptions: OptionSet {
106
+ let rawValue: Int
107
+
108
+ /// Will read Data URL using Data(contentsOf:)
109
+ static let legacy = DataURLReadOptions(rawValue: 1 << 0)
110
+ }
111
+
112
+ }