lottie-ios 3.2.3 → 3.4.2
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/.github/workflows/stale_issues.yml +17 -0
- package/.spi.yml +6 -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/package.xcworkspace/xcuserdata/calstephens.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 +2011 -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_tvOS.xcscheme → Lottie (macOS).xcscheme } +5 -18
- package/Lottie.xcodeproj/xcshareddata/xcschemes/{Lottie_macOS.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 +34 -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 +22 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +138 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +30 -0
- package/Package.swift +5 -15
- package/README.md +40 -60
- package/Rakefile +160 -0
- package/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift +81 -0
- package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +447 -0
- package/Sources/Private/CoreAnimation/Animations/CombinedShapeAnimation.swift +81 -0
- package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +41 -0
- package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +55 -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 +58 -0
- package/Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift +257 -0
- package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +124 -0
- package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +73 -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 +497 -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 +154 -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 +88 -0
- package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +167 -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 +64 -0
- package/Sources/Private/CoreAnimation/Layers/MaskCompositionLayer.swift +138 -0
- package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +140 -0
- package/Sources/Private/CoreAnimation/Layers/RepeaterLayer.swift +85 -0
- package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +315 -0
- package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +390 -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 +94 -86
- 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 +59 -43
- 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} +149 -106
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/LayerContainers/Utility/InvertedMatteLayer.swift +26 -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 +9 -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/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 +247 -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 +57 -42
- package/{lottie-swift/src/Private → Sources/Private/MainThread}/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +66 -58
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +169 -0
- 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 +222 -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 +74 -0
- package/Sources/Private/Model/ShapeItems/Fill.swift +74 -0
- package/Sources/Private/Model/ShapeItems/GradientFill.swift +137 -0
- package/Sources/Private/Model/ShapeItems/GradientStroke.swift +185 -0
- package/Sources/Private/Model/ShapeItems/Group.swift +48 -0
- package/{lottie-swift/src → Sources}/Private/Model/ShapeItems/Merge.swift +29 -12
- package/Sources/Private/Model/ShapeItems/Rectangle.swift +72 -0
- package/Sources/Private/Model/ShapeItems/Repeater.swift +135 -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 +135 -0
- package/Sources/Private/Model/ShapeItems/Star.swift +131 -0
- package/Sources/Private/Model/ShapeItems/Stroke.swift +101 -0
- package/Sources/Private/Model/ShapeItems/Trim.swift +77 -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/Private/NodeRenderSystem/NodeProperties/ValueProviders → Sources/Private/Utility/Interpolatable}/KeyframeInterpolator.swift +125 -108
- 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 +103 -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 +214 -0
- package/Tests/Samples/9squares_AlBoardman.json +1 -0
- package/Tests/Samples/Boat_Loader.json +1 -0
- package/Tests/Samples/HamburgerArrow.json +1 -0
- package/Tests/Samples/IconTransitions.json +1 -0
- package/Tests/Samples/Images/dog.png +0 -0
- package/Tests/Samples/Issues/issue_1125.json +1 -0
- package/Tests/Samples/Issues/issue_1260.json +1 -0
- package/Tests/Samples/Issues/issue_1403.json +1 -0
- package/Tests/Samples/Issues/issue_1407.json +1 -0
- package/Tests/Samples/Issues/issue_1460.json +1 -0
- package/Tests/Samples/Issues/issue_1488.json +1 -0
- package/Tests/Samples/Issues/issue_1505.json +1 -0
- package/Tests/Samples/Issues/issue_1541.json +1 -0
- package/Tests/Samples/Issues/issue_1557.json +1 -0
- package/Tests/Samples/Issues/issue_1603.json +1 -0
- package/Tests/Samples/Issues/issue_1628.json +1 -0
- package/Tests/Samples/Issues/issue_1636.json +1 -0
- package/Tests/Samples/Issues/issue_1643.json +1 -0
- package/Tests/Samples/Issues/issue_1655.json +1 -0
- package/Tests/Samples/Issues/issue_1664.json +1 -0
- package/Tests/Samples/Issues/issue_1683.json +1 -0
- package/Tests/Samples/Issues/issue_1687.json +1 -0
- package/Tests/Samples/Issues/issue_1711.json +1 -0
- package/Tests/Samples/Issues/issue_1717.json +1 -0
- package/Tests/Samples/Issues/issue_769.json +1 -0
- package/Tests/Samples/Issues/issue_885.json +1 -0
- package/Tests/Samples/Issues/issue_965.json +1 -0
- package/Tests/Samples/Issues/pr_1536.json +1 -0
- package/Tests/Samples/Issues/pr_1563.json +8439 -0
- package/Tests/Samples/Issues/pr_1592.json +5527 -0
- package/Tests/Samples/Issues/pr_1599.json +738 -0
- package/Tests/Samples/Issues/pr_1604_1.json +1 -0
- package/Tests/Samples/Issues/pr_1604_2.json +1 -0
- package/Tests/Samples/Issues/pr_1632_1.json +1 -0
- package/Tests/Samples/Issues/pr_1632_2.json +1 -0
- package/Tests/Samples/Issues/pr_1686.json +513 -0
- package/Tests/Samples/Issues/pr_1698.json +1 -0
- package/Tests/Samples/Issues/pr_1699.json +1 -0
- package/Tests/Samples/LottieFiles/LICENSE.md +14 -0
- package/Tests/Samples/LottieFiles/bounce_strokes.json +1 -0
- package/Tests/Samples/LottieFiles/cactus.json +1 -0
- package/Tests/Samples/LottieFiles/dog_car_ride.json +1 -0
- package/Tests/Samples/LottieFiles/draft_icon.json +1 -0
- package/Tests/Samples/LottieFiles/fireworks.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_1.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_2.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_pill.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_shapes.json +1 -0
- package/Tests/Samples/LottieFiles/gradient_square.json +1 -0
- package/Tests/Samples/LottieFiles/growth.json +1 -0
- package/Tests/Samples/LottieFiles/infinity_loader.json +1 -0
- package/Tests/Samples/LottieFiles/loading_dots_1.json +1 -0
- package/Tests/Samples/LottieFiles/loading_dots_2.json +1 -0
- package/Tests/Samples/LottieFiles/loading_dots_3.json +1 -0
- package/Tests/Samples/LottieFiles/loading_gradient_strokes.json +1 -0
- package/Tests/Samples/LottieFiles/settings_slider.json +1 -0
- package/Tests/Samples/LottieFiles/shop.json +1 -0
- package/Tests/Samples/LottieFiles/step_loader.json +1 -0
- package/Tests/Samples/LottieLogo1.json +1 -0
- package/Tests/Samples/LottieLogo1_masked.json +1 -0
- package/Tests/Samples/LottieLogo2.json +1 -0
- package/Tests/Samples/MotionCorpse_Jrcanest.json +1 -0
- package/Tests/Samples/Nonanimating/BasicLayers.json +1 -0
- package/Tests/Samples/Nonanimating/DisableNodesTest.json +1 -0
- package/Tests/Samples/Nonanimating/FirstText.json +1 -0
- package/Tests/Samples/Nonanimating/GeometryTransformTest.json +1 -0
- package/Tests/Samples/Nonanimating/Text_AnimatedProperties.json +1 -0
- package/Tests/Samples/Nonanimating/Text_Glyph.json +1 -0
- package/Tests/Samples/Nonanimating/Text_NoAnimation.json +1 -0
- package/Tests/Samples/Nonanimating/Text_NoGlyph.json +1 -0
- package/Tests/Samples/Nonanimating/Zoom.json +1 -0
- package/Tests/Samples/Nonanimating/_dog.json +1 -0
- package/Tests/Samples/Nonanimating/base64Test.json +1 -0
- package/Tests/Samples/Nonanimating/blend_mode_test.json +1 -0
- package/Tests/Samples/Nonanimating/keypathTest.json +1 -0
- package/Tests/Samples/Nonanimating/verifyLineHeight.json +1 -0
- package/Tests/Samples/PinJump.json +1 -0
- package/Tests/Samples/Switch.json +1 -0
- package/Tests/Samples/Switch_States.json +1 -0
- package/Tests/Samples/TwitterHeart.json +1 -0
- package/Tests/Samples/TwitterHeartButton.json +1 -0
- package/Tests/Samples/TypeFace/A.json +1 -0
- package/Tests/Samples/TypeFace/Apostrophe.json +1 -0
- package/Tests/Samples/TypeFace/B.json +1 -0
- package/Tests/Samples/TypeFace/BlinkingCursor.json +1 -0
- package/Tests/Samples/TypeFace/C.json +1 -0
- package/Tests/Samples/TypeFace/Colon.json +1 -0
- package/Tests/Samples/TypeFace/Comma.json +1 -0
- package/Tests/Samples/TypeFace/D.json +1 -0
- package/Tests/Samples/TypeFace/E.json +1 -0
- package/Tests/Samples/TypeFace/F.json +1 -0
- package/Tests/Samples/TypeFace/G.json +1 -0
- package/Tests/Samples/TypeFace/H.json +1 -0
- package/Tests/Samples/TypeFace/I.json +1 -0
- package/Tests/Samples/TypeFace/J.json +1 -0
- package/Tests/Samples/TypeFace/K.json +1 -0
- package/Tests/Samples/TypeFace/L.json +1 -0
- package/Tests/Samples/TypeFace/M.json +1 -0
- package/Tests/Samples/TypeFace/N.json +1 -0
- package/Tests/Samples/TypeFace/O.json +1 -0
- package/Tests/Samples/TypeFace/P.json +1 -0
- package/Tests/Samples/TypeFace/Q.json +1 -0
- package/Tests/Samples/TypeFace/R.json +1 -0
- package/Tests/Samples/TypeFace/S.json +1 -0
- package/Tests/Samples/TypeFace/T.json +1 -0
- package/Tests/Samples/TypeFace/U.json +1 -0
- package/Tests/Samples/TypeFace/V.json +1 -0
- package/Tests/Samples/TypeFace/W.json +1 -0
- package/Tests/Samples/TypeFace/X.json +1 -0
- package/Tests/Samples/TypeFace/Y.json +1 -0
- package/Tests/Samples/TypeFace/Z.json +1 -0
- package/Tests/Samples/Watermelon.json +1 -0
- package/Tests/Samples/setValueTest.json +1 -0
- package/Tests/Samples/timeremap.json +1 -0
- package/Tests/Samples/vcTransition1.json +1 -0
- package/Tests/Samples/vcTransition2.json +1 -0
- package/Tests/SnapshotConfiguration.swift +158 -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 +12 -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/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +0 -127
- 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
|
}
|