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.
- package/.github/actions/setup/action.yml +32 -0
- package/.github/issue_template.md +6 -23
- package/.github/workflows/main.yml +98 -0
- package/.spi.yml +6 -0
- package/.swift-version +1 -0
- package/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +7 -0
- package/.swiftpm/xcode/package.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/.swiftpm/xcode/xcuserdata/{brandonwithrow.xcuserdatad → cal.xcuserdatad}/xcschemes/xcschememanagement.plist +25 -15
- package/.swiftpm/xcode/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/Gemfile +4 -0
- package/Gemfile.lock +102 -0
- package/Lottie.xcodeproj/project.pbxproj +2003 -1972
- package/Lottie.xcodeproj/project.xcworkspace/contents.xcworkspacedata +1 -1
- package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_iOS.xcscheme → Lottie (iOS).xcscheme } +15 -18
- package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_macOS.xcscheme → Lottie (macOS).xcscheme } +7 -20
- package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_tvOS.xcscheme → Lottie (tvOS).xcscheme } +5 -18
- package/Lottie.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +37 -0
- package/Lottie.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +24 -0
- package/Lottie.xcworkspace/contents.xcworkspacedata +10 -0
- package/Lottie.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +115 -0
- package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/{Lottie.xcodeproj/xcuserdata/brandonwithrow.xcuserdatad → Lottie.xcworkspace/xcuserdata/cal.xcuserdatad}/xcdebugger/Breakpoints_v2.xcbkptlist +2 -2
- package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/xcdebugger/Expressions.xcexplist +153 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +39 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +25 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +30 -0
- package/Package.resolved +88 -0
- package/Package.swift +10 -15
- package/README.md +40 -60
- package/Rakefile +121 -0
- package/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift +81 -0
- package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +448 -0
- package/Sources/Private/CoreAnimation/Animations/CombinedShapeAnimation.swift +53 -0
- package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +41 -0
- package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +28 -0
- package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +210 -0
- package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +229 -0
- package/Sources/Private/CoreAnimation/Animations/OpacityAnimation.swift +52 -0
- package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +31 -0
- package/Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift +246 -0
- package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +95 -0
- package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +70 -0
- package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +205 -0
- package/Sources/Private/CoreAnimation/Animations/VisibilityAnimation.swift +37 -0
- package/Sources/Private/CoreAnimation/CompatibilityTracker.swift +130 -0
- package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +492 -0
- package/Sources/Private/CoreAnimation/Extensions/CALayer+fillBounds.swift +35 -0
- package/Sources/Private/CoreAnimation/Extensions/KeyframeGroup+exactlyOneKeyframe.swift +37 -0
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+combinedIfPossible.swift +73 -0
- package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +83 -0
- package/Sources/Private/CoreAnimation/Layers/BaseAnimationLayer.swift +33 -0
- package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +87 -0
- package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +131 -0
- package/Sources/Private/CoreAnimation/Layers/GradientRenderLayer.swift +94 -0
- package/Sources/Private/CoreAnimation/Layers/ImageLayer.swift +79 -0
- package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +60 -0
- package/Sources/Private/CoreAnimation/Layers/MaskCompositionLayer.swift +138 -0
- package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +140 -0
- package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +302 -0
- package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +319 -0
- package/Sources/Private/CoreAnimation/Layers/SolidLayer.swift +47 -0
- package/Sources/Private/CoreAnimation/Layers/TextLayer.swift +91 -0
- package/Sources/Private/CoreAnimation/Layers/TransformLayer.swift +11 -0
- package/Sources/Private/CoreAnimation/ValueProviderStore.swift +139 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/CompositionLayer.swift +93 -85
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/ImageCompositionLayer.swift +24 -21
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/MaskContainerLayer.swift +75 -54
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/NullCompositionLayer.swift +5 -5
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/PreCompositionLayer.swift +61 -44
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/ShapeCompositionLayer.swift +22 -20
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/SolidCompositionLayer.swift +26 -17
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/CompLayers/TextCompositionLayer.swift +42 -36
- package/{lottie-swift/src/Private/LayerContainers/AnimationContainer.swift → Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift} +200 -140
- package/Sources/Private/MainThread/LayerContainers/Utility/CachedImageProvider.swift +47 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/CompositionLayersInitializer.swift +33 -24
- package/{lottie-swift/src/Private/LayerContainers/Utility/TextLayer.swift → Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift} +120 -106
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/InvertedMatteLayer.swift +25 -24
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerFontProvider.swift +41 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/LayerImageProvider.swift +20 -16
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerTextProvider.swift +40 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/LayerTransformNode.swift +82 -67
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Extensions/ItemsExtension.swift +4 -4
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/NodeProperty.swift +29 -21
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.swift +16 -10
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/AnyValueContainer.swift +6 -6
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.swift +5 -5
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.swift +10 -8
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueContainer.swift +25 -21
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueProviders/GroupInterpolator.swift +23 -17
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.swift +125 -108
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/NodeProperties/ValueProviders/SingleValueProvider.swift +22 -17
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +110 -79
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/GroupOutputNode.swift +22 -16
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.swift +19 -15
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/PathOutputNode.swift +22 -20
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/Renderables/FillRenderer.swift +22 -23
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +242 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientStrokeRenderer.swift +30 -24
- package/{lottie-swift/src/Private/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift → Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift} +93 -66
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +23 -19
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +139 -0
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +170 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/PathNodes/RectNode.swift +95 -58
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/PathNodes/ShapeNode.swift +42 -29
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/PathNodes/StarNode.swift +108 -69
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +155 -0
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/FillNode.swift +51 -37
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +54 -42
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +65 -57
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +84 -58
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +138 -119
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Protocols/AnimatorNode.swift +80 -79
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Protocols/PathNode.swift +5 -3
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Protocols/RenderNode.swift +22 -17
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +27 -24
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/RenderLayers/ShapeRenderLayer.swift +34 -25
- package/Sources/Private/Model/Animation.swift +160 -0
- package/Sources/Private/Model/Assets/Asset.swift +43 -0
- package/{lottie-swift/src → Sources}/Private/Model/Assets/AssetLibrary.swift +40 -13
- package/Sources/Private/Model/Assets/ImageAsset.swift +112 -0
- package/{lottie-swift/src → Sources}/Private/Model/Assets/PrecompAsset.swift +20 -10
- package/Sources/Private/Model/DictionaryInitializable.swift +67 -0
- package/Sources/Private/Model/Extensions/Bundle.swift +34 -0
- package/{lottie-swift/src → Sources}/Private/Model/Extensions/KeyedDecodingContainerExtensions.swift +8 -4
- package/Sources/Private/Model/Keyframes/KeyframeData.swift +113 -0
- package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +197 -0
- package/{lottie-swift/src → Sources}/Private/Model/Layers/ImageLayerModel.swift +21 -11
- package/Sources/Private/Model/Layers/LayerModel.swift +228 -0
- package/{lottie-swift/src → Sources}/Private/Model/Layers/PreCompLayerModel.swift +39 -22
- package/{lottie-swift/src → Sources}/Private/Model/Layers/ShapeLayerModel.swift +23 -12
- package/{lottie-swift/src → Sources}/Private/Model/Layers/SolidLayerModel.swift +31 -19
- package/{lottie-swift/src → Sources}/Private/Model/Layers/TextLayerModel.swift +33 -19
- package/Sources/Private/Model/Objects/DashPattern.swift +44 -0
- package/Sources/Private/Model/Objects/Marker.swift +33 -0
- package/Sources/Private/Model/Objects/Mask.swift +80 -0
- package/Sources/Private/Model/Objects/Transform.swift +179 -0
- package/Sources/Private/Model/ShapeItems/Ellipse.swift +75 -0
- package/Sources/Private/Model/ShapeItems/Fill.swift +74 -0
- package/Sources/Private/Model/ShapeItems/GradientFill.swift +124 -0
- package/Sources/Private/Model/ShapeItems/GradientStroke.swift +186 -0
- package/Sources/Private/Model/ShapeItems/Group.swift +48 -0
- package/{lottie-swift/src → Sources}/Private/Model/ShapeItems/Merge.swift +29 -11
- package/Sources/Private/Model/ShapeItems/Rectangle.swift +73 -0
- package/Sources/Private/Model/ShapeItems/Repeater.swift +136 -0
- package/Sources/Private/Model/ShapeItems/Shape.swift +56 -0
- package/Sources/Private/Model/ShapeItems/ShapeItem.swift +163 -0
- package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +136 -0
- package/Sources/Private/Model/ShapeItems/Star.swift +132 -0
- package/Sources/Private/Model/ShapeItems/Stroke.swift +102 -0
- package/Sources/Private/Model/ShapeItems/Trim.swift +78 -0
- package/Sources/Private/Model/Text/Font.swift +61 -0
- package/{lottie-swift/src → Sources}/Private/Model/Text/Glyph.swift +63 -39
- package/Sources/Private/Model/Text/TextAnimator.swift +164 -0
- package/Sources/Private/Model/Text/TextDocument.swift +123 -0
- package/Sources/Private/RootAnimationLayer.swift +51 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Debugging/AnimatorNodeDebugging.swift +7 -7
- package/{lottie-swift/src → Sources}/Private/Utility/Debugging/LayerDebugging.swift +72 -48
- package/Sources/Private/Utility/Debugging/TestHelpers.swift +10 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Extensions/AnimationKeypathExtension.swift +69 -59
- package/Sources/Private/Utility/Extensions/BlendMode+Filter.swift +31 -0
- package/Sources/Private/Utility/Extensions/CGColor+RGB.swift +22 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Extensions/CGFloatExtensions.swift +70 -67
- package/Sources/Private/Utility/Extensions/DataExtension.swift +27 -0
- package/Sources/Private/Utility/Extensions/MathKit.swift +450 -0
- package/Sources/Private/Utility/Extensions/StringExtensions.swift +38 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Helpers/AnimationContext.swift +42 -16
- package/Sources/Private/Utility/Interpolatable/InterpolatableExtensions.swift +134 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Interpolatable/KeyframeExtensions.swift +13 -10
- package/Sources/Private/Utility/Interpolatable/KeyframeGroup+Extensions.swift +59 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Primitives/BezierPath.swift +229 -143
- package/Sources/Private/Utility/Primitives/CGPointExtension.swift +35 -0
- package/{lottie-swift/src → Sources}/Private/Utility/Primitives/ColorExtension.swift +46 -14
- package/{lottie-swift/src → Sources}/Private/Utility/Primitives/CompoundBezierPath.swift +58 -49
- package/Sources/Private/Utility/Primitives/CurveVertex.swift +184 -0
- package/Sources/Private/Utility/Primitives/PathElement.swift +75 -0
- package/Sources/Private/Utility/Primitives/UnitBezier.swift +115 -0
- package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +341 -0
- package/Sources/Public/Animation/AnimationPublic.swift +266 -0
- package/Sources/Public/Animation/AnimationView.swift +1335 -0
- package/Sources/Public/Animation/AnimationViewInitializers.swift +109 -0
- package/Sources/Public/AnimationCache/AnimationCacheProvider.swift +22 -0
- package/{lottie-swift/src → Sources}/Public/AnimationCache/LRUAnimationCache.swift +22 -18
- package/Sources/Public/DynamicProperties/AnimationKeypath.swift +49 -0
- package/Sources/Public/DynamicProperties/AnyValueProvider.swift +132 -0
- package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/ColorValueProvider.swift +54 -36
- package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/FloatValueProvider.swift +40 -36
- package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +123 -0
- package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/PointValueProvider.swift +40 -35
- package/{lottie-swift/src → Sources}/Public/DynamicProperties/ValueProviders/SizeValueProvider.swift +40 -35
- package/{lottie-swift/src → Sources}/Public/FontProvider/AnimationFontProvider.swift +15 -8
- package/Sources/Public/ImageProvider/AnimationImageProvider.swift +21 -0
- package/Sources/Public/Keyframes/Interpolatable.swift +253 -0
- package/Sources/Public/Keyframes/Keyframe.swift +92 -0
- package/Sources/Public/Logging/LottieLogger.swift +137 -0
- package/Sources/Public/LottieConfiguration.swift +143 -0
- package/{lottie-swift/src → Sources}/Public/Primitives/AnimationTime.swift +1 -1
- package/{lottie-swift/src → Sources}/Public/Primitives/Color.swift +10 -6
- package/{lottie-swift/src → Sources}/Public/Primitives/Vectors.swift +13 -12
- package/Sources/Public/TextProvider/AnimationTextProvider.swift +53 -0
- package/{lottie-swift/src → Sources}/Public/iOS/AnimatedButton.swift +42 -26
- package/{lottie-swift/src → Sources}/Public/iOS/AnimatedControl.swift +100 -91
- package/{lottie-swift/src → Sources}/Public/iOS/AnimatedSwitch.swift +128 -94
- package/{lottie-swift/src → Sources}/Public/iOS/AnimationSubview.swift +3 -3
- package/Sources/Public/iOS/AnimationViewBase.swift +78 -0
- package/{lottie-swift/src → Sources}/Public/iOS/BundleImageProvider.swift +36 -34
- package/{lottie-swift/src → Sources}/Public/iOS/Compatibility/CompatibleAnimationKeypath.swift +4 -0
- package/{lottie-swift/src → Sources}/Public/iOS/Compatibility/CompatibleAnimationView.swift +38 -29
- package/{lottie-swift/src → Sources}/Public/iOS/FilepathImageProvider.swift +24 -21
- package/{lottie-swift/src → Sources}/Public/iOS/UIColorExtension.swift +4 -4
- package/{lottie-swift/src/Public/MacOS/AnimationSubview.swift → Sources/Public/macOS/AnimationSubview.macOS.swift} +4 -5
- package/{lottie-swift/src/Public/MacOS/LottieView.swift → Sources/Public/macOS/AnimationViewBase.macOS.swift} +58 -50
- package/{lottie-swift/src/Public/MacOS/BundleImageProvider.swift → Sources/Public/macOS/BundleImageProvider.macOS.swift} +31 -32
- package/Sources/Public/macOS/FilepathImageProvider.macOS.swift +67 -0
- package/Tests/AnimationKeypathTests.swift +94 -0
- package/Tests/AutomaticEngineTests.swift +57 -0
- package/Tests/BundleTests.swift +25 -0
- package/Tests/DataURLTests.swift +64 -0
- package/Tests/ParsingTests.swift +43 -0
- package/Tests/PerformanceTests.swift +215 -0
- package/Tests/SnapshotConfiguration.swift +153 -0
- package/Tests/SnapshotTests.swift +265 -0
- package/Tests/Utils/Bundle+Module.swift +30 -0
- package/Tests/Utils/HardcodedFontProvider.swift +19 -0
- package/Tests/Utils/HardcodedImageProvider.swift +23 -0
- package/Tests/Utils/Snapshotting+presentationLayer.swift +47 -0
- package/Tests/ValueProvidersTests.swift +27 -0
- package/lottie-ios.podspec +11 -12
- package/package.json +1 -1
- package/script/test-carthage/Cartfile +1 -0
- package/script/test-carthage/Cartfile.resolved +1 -0
- package/script/test-carthage/CarthageTest/AppDelegate.swift +26 -0
- package/script/test-carthage/CarthageTest/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/script/test-carthage/CarthageTest/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
- package/script/test-carthage/CarthageTest/Assets.xcassets/Contents.json +6 -0
- package/script/test-carthage/CarthageTest/Base.lproj/LaunchScreen.storyboard +25 -0
- package/script/test-carthage/CarthageTest/Base.lproj/Main.storyboard +24 -0
- package/script/test-carthage/CarthageTest/Info.plist +66 -0
- package/script/test-carthage/CarthageTest/SceneDelegate.swift +10 -0
- package/script/test-carthage/CarthageTest/ViewController.swift +15 -0
- package/script/test-carthage/CarthageTest-macOS/AppDelegate.swift +7 -0
- package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json +58 -0
- package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/Contents.json +6 -0
- package/script/test-carthage/CarthageTest-macOS/Base.lproj/Main.storyboard +717 -0
- package/script/test-carthage/CarthageTest-macOS/CarthageTest_macOS.entitlements +10 -0
- package/script/test-carthage/CarthageTest-macOS/ViewController.swift +15 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.pbxproj +532 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/script/test-carthage/CarthageTest.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/script/test-carthage/CarthageTest.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +19 -0
- package/script/test-carthage/Mintfile +1 -0
- package/script/test-spm/LottieSPM.xcworkspace/contents.xcworkspacedata +7 -0
- package/script/test-spm/LottieSPM.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/script/test-spm/Mintfile +1 -0
- package/.swiftpm/xcode/package.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie/Info.plist +0 -22
- package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcodeproj/xcuserdata/brandonwithrow.xcuserdatad/xcschemes/LottieLibraryMacOS.xcscheme +0 -80
- package/Lottie.xcodeproj/xcuserdata/brandonwithrow.xcuserdatad/xcschemes/xcschememanagement.plist +0 -57
- package/lottie-swift/Assets/.gitkeep +0 -0
- package/lottie-swift/src/Private/LayerContainers/Utility/LayerFontProvider.swift +0 -37
- package/lottie-swift/src/Private/LayerContainers/Utility/LayerTextProvider.swift +0 -36
- package/lottie-swift/src/Private/Model/Animation.swift +0 -107
- package/lottie-swift/src/Private/Model/Assets/Asset.swift +0 -27
- package/lottie-swift/src/Private/Model/Assets/ImageAsset.swift +0 -48
- package/lottie-swift/src/Private/Model/Keyframes/Keyframe.swift +0 -128
- package/lottie-swift/src/Private/Model/Keyframes/KeyframeGroup.swift +0 -108
- package/lottie-swift/src/Private/Model/Layers/LayerModel.swift +0 -150
- package/lottie-swift/src/Private/Model/Objects/DashPattern.swift +0 -24
- package/lottie-swift/src/Private/Model/Objects/Marker.swift +0 -23
- package/lottie-swift/src/Private/Model/Objects/Mask.swift +0 -48
- package/lottie-swift/src/Private/Model/Objects/Transform.swift +0 -105
- package/lottie-swift/src/Private/Model/ShapeItems/Ellipse.swift +0 -50
- package/lottie-swift/src/Private/Model/ShapeItems/FillI.swift +0 -49
- package/lottie-swift/src/Private/Model/ShapeItems/GradientFill.swift +0 -86
- package/lottie-swift/src/Private/Model/ShapeItems/GradientStroke.swift +0 -125
- package/lottie-swift/src/Private/Model/ShapeItems/Group.swift +0 -32
- package/lottie-swift/src/Private/Model/ShapeItems/Rectangle.swift +0 -50
- package/lottie-swift/src/Private/Model/ShapeItems/Repeater.swift +0 -80
- package/lottie-swift/src/Private/Model/ShapeItems/Shape.swift +0 -37
- package/lottie-swift/src/Private/Model/ShapeItems/ShapeItem.swift +0 -95
- package/lottie-swift/src/Private/Model/ShapeItems/ShapeTransform.swift +0 -68
- package/lottie-swift/src/Private/Model/ShapeItems/Star.swift +0 -86
- package/lottie-swift/src/Private/Model/ShapeItems/Stroke.swift +0 -67
- package/lottie-swift/src/Private/Model/ShapeItems/Trim.swift +0 -53
- package/lottie-swift/src/Private/Model/Text/Font.swift +0 -35
- package/lottie-swift/src/Private/Model/Text/TextAnimator.swift +0 -99
- package/lottie-swift/src/Private/Model/Text/TextDocument.swift +0 -70
- package/lottie-swift/src/Private/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +0 -109
- package/lottie-swift/src/Private/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +0 -132
- package/lottie-swift/src/Private/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +0 -141
- package/lottie-swift/src/Private/Utility/Extensions/MathKit.swift +0 -539
- package/lottie-swift/src/Private/Utility/Extensions/StringExtensions.swift +0 -32
- package/lottie-swift/src/Private/Utility/Interpolatable/Interpolatable.swift +0 -18
- package/lottie-swift/src/Private/Utility/Interpolatable/InterpolatableExtensions.swift +0 -170
- package/lottie-swift/src/Private/Utility/Primitives/CurveVertex.swift +0 -177
- package/lottie-swift/src/Private/Utility/Primitives/PathElement.swift +0 -68
- package/lottie-swift/src/Private/Utility/Primitives/VectorsExtensions.swift +0 -218
- package/lottie-swift/src/Public/Animation/AnimationPublic.swift +0 -196
- package/lottie-swift/src/Public/Animation/AnimationView.swift +0 -1006
- package/lottie-swift/src/Public/Animation/AnimationViewInitializers.swift +0 -83
- package/lottie-swift/src/Public/AnimationCache/AnimationCacheProvider.swift +0 -24
- package/lottie-swift/src/Public/DynamicProperties/AnimationKeypath.swift +0 -46
- package/lottie-swift/src/Public/DynamicProperties/AnyValueProvider.swift +0 -29
- package/lottie-swift/src/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +0 -114
- package/lottie-swift/src/Public/ImageProvider/AnimationImageProvider.swift +0 -23
- package/lottie-swift/src/Public/MacOS/FilepathImageProvider.swift +0 -67
- package/lottie-swift/src/Public/TextProvider/AnimationTextProvider.swift +0 -39
- package/lottie-swift/src/Public/iOS/LottieView.swift +0 -62
- package/lottie-swift-testing.podspec +0 -32
|
@@ -8,20 +8,30 @@
|
|
|
8
8
|
import Foundation
|
|
9
9
|
|
|
10
10
|
final class PrecompAsset: Asset {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
enum CodingKeys : String, CodingKey {
|
|
16
|
-
case layers = "layers"
|
|
17
|
-
}
|
|
18
|
-
|
|
11
|
+
|
|
12
|
+
// MARK: Lifecycle
|
|
13
|
+
|
|
19
14
|
required init(from decoder: Decoder) throws {
|
|
20
15
|
let container = try decoder.container(keyedBy: PrecompAsset.CodingKeys.self)
|
|
21
|
-
|
|
16
|
+
layers = try container.decode([LayerModel].self, ofFamily: LayerType.self, forKey: .layers)
|
|
22
17
|
try super.init(from: decoder)
|
|
23
18
|
}
|
|
24
|
-
|
|
19
|
+
|
|
20
|
+
required init(dictionary: [String: Any]) throws {
|
|
21
|
+
let layerDictionaries: [[String: Any]] = try dictionary.value(for: CodingKeys.layers)
|
|
22
|
+
layers = try [LayerModel].fromDictionaries(layerDictionaries)
|
|
23
|
+
try super.init(dictionary: dictionary)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// MARK: Internal
|
|
27
|
+
|
|
28
|
+
enum CodingKeys: String, CodingKey {
|
|
29
|
+
case layers
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// Layers of the precomp
|
|
33
|
+
let layers: [LayerModel]
|
|
34
|
+
|
|
25
35
|
override func encode(to encoder: Encoder) throws {
|
|
26
36
|
try super.encode(to: encoder)
|
|
27
37
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
//
|
|
2
|
+
// DictionaryInitializable.swift
|
|
3
|
+
// Lottie
|
|
4
|
+
//
|
|
5
|
+
// Created by Marcelo Fabri on 5/5/22.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
// MARK: - InitializableError
|
|
11
|
+
|
|
12
|
+
enum InitializableError: Error {
|
|
13
|
+
case invalidInput
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// MARK: - DictionaryInitializable
|
|
17
|
+
|
|
18
|
+
protocol DictionaryInitializable {
|
|
19
|
+
|
|
20
|
+
init(dictionary: [String: Any]) throws
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// MARK: - AnyInitializable
|
|
25
|
+
|
|
26
|
+
protocol AnyInitializable {
|
|
27
|
+
|
|
28
|
+
init(value: Any) throws
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
extension Dictionary {
|
|
33
|
+
|
|
34
|
+
@_disfavoredOverload
|
|
35
|
+
func value<T, KeyType: RawRepresentable>(for key: KeyType) throws -> T where KeyType.RawValue == Key {
|
|
36
|
+
guard let value = self[key.rawValue] as? T else {
|
|
37
|
+
throw InitializableError.invalidInput
|
|
38
|
+
}
|
|
39
|
+
return value
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func value<T: AnyInitializable, KeyType: RawRepresentable>(for key: KeyType) throws -> T where KeyType.RawValue == Key {
|
|
43
|
+
if let value = self[key.rawValue] as? T {
|
|
44
|
+
return value
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if let value = self[key.rawValue] {
|
|
48
|
+
return try T(value: value)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
throw InitializableError.invalidInput
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// MARK: - Array + AnyInitializable
|
|
57
|
+
|
|
58
|
+
extension Array: AnyInitializable where Element == Double {
|
|
59
|
+
|
|
60
|
+
init(value: Any) throws {
|
|
61
|
+
guard let array = value as? [Double] else {
|
|
62
|
+
throw InitializableError.invalidInput
|
|
63
|
+
}
|
|
64
|
+
self = array
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
#if os(iOS) || os(tvOS) || os(watchOS) || targetEnvironment(macCatalyst)
|
|
3
|
+
import UIKit
|
|
4
|
+
#endif
|
|
5
|
+
|
|
6
|
+
extension Bundle {
|
|
7
|
+
func getAnimationData(_ name: String, subdirectory: String? = nil) throws -> Data? {
|
|
8
|
+
// Check for files in the bundle at the given path
|
|
9
|
+
let name = name.removingJSONSuffix()
|
|
10
|
+
if let url = url(forResource: name, withExtension: "json", subdirectory: subdirectory) {
|
|
11
|
+
return try Data(contentsOf: url)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Check for data assets (not available on macOS)
|
|
15
|
+
#if os(iOS) || os(tvOS) || os(watchOS) || targetEnvironment(macCatalyst)
|
|
16
|
+
let assetKey = subdirectory != nil ? "\(subdirectory ?? "")/\(name)" : name
|
|
17
|
+
return NSDataAsset(name: assetKey, bundle: self)?.data
|
|
18
|
+
#else
|
|
19
|
+
return nil
|
|
20
|
+
#endif
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
extension String {
|
|
25
|
+
fileprivate func removingJSONSuffix() -> String {
|
|
26
|
+
// Allow filenames to be passed with a ".json" extension (but not other extensions)
|
|
27
|
+
// to keep the behavior from Lottie 2.x - instead of failing to load the animation
|
|
28
|
+
guard hasSuffix(".json") else {
|
|
29
|
+
return self
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (self as NSString).deletingPathExtension
|
|
33
|
+
}
|
|
34
|
+
}
|
package/{lottie-swift/src → Sources}/Private/Model/Extensions/KeyedDecodingContainerExtensions.swift
RENAMED
|
@@ -2,30 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
import Foundation
|
|
4
4
|
|
|
5
|
+
// MARK: - ClassFamily
|
|
6
|
+
|
|
5
7
|
/// To support a new class family, create an enum that conforms to this protocol and contains the different types.
|
|
6
8
|
protocol ClassFamily: Decodable {
|
|
7
9
|
/// The discriminator key.
|
|
8
10
|
static var discriminator: Discriminator { get }
|
|
9
|
-
|
|
11
|
+
|
|
10
12
|
/// Returns the class type of the object corresponding to the value.
|
|
11
13
|
func getType() -> AnyObject.Type
|
|
12
14
|
}
|
|
13
15
|
|
|
16
|
+
// MARK: - Discriminator
|
|
17
|
+
|
|
14
18
|
/// Discriminator key enum used to retrieve discriminator fields in JSON payloads.
|
|
15
19
|
enum Discriminator: String, CodingKey {
|
|
16
20
|
case type = "ty"
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
extension KeyedDecodingContainer {
|
|
20
|
-
|
|
24
|
+
|
|
21
25
|
/// Decode a heterogeneous list of objects for a given family.
|
|
22
26
|
/// - Parameters:
|
|
23
27
|
/// - heterogeneousType: The decodable type of the list.
|
|
24
28
|
/// - family: The ClassFamily enum for the type family.
|
|
25
29
|
/// - key: The CodingKey to look up the list in the current container.
|
|
26
30
|
/// - Returns: The resulting list of heterogeneousType elements.
|
|
27
|
-
func decode<T
|
|
28
|
-
var container = try
|
|
31
|
+
func decode<T: Decodable, U: ClassFamily>(_: [T].Type, ofFamily family: U.Type, forKey key: K) throws -> [T] {
|
|
32
|
+
var container = try nestedUnkeyedContainer(forKey: key)
|
|
29
33
|
var list = [T]()
|
|
30
34
|
var tmpContainer = container
|
|
31
35
|
while !container.isAtEnd {
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Keyframe.swift
|
|
3
|
+
// lottie-swift
|
|
4
|
+
//
|
|
5
|
+
// Created by Brandon Withrow on 1/7/19.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import CoreGraphics
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
// MARK: - KeyframeData
|
|
12
|
+
|
|
13
|
+
/// A generic class used to parse and remap keyframe json.
|
|
14
|
+
///
|
|
15
|
+
/// Keyframe json has a couple of different variations and formats depending on the
|
|
16
|
+
/// type of keyframea and also the version of the JSON. By parsing the raw data
|
|
17
|
+
/// we can reconfigure it into a constant format.
|
|
18
|
+
final class KeyframeData<T> {
|
|
19
|
+
|
|
20
|
+
// MARK: Lifecycle
|
|
21
|
+
|
|
22
|
+
init(
|
|
23
|
+
startValue: T?,
|
|
24
|
+
endValue: T?,
|
|
25
|
+
time: AnimationFrameTime?,
|
|
26
|
+
hold: Int?,
|
|
27
|
+
inTangent: Vector2D?,
|
|
28
|
+
outTangent: Vector2D?,
|
|
29
|
+
spatialInTangent: Vector3D?,
|
|
30
|
+
spatialOutTangent: Vector3D?)
|
|
31
|
+
{
|
|
32
|
+
self.startValue = startValue
|
|
33
|
+
self.endValue = endValue
|
|
34
|
+
self.time = time
|
|
35
|
+
self.hold = hold
|
|
36
|
+
self.inTangent = inTangent
|
|
37
|
+
self.outTangent = outTangent
|
|
38
|
+
self.spatialInTangent = spatialInTangent
|
|
39
|
+
self.spatialOutTangent = spatialOutTangent
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// MARK: Internal
|
|
43
|
+
|
|
44
|
+
enum CodingKeys: String, CodingKey {
|
|
45
|
+
case startValue = "s"
|
|
46
|
+
case endValue = "e"
|
|
47
|
+
case time = "t"
|
|
48
|
+
case hold = "h"
|
|
49
|
+
case inTangent = "i"
|
|
50
|
+
case outTangent = "o"
|
|
51
|
+
case spatialInTangent = "ti"
|
|
52
|
+
case spatialOutTangent = "to"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// The start value of the keyframe
|
|
56
|
+
let startValue: T?
|
|
57
|
+
/// The End value of the keyframe. Note: Newer versions animation json do not have this field.
|
|
58
|
+
let endValue: T?
|
|
59
|
+
/// The time in frames of the keyframe.
|
|
60
|
+
let time: AnimationFrameTime?
|
|
61
|
+
/// A hold keyframe freezes interpolation until the next keyframe that is not a hold.
|
|
62
|
+
let hold: Int?
|
|
63
|
+
|
|
64
|
+
/// The in tangent for the time interpolation curve.
|
|
65
|
+
let inTangent: Vector2D?
|
|
66
|
+
/// The out tangent for the time interpolation curve.
|
|
67
|
+
let outTangent: Vector2D?
|
|
68
|
+
|
|
69
|
+
/// The spacial in tangent of the vector.
|
|
70
|
+
let spatialInTangent: Vector3D?
|
|
71
|
+
/// The spacial out tangent of the vector.
|
|
72
|
+
let spatialOutTangent: Vector3D?
|
|
73
|
+
|
|
74
|
+
var isHold: Bool {
|
|
75
|
+
if let hold = hold {
|
|
76
|
+
return hold > 0
|
|
77
|
+
}
|
|
78
|
+
return false
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// MARK: Encodable
|
|
83
|
+
|
|
84
|
+
extension KeyframeData: Encodable where T: Encodable { }
|
|
85
|
+
|
|
86
|
+
// MARK: Decodable
|
|
87
|
+
|
|
88
|
+
extension KeyframeData: Decodable where T: Decodable { }
|
|
89
|
+
|
|
90
|
+
// MARK: DictionaryInitializable
|
|
91
|
+
|
|
92
|
+
extension KeyframeData: DictionaryInitializable where T: AnyInitializable {
|
|
93
|
+
convenience init(dictionary: [String: Any]) throws {
|
|
94
|
+
let startValue = try? dictionary[CodingKeys.startValue.rawValue].flatMap(T.init)
|
|
95
|
+
let endValue = try? dictionary[CodingKeys.endValue.rawValue].flatMap(T.init)
|
|
96
|
+
let time: AnimationFrameTime? = try? dictionary.value(for: CodingKeys.time)
|
|
97
|
+
let hold: Int? = try? dictionary.value(for: CodingKeys.hold)
|
|
98
|
+
let inTangent: Vector2D? = try? dictionary.value(for: CodingKeys.inTangent)
|
|
99
|
+
let outTangent: Vector2D? = try? dictionary.value(for: CodingKeys.outTangent)
|
|
100
|
+
let spatialInTangent: Vector3D? = try? dictionary.value(for: CodingKeys.spatialInTangent)
|
|
101
|
+
let spatialOutTangent: Vector3D? = try? dictionary.value(for: CodingKeys.spatialOutTangent)
|
|
102
|
+
|
|
103
|
+
self.init(
|
|
104
|
+
startValue: startValue,
|
|
105
|
+
endValue: endValue,
|
|
106
|
+
time: time,
|
|
107
|
+
hold: hold,
|
|
108
|
+
inTangent: inTangent,
|
|
109
|
+
outTangent: outTangent,
|
|
110
|
+
spatialInTangent: spatialInTangent,
|
|
111
|
+
spatialOutTangent: spatialOutTangent)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
//
|
|
2
|
+
// KeyframeGroup.swift
|
|
3
|
+
// lottie-swift
|
|
4
|
+
//
|
|
5
|
+
// Created by Brandon Withrow on 1/14/19.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
// MARK: - KeyframeGroup
|
|
11
|
+
|
|
12
|
+
/// Used for coding/decoding a group of Keyframes by type.
|
|
13
|
+
///
|
|
14
|
+
/// Keyframe data is wrapped in a dictionary { "k" : KeyframeData }.
|
|
15
|
+
/// The keyframe data can either be an array of keyframes or, if no animation is present, the raw value.
|
|
16
|
+
/// This helper object is needed to properly decode the json.
|
|
17
|
+
|
|
18
|
+
final class KeyframeGroup<T> {
|
|
19
|
+
|
|
20
|
+
// MARK: Lifecycle
|
|
21
|
+
|
|
22
|
+
init(keyframes: ContiguousArray<Keyframe<T>>) {
|
|
23
|
+
self.keyframes = keyframes
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
init(_ value: T) {
|
|
27
|
+
keyframes = [Keyframe(value)]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// MARK: Internal
|
|
31
|
+
|
|
32
|
+
enum KeyframeWrapperKey: String, CodingKey {
|
|
33
|
+
case keyframeData = "k"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let keyframes: ContiguousArray<Keyframe<T>>
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// MARK: Decodable
|
|
41
|
+
|
|
42
|
+
extension KeyframeGroup: Decodable where T: Decodable {
|
|
43
|
+
convenience init(from decoder: Decoder) throws {
|
|
44
|
+
let container = try decoder.container(keyedBy: KeyframeWrapperKey.self)
|
|
45
|
+
|
|
46
|
+
if let keyframeData: T = try? container.decode(T.self, forKey: .keyframeData) {
|
|
47
|
+
/// Try to decode raw value; No keyframe data.
|
|
48
|
+
self.init(keyframes: [Keyframe<T>(keyframeData)])
|
|
49
|
+
} else {
|
|
50
|
+
// Decode and array of keyframes.
|
|
51
|
+
//
|
|
52
|
+
// Body Movin and Lottie deal with keyframes in different ways.
|
|
53
|
+
//
|
|
54
|
+
// A keyframe object in Body movin defines a span of time with a START
|
|
55
|
+
// and an END, from the current keyframe time to the next keyframe time.
|
|
56
|
+
//
|
|
57
|
+
// A keyframe object in Lottie defines a singular point in time/space.
|
|
58
|
+
// This point has an in-tangent and an out-tangent.
|
|
59
|
+
//
|
|
60
|
+
// To properly decode this we must iterate through keyframes while holding
|
|
61
|
+
// reference to the previous keyframe.
|
|
62
|
+
|
|
63
|
+
var keyframesContainer = try container.nestedUnkeyedContainer(forKey: .keyframeData)
|
|
64
|
+
var keyframes = ContiguousArray<Keyframe<T>>()
|
|
65
|
+
var previousKeyframeData: KeyframeData<T>?
|
|
66
|
+
while !keyframesContainer.isAtEnd {
|
|
67
|
+
// Ensure that Time and Value are present.
|
|
68
|
+
|
|
69
|
+
let keyframeData = try keyframesContainer.decode(KeyframeData<T>.self)
|
|
70
|
+
|
|
71
|
+
guard
|
|
72
|
+
let value: T = keyframeData.startValue ?? previousKeyframeData?.endValue,
|
|
73
|
+
let time = keyframeData.time else
|
|
74
|
+
{
|
|
75
|
+
/// Missing keyframe data. JSON must be corrupt.
|
|
76
|
+
throw DecodingError.dataCorruptedError(
|
|
77
|
+
forKey: KeyframeWrapperKey.keyframeData,
|
|
78
|
+
in: container,
|
|
79
|
+
debugDescription: "Missing keyframe data.")
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
keyframes.append(Keyframe<T>(
|
|
83
|
+
value: value,
|
|
84
|
+
time: AnimationFrameTime(time),
|
|
85
|
+
isHold: keyframeData.isHold,
|
|
86
|
+
inTangent: previousKeyframeData?.inTangent,
|
|
87
|
+
outTangent: keyframeData.outTangent,
|
|
88
|
+
spatialInTangent: previousKeyframeData?.spatialInTangent,
|
|
89
|
+
spatialOutTangent: keyframeData.spatialOutTangent))
|
|
90
|
+
previousKeyframeData = keyframeData
|
|
91
|
+
}
|
|
92
|
+
self.init(keyframes: keyframes)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// MARK: Encodable
|
|
98
|
+
|
|
99
|
+
extension KeyframeGroup: Encodable where T: Encodable {
|
|
100
|
+
func encode(to encoder: Encoder) throws {
|
|
101
|
+
var container = encoder.container(keyedBy: KeyframeWrapperKey.self)
|
|
102
|
+
|
|
103
|
+
if keyframes.count == 1 {
|
|
104
|
+
let keyframe = keyframes[0]
|
|
105
|
+
try container.encode(keyframe.value, forKey: .keyframeData)
|
|
106
|
+
} else {
|
|
107
|
+
var keyframeContainer = container.nestedUnkeyedContainer(forKey: .keyframeData)
|
|
108
|
+
|
|
109
|
+
for i in 1..<keyframes.endIndex {
|
|
110
|
+
let keyframe = keyframes[i - 1]
|
|
111
|
+
let nextKeyframe = keyframes[i]
|
|
112
|
+
let keyframeData = KeyframeData<T>(
|
|
113
|
+
startValue: keyframe.value,
|
|
114
|
+
endValue: nextKeyframe.value,
|
|
115
|
+
time: keyframe.time,
|
|
116
|
+
hold: keyframe.isHold ? 1 : nil,
|
|
117
|
+
inTangent: nextKeyframe.inTangent,
|
|
118
|
+
outTangent: keyframe.outTangent,
|
|
119
|
+
spatialInTangent: nil,
|
|
120
|
+
spatialOutTangent: nil)
|
|
121
|
+
try keyframeContainer.encode(keyframeData)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// MARK: DictionaryInitializable
|
|
128
|
+
|
|
129
|
+
extension KeyframeGroup: DictionaryInitializable where T: AnyInitializable {
|
|
130
|
+
convenience init(dictionary: [String: Any]) throws {
|
|
131
|
+
var keyframes = ContiguousArray<Keyframe<T>>()
|
|
132
|
+
if
|
|
133
|
+
let rawValue = dictionary[KeyframeWrapperKey.keyframeData.rawValue],
|
|
134
|
+
let value = try? T(value: rawValue)
|
|
135
|
+
{
|
|
136
|
+
keyframes = [Keyframe<T>(value)]
|
|
137
|
+
} else {
|
|
138
|
+
var frameDictionaries: [[String: Any]]
|
|
139
|
+
if let singleFrameDictionary = dictionary[KeyframeWrapperKey.keyframeData.rawValue] as? [String: Any] {
|
|
140
|
+
frameDictionaries = [singleFrameDictionary]
|
|
141
|
+
} else {
|
|
142
|
+
frameDictionaries = try dictionary.value(for: KeyframeWrapperKey.keyframeData)
|
|
143
|
+
}
|
|
144
|
+
var previousKeyframeData: KeyframeData<T>?
|
|
145
|
+
for frameDictionary in frameDictionaries {
|
|
146
|
+
let data = try KeyframeData<T>(dictionary: frameDictionary)
|
|
147
|
+
guard
|
|
148
|
+
let value: T = data.startValue ?? previousKeyframeData?.endValue,
|
|
149
|
+
let time = data.time else
|
|
150
|
+
{
|
|
151
|
+
throw InitializableError.invalidInput
|
|
152
|
+
}
|
|
153
|
+
keyframes.append(Keyframe<T>(
|
|
154
|
+
value: value,
|
|
155
|
+
time: time,
|
|
156
|
+
isHold: data.isHold,
|
|
157
|
+
inTangent: previousKeyframeData?.inTangent,
|
|
158
|
+
outTangent: data.outTangent,
|
|
159
|
+
spatialInTangent: previousKeyframeData?.spatialInTangent,
|
|
160
|
+
spatialOutTangent: data.spatialOutTangent))
|
|
161
|
+
previousKeyframeData = data
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
self.init(keyframes: keyframes)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// MARK: Equatable
|
|
170
|
+
|
|
171
|
+
extension KeyframeGroup: Equatable where T: Equatable {
|
|
172
|
+
static func == (_ lhs: KeyframeGroup<T>, _ rhs: KeyframeGroup<T>) -> Bool {
|
|
173
|
+
lhs.keyframes == rhs.keyframes
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// MARK: Hashable
|
|
178
|
+
|
|
179
|
+
extension KeyframeGroup: Hashable where T: Hashable {
|
|
180
|
+
func hash(into hasher: inout Hasher) {
|
|
181
|
+
hasher.combine(keyframes)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
extension Keyframe {
|
|
186
|
+
/// Creates a copy of this `Keyframe` with the same timing data, but a different value
|
|
187
|
+
func withValue<Value>(_ newValue: Value) -> Keyframe<Value> {
|
|
188
|
+
Keyframe<Value>(
|
|
189
|
+
value: newValue,
|
|
190
|
+
time: time,
|
|
191
|
+
isHold: isHold,
|
|
192
|
+
inTangent: inTangent,
|
|
193
|
+
outTangent: outTangent,
|
|
194
|
+
spatialInTangent: spatialInTangent,
|
|
195
|
+
spatialOutTangent: spatialOutTangent)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -9,24 +9,34 @@ import Foundation
|
|
|
9
9
|
|
|
10
10
|
/// A layer that holds an image.
|
|
11
11
|
final class ImageLayerModel: LayerModel {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
private enum CodingKeys : String, CodingKey {
|
|
17
|
-
case referenceID = "refId"
|
|
18
|
-
}
|
|
19
|
-
|
|
12
|
+
|
|
13
|
+
// MARK: Lifecycle
|
|
14
|
+
|
|
20
15
|
required init(from decoder: Decoder) throws {
|
|
21
16
|
let container = try decoder.container(keyedBy: ImageLayerModel.CodingKeys.self)
|
|
22
|
-
|
|
17
|
+
referenceID = try container.decode(String.self, forKey: .referenceID)
|
|
23
18
|
try super.init(from: decoder)
|
|
24
19
|
}
|
|
25
|
-
|
|
20
|
+
|
|
21
|
+
required init(dictionary: [String: Any]) throws {
|
|
22
|
+
referenceID = try dictionary.value(for: CodingKeys.referenceID)
|
|
23
|
+
try super.init(dictionary: dictionary)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// MARK: Internal
|
|
27
|
+
|
|
28
|
+
/// The reference ID of the image.
|
|
29
|
+
let referenceID: String
|
|
30
|
+
|
|
26
31
|
override func encode(to encoder: Encoder) throws {
|
|
27
32
|
try super.encode(to: encoder)
|
|
28
33
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
29
34
|
try container.encode(referenceID, forKey: .referenceID)
|
|
30
35
|
}
|
|
31
|
-
|
|
36
|
+
|
|
37
|
+
// MARK: Private
|
|
38
|
+
|
|
39
|
+
private enum CodingKeys: String, CodingKey {
|
|
40
|
+
case referenceID = "refId"
|
|
41
|
+
}
|
|
32
42
|
}
|