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
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// Created by Cal Stephens on 1/7/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
// MARK: - GradientShapeItem
|
|
7
|
+
|
|
8
|
+
/// A `ShapeItem` that represents a gradient
|
|
9
|
+
protocol GradientShapeItem: OpacityAnimationModel {
|
|
10
|
+
var startPoint: KeyframeGroup<Vector3D> { get }
|
|
11
|
+
var endPoint: KeyframeGroup<Vector3D> { get }
|
|
12
|
+
var gradientType: GradientType { get }
|
|
13
|
+
var numberOfColors: Int { get }
|
|
14
|
+
var colors: KeyframeGroup<[Double]> { get }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// MARK: - GradientFill + GradientShapeItem
|
|
18
|
+
|
|
19
|
+
extension GradientFill: GradientShapeItem { }
|
|
20
|
+
|
|
21
|
+
// MARK: - GradientStroke + GradientShapeItem
|
|
22
|
+
|
|
23
|
+
extension GradientStroke: GradientShapeItem { }
|
|
24
|
+
|
|
25
|
+
// MARK: - GradientRenderLayer + GradientShapeItem
|
|
26
|
+
|
|
27
|
+
extension GradientRenderLayer {
|
|
28
|
+
|
|
29
|
+
// MARK: Internal
|
|
30
|
+
|
|
31
|
+
/// Adds gradient-related animations to this layer, from the given `GradientFill`
|
|
32
|
+
/// - The RGB components and alpha components can have different color stops / locations,
|
|
33
|
+
/// so have to be rendered in separate `CAGradientLayer`s.
|
|
34
|
+
func addGradientAnimations(
|
|
35
|
+
for gradient: GradientShapeItem,
|
|
36
|
+
type: GradientContentType,
|
|
37
|
+
context: LayerAnimationContext) throws
|
|
38
|
+
{
|
|
39
|
+
// We have to set `colors` to a non-nil value with some valid number of colors
|
|
40
|
+
// for the color animation below to have any effect
|
|
41
|
+
colors = .init(
|
|
42
|
+
repeating: CGColor.rgb(0, 0, 0),
|
|
43
|
+
count: gradient.numberOfColors)
|
|
44
|
+
|
|
45
|
+
try addAnimation(
|
|
46
|
+
for: .colors,
|
|
47
|
+
keyframes: gradient.colors.keyframes,
|
|
48
|
+
value: { colorComponents in
|
|
49
|
+
gradient.colorConfiguration(from: colorComponents, type: type).map { $0.color }
|
|
50
|
+
},
|
|
51
|
+
context: context)
|
|
52
|
+
|
|
53
|
+
try addAnimation(
|
|
54
|
+
for: .locations,
|
|
55
|
+
keyframes: gradient.colors.keyframes,
|
|
56
|
+
value: { colorComponents in
|
|
57
|
+
gradient.colorConfiguration(from: colorComponents, type: type).map { $0.location }
|
|
58
|
+
},
|
|
59
|
+
context: context)
|
|
60
|
+
|
|
61
|
+
try addOpacityAnimation(for: gradient, context: context)
|
|
62
|
+
|
|
63
|
+
switch gradient.gradientType {
|
|
64
|
+
case .linear:
|
|
65
|
+
try addLinearGradientAnimations(for: gradient, context: context)
|
|
66
|
+
case .radial:
|
|
67
|
+
try addRadialGradientAnimations(for: gradient, context: context)
|
|
68
|
+
case .none:
|
|
69
|
+
break
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// MARK: Private
|
|
74
|
+
|
|
75
|
+
private func addLinearGradientAnimations(
|
|
76
|
+
for gradient: GradientShapeItem,
|
|
77
|
+
context: LayerAnimationContext)
|
|
78
|
+
throws
|
|
79
|
+
{
|
|
80
|
+
type = .axial
|
|
81
|
+
|
|
82
|
+
try addAnimation(
|
|
83
|
+
for: .startPoint,
|
|
84
|
+
keyframes: gradient.startPoint.keyframes,
|
|
85
|
+
value: { absoluteStartPoint in
|
|
86
|
+
percentBasedPointInBounds(from: absoluteStartPoint.pointValue)
|
|
87
|
+
},
|
|
88
|
+
context: context)
|
|
89
|
+
|
|
90
|
+
try addAnimation(
|
|
91
|
+
for: .endPoint,
|
|
92
|
+
keyframes: gradient.endPoint.keyframes,
|
|
93
|
+
value: { absoluteEndPoint in
|
|
94
|
+
percentBasedPointInBounds(from: absoluteEndPoint.pointValue)
|
|
95
|
+
},
|
|
96
|
+
context: context)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private func addRadialGradientAnimations(for gradient: GradientShapeItem, context: LayerAnimationContext) throws {
|
|
100
|
+
type = .radial
|
|
101
|
+
|
|
102
|
+
// To draw the correct gradients, we have to derive a custom `endPoint`
|
|
103
|
+
// relative to the `startPoint` value. Since calculating the `endPoint`
|
|
104
|
+
// at any given time requires knowing the current `startPoint`,
|
|
105
|
+
// we can't allow them to animate separately.
|
|
106
|
+
let absoluteStartPoint = try gradient.startPoint
|
|
107
|
+
.exactlyOneKeyframe(context: context, description: "gradient startPoint").value.pointValue
|
|
108
|
+
|
|
109
|
+
let absoluteEndPoint = try gradient.endPoint
|
|
110
|
+
.exactlyOneKeyframe(context: context, description: "gradient endPoint").value.pointValue
|
|
111
|
+
|
|
112
|
+
startPoint = percentBasedPointInBounds(from: absoluteStartPoint)
|
|
113
|
+
|
|
114
|
+
let radius = absoluteStartPoint.distanceTo(absoluteEndPoint)
|
|
115
|
+
endPoint = percentBasedPointInBounds(
|
|
116
|
+
from: CGPoint(
|
|
117
|
+
x: absoluteStartPoint.x + radius,
|
|
118
|
+
y: absoluteStartPoint.y + radius))
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// MARK: - GradientContentType
|
|
123
|
+
|
|
124
|
+
/// Each type of gradient that can be constructed from a `GradientShapeItem`
|
|
125
|
+
enum GradientContentType {
|
|
126
|
+
case rgb
|
|
127
|
+
case alpha
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// `colors` and `locations` configuration for a `CAGradientLayer`
|
|
131
|
+
typealias GradientColorConfiguration = [(color: CGColor, location: CGFloat)]
|
|
132
|
+
|
|
133
|
+
extension GradientShapeItem {
|
|
134
|
+
|
|
135
|
+
// MARK: Internal
|
|
136
|
+
|
|
137
|
+
/// Whether or not this `GradientShapeItem` includes an alpha component
|
|
138
|
+
/// that has to be rendered as a separate `CAGradientLayer` from the
|
|
139
|
+
/// layer that renders the rgb color components
|
|
140
|
+
var hasAlphaComponent: Bool {
|
|
141
|
+
for colorComponentsKeyframe in colors.keyframes {
|
|
142
|
+
let colorComponents = colorComponentsKeyframe.value
|
|
143
|
+
let alphaConfiguration = colorConfiguration(from: colorComponents, type: .alpha)
|
|
144
|
+
|
|
145
|
+
let notFullyOpaque = alphaConfiguration.contains(where: { color, _ in
|
|
146
|
+
color.alpha < 0.999
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
if notFullyOpaque {
|
|
150
|
+
return true
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return false
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// MARK: Fileprivate
|
|
158
|
+
|
|
159
|
+
/// Converts the compact `[Double]` color components representation
|
|
160
|
+
/// into an array of `CGColor`s and the location of those colors within the gradient.
|
|
161
|
+
/// - The color components array is a repeating list of `[location, red, green, blue]` values
|
|
162
|
+
/// for each color in the gradient, followed by an optional repeating list of
|
|
163
|
+
/// `[location, alpha]` values that control the colors' alpha values.
|
|
164
|
+
/// - The RGB and alpha values can have different color stops / locations,
|
|
165
|
+
/// so each has to be rendered in a separate `CAGradientLayer`.
|
|
166
|
+
fileprivate func colorConfiguration(
|
|
167
|
+
from colorComponents: [Double],
|
|
168
|
+
type: GradientContentType)
|
|
169
|
+
-> GradientColorConfiguration
|
|
170
|
+
{
|
|
171
|
+
switch type {
|
|
172
|
+
case .rgb:
|
|
173
|
+
precondition(
|
|
174
|
+
colorComponents.count >= numberOfColors * 4,
|
|
175
|
+
"Each color must have RGB components and a location component")
|
|
176
|
+
|
|
177
|
+
// Each group of four `Double` values represents a single `CGColor`,
|
|
178
|
+
// and its relative location within the gradient.
|
|
179
|
+
var colors = GradientColorConfiguration()
|
|
180
|
+
|
|
181
|
+
for colorIndex in 0..<numberOfColors {
|
|
182
|
+
let colorStartIndex = colorIndex * 4
|
|
183
|
+
|
|
184
|
+
let colorLocation = CGFloat(colorComponents[colorStartIndex])
|
|
185
|
+
|
|
186
|
+
let color = CGColor.rgb(
|
|
187
|
+
CGFloat(colorComponents[colorStartIndex + 1]),
|
|
188
|
+
CGFloat(colorComponents[colorStartIndex + 2]),
|
|
189
|
+
CGFloat(colorComponents[colorStartIndex + 3]))
|
|
190
|
+
|
|
191
|
+
colors.append((color: color, location: colorLocation))
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return colors
|
|
195
|
+
|
|
196
|
+
case .alpha:
|
|
197
|
+
// After the rgb color components, there can be arbitrary number of repeating
|
|
198
|
+
// `[alphaLocation, alphaValue]` pairs that define a separate alpha gradient.
|
|
199
|
+
var alphaValues = GradientColorConfiguration()
|
|
200
|
+
|
|
201
|
+
for alphaIndex in stride(from: numberOfColors * 4, to: colorComponents.endIndex, by: 2) {
|
|
202
|
+
let alphaLocation = CGFloat(colorComponents[alphaIndex])
|
|
203
|
+
let alphaValue = CGFloat(colorComponents[alphaIndex + 1])
|
|
204
|
+
alphaValues.append((color: .rgba(0, 0, 0, alphaValue), location: alphaLocation))
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return alphaValues
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// Created by Cal Stephens on 1/11/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
// MARK: - LayerProperty
|
|
7
|
+
|
|
8
|
+
/// A strongly typed value that can be used as the `keyPath` of a `CAAnimation`
|
|
9
|
+
///
|
|
10
|
+
/// Supported key paths and their expected value types are described
|
|
11
|
+
/// at https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/AnimatableProperties/AnimatableProperties.html#//apple_ref/doc/uid/TP40004514-CH11-SW1
|
|
12
|
+
/// and https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/Key-ValueCodingExtensions/Key-ValueCodingExtensions.html
|
|
13
|
+
struct LayerProperty<ValueRepresentation: Equatable> {
|
|
14
|
+
/// The `CALayer` KVC key path that this value should be assigned to
|
|
15
|
+
let caLayerKeypath: String
|
|
16
|
+
|
|
17
|
+
/// The default value of this property on a `CALayer`
|
|
18
|
+
/// - If the keyframe values are just equal to the default value,
|
|
19
|
+
/// then we can improve performance a bit by just not creating
|
|
20
|
+
/// a CAAnimation (since it would be redundant).
|
|
21
|
+
let defaultValue: ValueRepresentation?
|
|
22
|
+
|
|
23
|
+
/// A description of how this property can be customized dynamically
|
|
24
|
+
/// at runtime using `AnimationView.setValueProvider(_:keypath:)`
|
|
25
|
+
let customizableProperty: CustomizableProperty<ValueRepresentation>?
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// MARK: - CustomizableProperty
|
|
29
|
+
|
|
30
|
+
/// A description of how a `CALayer` property can be customized dynamically
|
|
31
|
+
/// at runtime using `AnimationView.setValueProvider(_:keypath:)`
|
|
32
|
+
struct CustomizableProperty<ValueRepresentation> {
|
|
33
|
+
/// The name that `AnimationKeypath`s can use to refer to this property
|
|
34
|
+
/// - When building an animation for this property that will be applied
|
|
35
|
+
/// to a specific layer, this `name` is appended to the end of that
|
|
36
|
+
/// layer's `AnimationKeypath`. The combined keypath is used to query
|
|
37
|
+
/// the `ValueProviderStore`.
|
|
38
|
+
let name: [PropertyName]
|
|
39
|
+
|
|
40
|
+
/// A closure that coverts the type-erased value of an `AnyValueProvider`
|
|
41
|
+
/// to the strongly-typed representation used by this property, if possible.
|
|
42
|
+
let conversion: (Any) -> ValueRepresentation?
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// MARK: - PropertyName
|
|
46
|
+
|
|
47
|
+
/// The name of a customizable property that can be used in an `AnimationKeypath`
|
|
48
|
+
/// - These values should be shared between the two rendering engines,
|
|
49
|
+
/// since they form the public API of the `AnimationKeypath` system.
|
|
50
|
+
enum PropertyName: String {
|
|
51
|
+
case color = "Color"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// MARK: CALayer properties
|
|
55
|
+
|
|
56
|
+
extension LayerProperty {
|
|
57
|
+
static var position: LayerProperty<CGPoint> {
|
|
58
|
+
.init(
|
|
59
|
+
caLayerKeypath: "transform.translation",
|
|
60
|
+
defaultValue: CGPoint(x: 0, y: 0),
|
|
61
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static var positionX: LayerProperty<CGFloat> {
|
|
65
|
+
.init(
|
|
66
|
+
caLayerKeypath: "transform.translation.x",
|
|
67
|
+
defaultValue: 0,
|
|
68
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static var positionY: LayerProperty<CGFloat> {
|
|
72
|
+
.init(
|
|
73
|
+
caLayerKeypath: "transform.translation.y",
|
|
74
|
+
defaultValue: 0,
|
|
75
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static var scale: LayerProperty<CGFloat> {
|
|
79
|
+
.init(
|
|
80
|
+
caLayerKeypath: "transform.scale",
|
|
81
|
+
defaultValue: 1,
|
|
82
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static var scaleX: LayerProperty<CGFloat> {
|
|
86
|
+
.init(
|
|
87
|
+
caLayerKeypath: "transform.scale.x",
|
|
88
|
+
defaultValue: 1,
|
|
89
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static var scaleY: LayerProperty<CGFloat> {
|
|
93
|
+
.init(
|
|
94
|
+
caLayerKeypath: "transform.scale.y",
|
|
95
|
+
defaultValue: 1,
|
|
96
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static var rotation: LayerProperty<CGFloat> {
|
|
100
|
+
.init(
|
|
101
|
+
caLayerKeypath: "transform.rotation",
|
|
102
|
+
defaultValue: 0,
|
|
103
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static var rotationY: LayerProperty<CGFloat> {
|
|
107
|
+
.init(
|
|
108
|
+
caLayerKeypath: "transform.rotation.y",
|
|
109
|
+
defaultValue: 0,
|
|
110
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static var anchorPoint: LayerProperty<CGPoint> {
|
|
114
|
+
.init(
|
|
115
|
+
caLayerKeypath: #keyPath(CALayer.anchorPoint),
|
|
116
|
+
// This is intentionally not `GGPoint(x: 0.5, y: 0.5)` (the actual default)
|
|
117
|
+
// to opt `anchorPoint` out of the KVC `setValue` flow, which causes issues.
|
|
118
|
+
defaultValue: nil,
|
|
119
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static var opacity: LayerProperty<CGFloat> {
|
|
123
|
+
.init(
|
|
124
|
+
caLayerKeypath: #keyPath(CALayer.opacity),
|
|
125
|
+
defaultValue: 1,
|
|
126
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// MARK: CAShapeLayer properties
|
|
131
|
+
|
|
132
|
+
extension LayerProperty {
|
|
133
|
+
static var path: LayerProperty<CGPath> {
|
|
134
|
+
.init(
|
|
135
|
+
caLayerKeypath: #keyPath(CAShapeLayer.path),
|
|
136
|
+
defaultValue: nil,
|
|
137
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static var fillColor: LayerProperty<CGColor> {
|
|
141
|
+
.init(
|
|
142
|
+
caLayerKeypath: #keyPath(CAShapeLayer.fillColor),
|
|
143
|
+
defaultValue: nil,
|
|
144
|
+
customizableProperty: .color)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static var lineWidth: LayerProperty<CGFloat> {
|
|
148
|
+
.init(
|
|
149
|
+
caLayerKeypath: #keyPath(CAShapeLayer.lineWidth),
|
|
150
|
+
defaultValue: 1,
|
|
151
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static var lineDashPhase: LayerProperty<CGFloat> {
|
|
155
|
+
.init(
|
|
156
|
+
caLayerKeypath: #keyPath(CAShapeLayer.lineDashPhase),
|
|
157
|
+
defaultValue: 0,
|
|
158
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static var strokeColor: LayerProperty<CGColor> {
|
|
162
|
+
.init(
|
|
163
|
+
caLayerKeypath: #keyPath(CAShapeLayer.strokeColor),
|
|
164
|
+
defaultValue: nil,
|
|
165
|
+
customizableProperty: .color)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static var strokeStart: LayerProperty<CGFloat> {
|
|
169
|
+
.init(
|
|
170
|
+
caLayerKeypath: #keyPath(CAShapeLayer.strokeStart),
|
|
171
|
+
defaultValue: 0,
|
|
172
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
static var strokeEnd: LayerProperty<CGFloat> {
|
|
176
|
+
.init(
|
|
177
|
+
caLayerKeypath: #keyPath(CAShapeLayer.strokeEnd),
|
|
178
|
+
defaultValue: 1,
|
|
179
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// MARK: CAGradientLayer properties
|
|
184
|
+
|
|
185
|
+
extension LayerProperty {
|
|
186
|
+
static var colors: LayerProperty<[CGColor]> {
|
|
187
|
+
.init(
|
|
188
|
+
caLayerKeypath: #keyPath(CAGradientLayer.colors),
|
|
189
|
+
defaultValue: nil,
|
|
190
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
static var locations: LayerProperty<[CGFloat]> {
|
|
194
|
+
.init(
|
|
195
|
+
caLayerKeypath: #keyPath(CAGradientLayer.locations),
|
|
196
|
+
defaultValue: nil,
|
|
197
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static var startPoint: LayerProperty<CGPoint> {
|
|
201
|
+
.init(
|
|
202
|
+
caLayerKeypath: #keyPath(CAGradientLayer.startPoint),
|
|
203
|
+
defaultValue: nil,
|
|
204
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static var endPoint: LayerProperty<CGPoint> {
|
|
208
|
+
.init(
|
|
209
|
+
caLayerKeypath: #keyPath(CAGradientLayer.endPoint),
|
|
210
|
+
defaultValue: nil,
|
|
211
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// MARK: - CustomizableProperty types
|
|
216
|
+
|
|
217
|
+
extension CustomizableProperty {
|
|
218
|
+
static var color: CustomizableProperty<CGColor> {
|
|
219
|
+
.init(
|
|
220
|
+
name: [.color],
|
|
221
|
+
conversion: { typeErasedValue in
|
|
222
|
+
guard let color = typeErasedValue as? Color else {
|
|
223
|
+
return nil
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return .rgba(CGFloat(color.r), CGFloat(color.g), CGFloat(color.b), CGFloat(color.a))
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Created by Cal Stephens on 5/17/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
// MARK: - OpacityAnimationModel
|
|
7
|
+
|
|
8
|
+
protocol OpacityAnimationModel {
|
|
9
|
+
/// The opacity animation to apply to a `CALayer`
|
|
10
|
+
var opacity: KeyframeGroup<Vector1D> { get }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// MARK: - Transform + OpacityAnimationModel
|
|
14
|
+
|
|
15
|
+
extension Transform: OpacityAnimationModel { }
|
|
16
|
+
|
|
17
|
+
// MARK: - ShapeTransform + OpacityAnimationModel
|
|
18
|
+
|
|
19
|
+
extension ShapeTransform: OpacityAnimationModel { }
|
|
20
|
+
|
|
21
|
+
// MARK: - Fill + OpacityAnimationModel
|
|
22
|
+
|
|
23
|
+
extension Fill: OpacityAnimationModel { }
|
|
24
|
+
|
|
25
|
+
// MARK: - GradientFill + OpacityAnimationModel
|
|
26
|
+
|
|
27
|
+
extension GradientFill: OpacityAnimationModel { }
|
|
28
|
+
|
|
29
|
+
// MARK: - Stroke + OpacityAnimationModel
|
|
30
|
+
|
|
31
|
+
extension Stroke: OpacityAnimationModel { }
|
|
32
|
+
|
|
33
|
+
// MARK: - GradientStroke + OpacityAnimationModel
|
|
34
|
+
|
|
35
|
+
extension GradientStroke: OpacityAnimationModel { }
|
|
36
|
+
|
|
37
|
+
extension CALayer {
|
|
38
|
+
/// Adds the opacity animation from the given `OpacityAnimationModel` to this layer
|
|
39
|
+
@nonobjc
|
|
40
|
+
func addOpacityAnimation(for opacity: OpacityAnimationModel, context: LayerAnimationContext) throws {
|
|
41
|
+
try addAnimation(
|
|
42
|
+
for: .opacity,
|
|
43
|
+
keyframes: opacity.opacity.keyframes,
|
|
44
|
+
value: {
|
|
45
|
+
// Lottie animation files express opacity as a numerical percentage value
|
|
46
|
+
// (e.g. 0%, 50%, 100%) so we divide by 100 to get the decimal values
|
|
47
|
+
// expected by Core Animation (e.g. 0.0, 0.5, 1.0).
|
|
48
|
+
$0.cgFloatValue / 100
|
|
49
|
+
},
|
|
50
|
+
context: context)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Created by Cal Stephens on 12/21/21.
|
|
2
|
+
// Copyright © 2021 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
extension CAShapeLayer {
|
|
7
|
+
/// Adds animations for the given `Rectangle` to this `CALayer`
|
|
8
|
+
@nonobjc
|
|
9
|
+
func addAnimations(
|
|
10
|
+
for rectangle: Rectangle,
|
|
11
|
+
context: LayerAnimationContext,
|
|
12
|
+
pathMultiplier: PathMultiplier)
|
|
13
|
+
throws
|
|
14
|
+
{
|
|
15
|
+
try addAnimation(
|
|
16
|
+
for: .path,
|
|
17
|
+
keyframes: rectangle.size.keyframes,
|
|
18
|
+
value: { sizeKeyframe in
|
|
19
|
+
BezierPath.rectangle(
|
|
20
|
+
position: try rectangle.position
|
|
21
|
+
.exactlyOneKeyframe(context: context, description: "rectangle position").value.pointValue,
|
|
22
|
+
size: sizeKeyframe.sizeValue,
|
|
23
|
+
cornerRadius: try rectangle.cornerRadius
|
|
24
|
+
.exactlyOneKeyframe(context: context, description: "rectangle cornerRadius").value.cgFloatValue,
|
|
25
|
+
direction: rectangle.direction)
|
|
26
|
+
.cgPath()
|
|
27
|
+
.duplicated(times: pathMultiplier)
|
|
28
|
+
},
|
|
29
|
+
context: context)
|
|
30
|
+
}
|
|
31
|
+
}
|