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,75 +8,85 @@
|
|
|
8
8
|
import Foundation
|
|
9
9
|
import QuartzCore
|
|
10
10
|
|
|
11
|
+
// MARK: - TrimPathProperties
|
|
12
|
+
|
|
11
13
|
final class TrimPathProperties: NodePropertyMap, KeypathSearchable {
|
|
12
|
-
|
|
14
|
+
|
|
15
|
+
// MARK: Lifecycle
|
|
16
|
+
|
|
13
17
|
init(trim: Trim) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
keypathName = trim.name
|
|
19
|
+
start = NodeProperty(provider: KeyframeInterpolator(keyframes: trim.start.keyframes))
|
|
20
|
+
end = NodeProperty(provider: KeyframeInterpolator(keyframes: trim.end.keyframes))
|
|
21
|
+
offset = NodeProperty(provider: KeyframeInterpolator(keyframes: trim.offset.keyframes))
|
|
22
|
+
type = trim.trimType
|
|
23
|
+
keypathProperties = [
|
|
20
24
|
"Start" : start,
|
|
21
25
|
"End" : end,
|
|
22
|
-
"Offset" : offset
|
|
26
|
+
"Offset" : offset,
|
|
23
27
|
]
|
|
24
|
-
|
|
28
|
+
properties = Array(keypathProperties.values)
|
|
25
29
|
}
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
|
|
31
|
+
// MARK: Internal
|
|
32
|
+
|
|
33
|
+
let keypathProperties: [String: AnyNodeProperty]
|
|
28
34
|
let properties: [AnyNodeProperty]
|
|
29
35
|
let keypathName: String
|
|
30
|
-
|
|
36
|
+
|
|
31
37
|
let start: NodeProperty<Vector1D>
|
|
32
38
|
let end: NodeProperty<Vector1D>
|
|
33
39
|
let offset: NodeProperty<Vector1D>
|
|
34
40
|
let type: TrimType
|
|
35
41
|
}
|
|
36
42
|
|
|
43
|
+
// MARK: - TrimPathNode
|
|
44
|
+
|
|
37
45
|
final class TrimPathNode: AnimatorNode {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
fileprivate let upstreamPaths: [PathOutputNode]
|
|
42
|
-
|
|
46
|
+
|
|
47
|
+
// MARK: Lifecycle
|
|
48
|
+
|
|
43
49
|
init(parentNode: AnimatorNode?, trim: Trim, upstreamPaths: [PathOutputNode]) {
|
|
44
|
-
|
|
50
|
+
outputNode = PassThroughOutputNode(parent: parentNode?.outputNode)
|
|
45
51
|
self.parentNode = parentNode
|
|
46
|
-
|
|
52
|
+
properties = TrimPathProperties(trim: trim)
|
|
47
53
|
self.upstreamPaths = upstreamPaths
|
|
48
54
|
}
|
|
49
|
-
|
|
50
|
-
// MARK:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
|
|
56
|
+
// MARK: Internal
|
|
57
|
+
|
|
58
|
+
let properties: TrimPathProperties
|
|
59
|
+
|
|
55
60
|
let parentNode: AnimatorNode?
|
|
56
61
|
let outputNode: NodeOutput
|
|
57
|
-
var hasLocalUpdates
|
|
58
|
-
var hasUpstreamUpdates
|
|
62
|
+
var hasLocalUpdates = false
|
|
63
|
+
var hasUpstreamUpdates = false
|
|
59
64
|
var lastUpdateFrame: CGFloat? = nil
|
|
60
|
-
var isEnabled
|
|
61
|
-
|
|
65
|
+
var isEnabled = true
|
|
66
|
+
|
|
67
|
+
// MARK: Animator Node
|
|
68
|
+
var propertyMap: NodePropertyMap & KeypathSearchable {
|
|
69
|
+
properties
|
|
70
|
+
}
|
|
71
|
+
|
|
62
72
|
func forceUpstreamOutputUpdates() -> Bool {
|
|
63
|
-
|
|
73
|
+
hasLocalUpdates || hasUpstreamUpdates
|
|
64
74
|
}
|
|
65
|
-
|
|
75
|
+
|
|
66
76
|
func rebuildOutputs(frame: CGFloat) {
|
|
67
77
|
/// Make sure there is a trim.
|
|
68
|
-
let startValue = properties.start.value.cgFloatValue
|
|
78
|
+
let startValue = properties.start.value.cgFloatValue * 0.01
|
|
69
79
|
let endValue = properties.end.value.cgFloatValue * 0.01
|
|
70
80
|
let start = min(startValue, endValue)
|
|
71
81
|
let end = max(startValue, endValue)
|
|
72
|
-
|
|
82
|
+
|
|
73
83
|
let offset = properties.offset.value.cgFloatValue.truncatingRemainder(dividingBy: 360) / 360
|
|
74
|
-
|
|
84
|
+
|
|
75
85
|
/// No need to trim, it's a full path
|
|
76
86
|
if start == 0, end == 1 {
|
|
77
87
|
return
|
|
78
88
|
}
|
|
79
|
-
|
|
89
|
+
|
|
80
90
|
/// All paths are empty.
|
|
81
91
|
if start == end {
|
|
82
92
|
for pathContainer in upstreamPaths {
|
|
@@ -84,31 +94,33 @@ final class TrimPathNode: AnimatorNode {
|
|
|
84
94
|
}
|
|
85
95
|
return
|
|
86
96
|
}
|
|
87
|
-
|
|
97
|
+
|
|
88
98
|
if properties.type == .simultaneously {
|
|
89
99
|
/// Just trim each path
|
|
90
100
|
for pathContainer in upstreamPaths {
|
|
91
101
|
let pathObjects = pathContainer.removePaths(updateFrame: frame)
|
|
92
102
|
for path in pathObjects {
|
|
93
103
|
// We are treating each compount path as an individual path. Its subpaths are treated as a whole.
|
|
94
|
-
pathContainer.appendPath(
|
|
104
|
+
pathContainer.appendPath(
|
|
105
|
+
path.trim(fromPosition: start, toPosition: end, offset: offset, trimSimultaneously: false),
|
|
106
|
+
updateFrame: frame)
|
|
95
107
|
}
|
|
96
108
|
}
|
|
97
109
|
return
|
|
98
110
|
}
|
|
99
|
-
|
|
111
|
+
|
|
100
112
|
/// Individual path trimming.
|
|
101
|
-
|
|
113
|
+
|
|
102
114
|
/// Brace yourself for the below code.
|
|
103
|
-
|
|
115
|
+
|
|
104
116
|
/// Normalize lengths with offset.
|
|
105
|
-
var startPosition = (start+offset).truncatingRemainder(dividingBy: 1)
|
|
106
|
-
var endPosition =
|
|
107
|
-
|
|
117
|
+
var startPosition = (start + offset).truncatingRemainder(dividingBy: 1)
|
|
118
|
+
var endPosition = (end + offset).truncatingRemainder(dividingBy: 1)
|
|
119
|
+
|
|
108
120
|
if startPosition < 0 {
|
|
109
121
|
startPosition = 1 + startPosition
|
|
110
122
|
}
|
|
111
|
-
|
|
123
|
+
|
|
112
124
|
if endPosition < 0 {
|
|
113
125
|
endPosition = 1 + endPosition
|
|
114
126
|
}
|
|
@@ -118,27 +130,27 @@ final class TrimPathNode: AnimatorNode {
|
|
|
118
130
|
if endPosition == 0 {
|
|
119
131
|
endPosition = 1
|
|
120
132
|
}
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
|
|
123
134
|
/// First get the total length of all paths.
|
|
124
135
|
var totalLength: CGFloat = 0
|
|
125
136
|
upstreamPaths.forEach({ totalLength = totalLength + $0.totalLength })
|
|
126
|
-
|
|
137
|
+
|
|
127
138
|
/// Now determine the start and end cut lengths
|
|
128
139
|
let startLength = startPosition * totalLength
|
|
129
140
|
let endLength = endPosition * totalLength
|
|
130
141
|
var pathStart: CGFloat = 0
|
|
131
|
-
|
|
142
|
+
|
|
132
143
|
/// Now loop through all path containers
|
|
133
144
|
for pathContainer in upstreamPaths {
|
|
134
|
-
|
|
135
145
|
let pathEnd = pathStart + pathContainer.totalLength
|
|
136
|
-
|
|
137
|
-
if
|
|
138
|
-
|
|
146
|
+
|
|
147
|
+
if
|
|
148
|
+
!startLength.isInRange(pathStart, pathEnd) &&
|
|
149
|
+
endLength.isInRange(pathStart, pathEnd)
|
|
150
|
+
{
|
|
139
151
|
// pathStart|=======E----------------------|pathEnd
|
|
140
152
|
// Cut path components, removing after end.
|
|
141
|
-
|
|
153
|
+
|
|
142
154
|
let pathCutLength = endLength - pathStart
|
|
143
155
|
let subpaths = pathContainer.removePaths(updateFrame: frame)
|
|
144
156
|
var subpathStart: CGFloat = 0
|
|
@@ -160,12 +172,14 @@ final class TrimPathNode: AnimatorNode {
|
|
|
160
172
|
}
|
|
161
173
|
subpathStart = subpathEnd
|
|
162
174
|
}
|
|
163
|
-
|
|
164
|
-
} else if
|
|
165
|
-
|
|
175
|
+
|
|
176
|
+
} else if
|
|
177
|
+
!endLength.isInRange(pathStart, pathEnd) &&
|
|
178
|
+
startLength.isInRange(pathStart, pathEnd)
|
|
179
|
+
{
|
|
166
180
|
// pathStart|-------S======================|pathEnd
|
|
167
181
|
//
|
|
168
|
-
|
|
182
|
+
|
|
169
183
|
// Cut path components, removing before beginning.
|
|
170
184
|
let pathCutLength = startLength - pathStart
|
|
171
185
|
// Clear paths from container
|
|
@@ -173,7 +187,7 @@ final class TrimPathNode: AnimatorNode {
|
|
|
173
187
|
var subpathStart: CGFloat = 0
|
|
174
188
|
for path in subpaths {
|
|
175
189
|
let subpathEnd = subpathStart + path.length
|
|
176
|
-
|
|
190
|
+
|
|
177
191
|
if subpathStart < pathCutLength, pathCutLength < subpathEnd {
|
|
178
192
|
/// This is the subpath that needs to be cut.
|
|
179
193
|
let cutLength = pathCutLength - subpathStart
|
|
@@ -184,12 +198,14 @@ final class TrimPathNode: AnimatorNode {
|
|
|
184
198
|
}
|
|
185
199
|
subpathStart = subpathEnd
|
|
186
200
|
}
|
|
187
|
-
} else if
|
|
188
|
-
|
|
201
|
+
} else if
|
|
202
|
+
endLength.isInRange(pathStart, pathEnd) &&
|
|
203
|
+
startLength.isInRange(pathStart, pathEnd)
|
|
204
|
+
{
|
|
189
205
|
// pathStart|-------S============E---------|endLength
|
|
190
206
|
// pathStart|=====E----------------S=======|endLength
|
|
191
207
|
// trim from path beginning to endLength.
|
|
192
|
-
|
|
208
|
+
|
|
193
209
|
// Cut path components, removing before beginnings.
|
|
194
210
|
let startCutLength = startLength - pathStart
|
|
195
211
|
let endCutLength = endLength - pathStart
|
|
@@ -197,51 +213,66 @@ final class TrimPathNode: AnimatorNode {
|
|
|
197
213
|
let subpaths = pathContainer.removePaths(updateFrame: frame)
|
|
198
214
|
var subpathStart: CGFloat = 0
|
|
199
215
|
for path in subpaths {
|
|
200
|
-
|
|
201
216
|
let subpathEnd = subpathStart + path.length
|
|
202
|
-
|
|
203
|
-
if
|
|
204
|
-
!
|
|
217
|
+
|
|
218
|
+
if
|
|
219
|
+
!startCutLength.isInRange(subpathStart, subpathEnd),
|
|
220
|
+
!endCutLength.isInRange(subpathStart, subpathEnd)
|
|
221
|
+
{
|
|
205
222
|
// The whole path is included. Add
|
|
206
223
|
// S|==============================|E
|
|
207
224
|
pathContainer.appendPath(path, updateFrame: frame)
|
|
208
|
-
|
|
209
|
-
} else if
|
|
210
|
-
|
|
225
|
+
|
|
226
|
+
} else if
|
|
227
|
+
startCutLength.isInRange(subpathStart, subpathEnd),
|
|
228
|
+
!endCutLength.isInRange(subpathStart, subpathEnd)
|
|
229
|
+
{
|
|
211
230
|
/// The start of the path needs to be trimmed
|
|
212
231
|
// |-------S======================|E
|
|
213
232
|
let cutLength = startCutLength - subpathStart
|
|
214
233
|
let newPath = path.trim(fromPosition: cutLength / path.length, toPosition: 1, offset: 0, trimSimultaneously: false)
|
|
215
234
|
pathContainer.appendPath(newPath, updateFrame: frame)
|
|
216
|
-
} else if
|
|
217
|
-
|
|
235
|
+
} else if
|
|
236
|
+
!startCutLength.isInRange(subpathStart, subpathEnd),
|
|
237
|
+
endCutLength.isInRange(subpathStart, subpathEnd)
|
|
238
|
+
{
|
|
218
239
|
// S|=======E----------------------|
|
|
219
240
|
let cutLength = endCutLength - subpathStart
|
|
220
241
|
let newPath = path.trim(fromPosition: 0, toPosition: cutLength / path.length, offset: 0, trimSimultaneously: false)
|
|
221
242
|
pathContainer.appendPath(newPath, updateFrame: frame)
|
|
222
243
|
break
|
|
223
|
-
} else if
|
|
224
|
-
|
|
244
|
+
} else if
|
|
245
|
+
startCutLength.isInRange(subpathStart, subpathEnd),
|
|
246
|
+
endCutLength.isInRange(subpathStart, subpathEnd)
|
|
247
|
+
{
|
|
225
248
|
// |-------S============E---------|
|
|
226
249
|
let cutFromLength = startCutLength - subpathStart
|
|
227
250
|
let cutToLength = endCutLength - subpathStart
|
|
228
|
-
let newPath = path.trim(
|
|
251
|
+
let newPath = path.trim(
|
|
252
|
+
fromPosition: cutFromLength / path.length,
|
|
253
|
+
toPosition: cutToLength / path.length,
|
|
254
|
+
offset: 0,
|
|
255
|
+
trimSimultaneously: false)
|
|
229
256
|
pathContainer.appendPath(newPath, updateFrame: frame)
|
|
230
257
|
break
|
|
231
258
|
}
|
|
232
|
-
|
|
259
|
+
|
|
233
260
|
subpathStart = subpathEnd
|
|
234
261
|
}
|
|
235
|
-
} else if
|
|
262
|
+
} else if
|
|
263
|
+
(endLength <= pathStart && pathEnd <= startLength) ||
|
|
236
264
|
(startLength <= pathStart && endLength <= pathStart) ||
|
|
237
|
-
(pathEnd <= startLength && pathEnd <= endLength)
|
|
265
|
+
(pathEnd <= startLength && pathEnd <= endLength)
|
|
266
|
+
{
|
|
238
267
|
/// The Path needs to be cleared
|
|
239
268
|
pathContainer.removePaths(updateFrame: frame)
|
|
240
269
|
}
|
|
241
|
-
|
|
270
|
+
|
|
242
271
|
pathStart = pathEnd
|
|
243
272
|
}
|
|
244
|
-
|
|
245
273
|
}
|
|
246
|
-
|
|
274
|
+
|
|
275
|
+
// MARK: Fileprivate
|
|
276
|
+
|
|
277
|
+
fileprivate let upstreamPaths: [PathOutputNode]
|
|
247
278
|
}
|
|
@@ -5,25 +5,29 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/30/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
8
|
import CoreGraphics
|
|
9
|
+
import Foundation
|
|
10
10
|
import QuartzCore
|
|
11
11
|
|
|
12
12
|
class GroupOutputNode: NodeOutput {
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
// MARK: Lifecycle
|
|
15
|
+
|
|
14
16
|
init(parent: NodeOutput?, rootNode: NodeOutput?) {
|
|
15
17
|
self.parent = parent
|
|
16
18
|
self.rootNode = rootNode
|
|
17
19
|
}
|
|
18
|
-
|
|
20
|
+
|
|
21
|
+
// MARK: Internal
|
|
22
|
+
|
|
19
23
|
let parent: NodeOutput?
|
|
20
24
|
let rootNode: NodeOutput?
|
|
21
|
-
var isEnabled
|
|
22
|
-
|
|
25
|
+
var isEnabled = true
|
|
26
|
+
|
|
23
27
|
private(set) var outputPath: CGPath? = nil
|
|
24
28
|
private(set) var transform: CATransform3D = CATransform3DIdentity
|
|
25
|
-
|
|
26
|
-
func setTransform(_ xform: CATransform3D, forFrame: CGFloat) {
|
|
29
|
+
|
|
30
|
+
func setTransform(_ xform: CATransform3D, forFrame _: CGFloat) {
|
|
27
31
|
transform = xform
|
|
28
32
|
outputPath = nil
|
|
29
33
|
}
|
|
@@ -34,7 +38,7 @@ class GroupOutputNode: NodeOutput {
|
|
|
34
38
|
outputPath = parent?.outputPath
|
|
35
39
|
return upstreamUpdates
|
|
36
40
|
}
|
|
37
|
-
|
|
41
|
+
|
|
38
42
|
let upstreamUpdates = parent?.hasOutputUpdates(forFrame) ?? false
|
|
39
43
|
if upstreamUpdates {
|
|
40
44
|
outputPath = nil
|
|
@@ -43,28 +47,30 @@ class GroupOutputNode: NodeOutput {
|
|
|
43
47
|
if rootUpdates {
|
|
44
48
|
outputPath = nil
|
|
45
49
|
}
|
|
46
|
-
|
|
47
|
-
var localUpdates
|
|
50
|
+
|
|
51
|
+
var localUpdates = false
|
|
48
52
|
if outputPath == nil {
|
|
49
53
|
localUpdates = true
|
|
50
|
-
|
|
54
|
+
|
|
51
55
|
let newPath = CGMutablePath()
|
|
52
56
|
if let parentNode = parent, let parentPath = parentNode.outputPath {
|
|
53
57
|
/// First add parent path.
|
|
54
58
|
newPath.addPath(parentPath)
|
|
55
59
|
}
|
|
56
60
|
var xform = CATransform3DGetAffineTransform(transform)
|
|
57
|
-
if
|
|
61
|
+
if
|
|
62
|
+
let rootNode = rootNode,
|
|
58
63
|
let rootPath = rootNode.outputPath,
|
|
59
|
-
let xformedPath = rootPath.copy(using: &xform)
|
|
64
|
+
let xformedPath = rootPath.copy(using: &xform)
|
|
65
|
+
{
|
|
60
66
|
/// Now add root path. Note root path is transformed.
|
|
61
67
|
newPath.addPath(xformedPath)
|
|
62
68
|
}
|
|
63
|
-
|
|
69
|
+
|
|
64
70
|
outputPath = newPath
|
|
65
71
|
}
|
|
66
|
-
|
|
72
|
+
|
|
67
73
|
return upstreamUpdates || localUpdates
|
|
68
74
|
}
|
|
69
|
-
|
|
75
|
+
|
|
70
76
|
}
|
|
@@ -5,20 +5,31 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/30/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
8
|
import CoreGraphics
|
|
9
|
+
import Foundation
|
|
10
10
|
|
|
11
11
|
class PassThroughOutputNode: NodeOutput {
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
// MARK: Lifecycle
|
|
14
|
+
|
|
13
15
|
init(parent: NodeOutput?) {
|
|
14
16
|
self.parent = parent
|
|
15
17
|
}
|
|
16
|
-
|
|
18
|
+
|
|
19
|
+
// MARK: Internal
|
|
20
|
+
|
|
17
21
|
let parent: NodeOutput?
|
|
18
|
-
|
|
19
|
-
var hasUpdate
|
|
20
|
-
var isEnabled
|
|
21
|
-
|
|
22
|
+
|
|
23
|
+
var hasUpdate = false
|
|
24
|
+
var isEnabled = true
|
|
25
|
+
|
|
26
|
+
var outputPath: CGPath? {
|
|
27
|
+
if let parent = parent {
|
|
28
|
+
return parent.outputPath
|
|
29
|
+
}
|
|
30
|
+
return nil
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
func hasOutputUpdates(_ forFrame: CGFloat) -> Bool {
|
|
23
34
|
/// Changes to this node do not affect downstream nodes.
|
|
24
35
|
let parentUpdate = parent?.hasOutputUpdates(forFrame) ?? false
|
|
@@ -26,14 +37,7 @@ class PassThroughOutputNode: NodeOutput {
|
|
|
26
37
|
hasUpdate = hasUpdate || parentUpdate
|
|
27
38
|
return parentUpdate
|
|
28
39
|
}
|
|
29
|
-
|
|
30
|
-
var outputPath: CGPath? {
|
|
31
|
-
if let parent = parent {
|
|
32
|
-
return parent.outputPath
|
|
33
|
-
}
|
|
34
|
-
return nil
|
|
35
|
-
}
|
|
36
|
-
|
|
40
|
+
|
|
37
41
|
func hasRenderUpdates(_ forFrame: CGFloat) -> Bool {
|
|
38
42
|
/// Return true if there are upstream updates or if this node has updates
|
|
39
43
|
let upstreamUpdates = parent?.hasOutputUpdates(forFrame) ?? false
|
|
@@ -5,34 +5,40 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/30/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
8
|
import CoreGraphics
|
|
9
|
+
import Foundation
|
|
10
10
|
|
|
11
11
|
/// A node that has an output of a BezierPath
|
|
12
12
|
class PathOutputNode: NodeOutput {
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
// MARK: Lifecycle
|
|
15
|
+
|
|
14
16
|
init(parent: NodeOutput?) {
|
|
15
17
|
self.parent = parent
|
|
16
18
|
}
|
|
17
|
-
|
|
19
|
+
|
|
20
|
+
// MARK: Internal
|
|
21
|
+
|
|
18
22
|
let parent: NodeOutput?
|
|
19
|
-
|
|
23
|
+
|
|
20
24
|
fileprivate(set) var outputPath: CGPath? = nil
|
|
21
|
-
|
|
25
|
+
|
|
22
26
|
var lastUpdateFrame: CGFloat? = nil
|
|
23
27
|
var lastPathBuildFrame: CGFloat? = nil
|
|
24
|
-
var isEnabled
|
|
25
|
-
|
|
28
|
+
var isEnabled = true
|
|
29
|
+
fileprivate(set) var totalLength: CGFloat = 0
|
|
30
|
+
fileprivate(set) var pathObjects: [CompoundBezierPath] = []
|
|
31
|
+
|
|
26
32
|
func hasOutputUpdates(_ forFrame: CGFloat) -> Bool {
|
|
27
33
|
guard isEnabled else {
|
|
28
34
|
let upstreamUpdates = parent?.hasOutputUpdates(forFrame) ?? false
|
|
29
35
|
outputPath = parent?.outputPath
|
|
30
36
|
return upstreamUpdates
|
|
31
37
|
}
|
|
32
|
-
|
|
38
|
+
|
|
33
39
|
/// Ask if parent was updated
|
|
34
40
|
let upstreamUpdates = parent?.hasOutputUpdates(forFrame) ?? false
|
|
35
|
-
|
|
41
|
+
|
|
36
42
|
/// If parent was updated and the path hasn't been built for this frame, clear the path.
|
|
37
43
|
if upstreamUpdates && lastPathBuildFrame != forFrame {
|
|
38
44
|
outputPath = nil
|
|
@@ -52,17 +58,13 @@ class PathOutputNode: NodeOutput {
|
|
|
52
58
|
}
|
|
53
59
|
outputPath = newPath
|
|
54
60
|
}
|
|
55
|
-
|
|
61
|
+
|
|
56
62
|
/// Return true if there were upstream updates or if this node was updated.
|
|
57
63
|
return upstreamUpdates || (lastUpdateFrame == forFrame)
|
|
58
64
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
fileprivate(set) var totalLength: CGFloat = 0
|
|
63
|
-
fileprivate(set) var pathObjects: [CompoundBezierPath] = []
|
|
64
|
-
|
|
65
|
-
@discardableResult func removePaths(updateFrame: CGFloat?) -> [CompoundBezierPath] {
|
|
65
|
+
|
|
66
|
+
@discardableResult
|
|
67
|
+
func removePaths(updateFrame: CGFloat?) -> [CompoundBezierPath] {
|
|
66
68
|
lastUpdateFrame = updateFrame
|
|
67
69
|
let returnPaths = pathObjects
|
|
68
70
|
outputPath = nil
|
|
@@ -70,19 +72,19 @@ class PathOutputNode: NodeOutput {
|
|
|
70
72
|
pathObjects = []
|
|
71
73
|
return returnPaths
|
|
72
74
|
}
|
|
73
|
-
|
|
75
|
+
|
|
74
76
|
func setPath(_ path: BezierPath, updateFrame: CGFloat) {
|
|
75
77
|
lastUpdateFrame = updateFrame
|
|
76
78
|
outputPath = nil
|
|
77
79
|
totalLength = path.length
|
|
78
80
|
pathObjects = [CompoundBezierPath(path: path)]
|
|
79
81
|
}
|
|
80
|
-
|
|
82
|
+
|
|
81
83
|
func appendPath(_ path: CompoundBezierPath, updateFrame: CGFloat) {
|
|
82
84
|
lastUpdateFrame = updateFrame
|
|
83
85
|
outputPath = nil
|
|
84
86
|
totalLength = totalLength + path.length
|
|
85
87
|
pathObjects.append(path)
|
|
86
88
|
}
|
|
87
|
-
|
|
89
|
+
|
|
88
90
|
}
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/30/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
+
import CoreGraphics
|
|
8
9
|
import Foundation
|
|
9
10
|
import QuartzCore
|
|
10
|
-
import CoreGraphics
|
|
11
11
|
|
|
12
12
|
extension FillRule {
|
|
13
13
|
var cgFillRule: CGPathFillRule {
|
|
@@ -18,7 +18,7 @@ extension FillRule {
|
|
|
18
18
|
return .winding
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
var caFillRule: CAShapeLayerFillRule {
|
|
23
23
|
switch self {
|
|
24
24
|
case .evenOdd:
|
|
@@ -29,44 +29,43 @@ extension FillRule {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// MARK: - FillRenderer
|
|
33
|
+
|
|
32
34
|
/// A rendered for a Path Fill
|
|
33
35
|
final class FillRenderer: PassThroughOutputNode, Renderable {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
func updateShapeLayer(layer: CAShapeLayer) {
|
|
38
|
-
layer.fillColor = color
|
|
39
|
-
layer.opacity = Float(opacity)
|
|
40
|
-
layer.fillRule = fillRule.caFillRule
|
|
41
|
-
hasUpdate = false
|
|
42
|
-
}
|
|
43
|
-
|
|
36
|
+
var shouldRenderInContext = false
|
|
37
|
+
|
|
44
38
|
var color: CGColor? {
|
|
45
39
|
didSet {
|
|
46
40
|
hasUpdate = true
|
|
47
41
|
}
|
|
48
42
|
}
|
|
49
|
-
|
|
43
|
+
|
|
50
44
|
var opacity: CGFloat = 0 {
|
|
51
45
|
didSet {
|
|
52
46
|
hasUpdate = true
|
|
53
47
|
}
|
|
54
48
|
}
|
|
55
|
-
|
|
49
|
+
|
|
56
50
|
var fillRule: FillRule = .none {
|
|
57
51
|
didSet {
|
|
58
52
|
hasUpdate = true
|
|
59
53
|
}
|
|
60
54
|
}
|
|
61
|
-
|
|
62
|
-
func render(_
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
55
|
+
|
|
56
|
+
func render(_: CGContext) {
|
|
57
|
+
// do nothing
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
func setupSublayers(layer _: CAShapeLayer) {
|
|
61
|
+
// do nothing
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
func updateShapeLayer(layer: CAShapeLayer) {
|
|
65
|
+
layer.fillColor = color
|
|
66
|
+
layer.opacity = Float(opacity)
|
|
67
|
+
layer.fillRule = fillRule.caFillRule
|
|
67
68
|
hasUpdate = false
|
|
68
|
-
inContext.setAlpha(opacity * 0.01)
|
|
69
|
-
inContext.setFillColor(color)
|
|
70
|
-
inContext.fillPath(using: fillRule.cgFillRule)
|
|
71
69
|
}
|
|
70
|
+
|
|
72
71
|
}
|