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
|
@@ -5,39 +5,45 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/8/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
8
|
import CoreGraphics
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
// MARK: - BezierPath
|
|
10
12
|
|
|
11
13
|
/// A container that holds instructions for creating a single, unbroken Bezier Path.
|
|
12
14
|
struct BezierPath {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
/// If the path is closed or not.
|
|
18
|
-
fileprivate(set) var closed: Bool
|
|
19
|
-
|
|
20
|
-
/// The total length of the path.
|
|
21
|
-
fileprivate(set) var length: CGFloat
|
|
22
|
-
|
|
15
|
+
|
|
16
|
+
// MARK: Lifecycle
|
|
17
|
+
|
|
23
18
|
/// Initializes a new Bezier Path.
|
|
24
19
|
init(startPoint: CurveVertex) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
elements = [PathElement(vertex: startPoint)]
|
|
21
|
+
length = 0
|
|
22
|
+
closed = false
|
|
28
23
|
}
|
|
29
|
-
|
|
24
|
+
|
|
30
25
|
init() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
elements = []
|
|
27
|
+
length = 0
|
|
28
|
+
closed = false
|
|
34
29
|
}
|
|
35
|
-
|
|
30
|
+
|
|
31
|
+
// MARK: Internal
|
|
32
|
+
|
|
33
|
+
/// The elements of the path
|
|
34
|
+
private(set) var elements: [PathElement]
|
|
35
|
+
|
|
36
|
+
/// If the path is closed or not.
|
|
37
|
+
private(set) var closed: Bool
|
|
38
|
+
|
|
39
|
+
/// The total length of the path.
|
|
40
|
+
private(set) var length: CGFloat
|
|
41
|
+
|
|
36
42
|
mutating func moveToStartPoint(_ vertex: CurveVertex) {
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
elements = [PathElement(vertex: vertex)]
|
|
44
|
+
length = 0
|
|
39
45
|
}
|
|
40
|
-
|
|
46
|
+
|
|
41
47
|
mutating func addVertex(_ vertex: CurveVertex) {
|
|
42
48
|
guard let previous = elements.last else {
|
|
43
49
|
addElement(PathElement(vertex: vertex))
|
|
@@ -45,132 +51,137 @@ struct BezierPath {
|
|
|
45
51
|
}
|
|
46
52
|
addElement(previous.pathElementTo(vertex))
|
|
47
53
|
}
|
|
48
|
-
|
|
54
|
+
|
|
49
55
|
mutating func addCurve(toPoint: CGPoint, outTangent: CGPoint, inTangent: CGPoint) {
|
|
50
56
|
guard let previous = elements.last else { return }
|
|
51
57
|
let newVertex = CurveVertex(inTangent, toPoint, toPoint)
|
|
52
|
-
updateVertex(
|
|
58
|
+
updateVertex(
|
|
59
|
+
CurveVertex(previous.vertex.inTangent, previous.vertex.point, outTangent),
|
|
60
|
+
atIndex: elements.endIndex - 1,
|
|
61
|
+
remeasure: false)
|
|
53
62
|
addVertex(newVertex)
|
|
54
63
|
}
|
|
55
|
-
|
|
64
|
+
|
|
56
65
|
mutating func addLine(toPoint: CGPoint) {
|
|
57
66
|
guard let previous = elements.last else { return }
|
|
58
67
|
let newVertex = CurveVertex(point: toPoint, inTangentRelative: .zero, outTangentRelative: .zero)
|
|
59
|
-
updateVertex(
|
|
68
|
+
updateVertex(
|
|
69
|
+
CurveVertex(previous.vertex.inTangent, previous.vertex.point, previous.vertex.point),
|
|
70
|
+
atIndex: elements.endIndex - 1,
|
|
71
|
+
remeasure: false)
|
|
60
72
|
addVertex(newVertex)
|
|
61
73
|
}
|
|
62
|
-
|
|
74
|
+
|
|
63
75
|
mutating func close() {
|
|
64
|
-
|
|
76
|
+
closed = true
|
|
65
77
|
}
|
|
66
|
-
|
|
78
|
+
|
|
67
79
|
mutating func addElement(_ pathElement: PathElement) {
|
|
68
80
|
elements.append(pathElement)
|
|
69
81
|
length = length + pathElement.length
|
|
70
82
|
}
|
|
71
|
-
|
|
83
|
+
|
|
72
84
|
mutating func updateVertex(_ vertex: CurveVertex, atIndex: Int, remeasure: Bool) {
|
|
73
85
|
if remeasure {
|
|
74
86
|
var newElement: PathElement
|
|
75
87
|
if atIndex > 0 {
|
|
76
|
-
let previousElement = elements[atIndex-1]
|
|
88
|
+
let previousElement = elements[atIndex - 1]
|
|
77
89
|
newElement = previousElement.pathElementTo(vertex)
|
|
78
90
|
} else {
|
|
79
91
|
newElement = PathElement(vertex: vertex)
|
|
80
92
|
}
|
|
81
93
|
elements[atIndex] = newElement
|
|
82
|
-
|
|
83
|
-
if atIndex + 1 < elements.count{
|
|
94
|
+
|
|
95
|
+
if atIndex + 1 < elements.count {
|
|
84
96
|
let nextElement = elements[atIndex + 1]
|
|
85
97
|
elements[atIndex + 1] = newElement.pathElementTo(nextElement.vertex)
|
|
86
98
|
}
|
|
87
|
-
|
|
99
|
+
|
|
88
100
|
} else {
|
|
89
101
|
let oldElement = elements[atIndex]
|
|
90
102
|
elements[atIndex] = oldElement.updateVertex(newVertex: vertex)
|
|
91
103
|
}
|
|
92
104
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
*/
|
|
105
|
+
|
|
106
|
+
/// Trims a path fromLength toLength with an offset.
|
|
107
|
+
///
|
|
108
|
+
/// Length and offset are defined in the length coordinate space.
|
|
109
|
+
/// If any argument is outside the range of this path, then it will be looped over the path from finish to start.
|
|
110
|
+
///
|
|
111
|
+
/// Cutting the curve when fromLength is less than toLength
|
|
112
|
+
/// x x x x
|
|
113
|
+
/// ~~~~~~~~~~~~~~~ooooooooooooooooooooooooooooooooooooooooooooooooo-------------------
|
|
114
|
+
/// |Offset |fromLength toLength| |
|
|
115
|
+
///
|
|
116
|
+
/// Cutting the curve when from Length is greater than toLength
|
|
117
|
+
/// x x x x x
|
|
118
|
+
/// oooooooooooooooooo--------------------~~~~~~~~~~~~~~~~ooooooooooooooooooooooooooooo
|
|
119
|
+
/// | toLength| |Offset |fromLength |
|
|
120
|
+
///
|
|
111
121
|
func trim(fromLength: CGFloat, toLength: CGFloat, offsetLength: CGFloat) -> [BezierPath] {
|
|
112
122
|
guard elements.count > 1 else {
|
|
113
123
|
return []
|
|
114
124
|
}
|
|
115
|
-
|
|
125
|
+
|
|
116
126
|
if fromLength == toLength {
|
|
117
127
|
return []
|
|
118
128
|
}
|
|
119
|
-
|
|
129
|
+
|
|
120
130
|
/// Normalize lengths to the curve length.
|
|
121
|
-
var start = (fromLength+offsetLength).truncatingRemainder(dividingBy: length)
|
|
122
|
-
var end =
|
|
123
|
-
|
|
131
|
+
var start = (fromLength + offsetLength).truncatingRemainder(dividingBy: length)
|
|
132
|
+
var end = (toLength + offsetLength).truncatingRemainder(dividingBy: length)
|
|
133
|
+
|
|
124
134
|
if start < 0 {
|
|
125
135
|
start = length + start
|
|
126
136
|
}
|
|
127
|
-
|
|
137
|
+
|
|
128
138
|
if end < 0 {
|
|
129
139
|
end = length + end
|
|
130
140
|
}
|
|
131
|
-
|
|
141
|
+
|
|
132
142
|
if start == length {
|
|
133
143
|
start = 0
|
|
134
144
|
}
|
|
135
145
|
if end == 0 {
|
|
136
146
|
end = length
|
|
137
147
|
}
|
|
138
|
-
|
|
139
|
-
if
|
|
148
|
+
|
|
149
|
+
if
|
|
150
|
+
start == 0 && end == length ||
|
|
140
151
|
start == end ||
|
|
141
|
-
start == length && end == 0
|
|
152
|
+
start == length && end == 0
|
|
153
|
+
{
|
|
142
154
|
/// The trim encompasses the entire path. Return.
|
|
143
155
|
return [self]
|
|
144
156
|
}
|
|
145
|
-
|
|
157
|
+
|
|
146
158
|
if start > end {
|
|
147
159
|
// Start is greater than end. Two paths are returned.
|
|
148
160
|
return trimPathAtLengths(positions: [(start: 0, end: end), (start: start, end: length)])
|
|
149
161
|
}
|
|
150
|
-
|
|
162
|
+
|
|
151
163
|
return trimPathAtLengths(positions: [(start: start, end: end)])
|
|
152
164
|
}
|
|
153
|
-
|
|
154
|
-
// MARK:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
fileprivate func trimPathAtLengths(positions: [(start: CGFloat, end: CGFloat)]) -> [BezierPath] {
|
|
165
|
+
|
|
166
|
+
// MARK: Private
|
|
167
|
+
|
|
168
|
+
private func trimPathAtLengths(positions: [(start: CGFloat, end: CGFloat)]) -> [BezierPath] {
|
|
158
169
|
guard positions.count > 0 else {
|
|
159
170
|
return []
|
|
160
171
|
}
|
|
161
172
|
var remainingPositions = positions
|
|
162
|
-
|
|
173
|
+
|
|
163
174
|
var trim = remainingPositions.remove(at: 0)
|
|
164
175
|
|
|
165
176
|
var paths = [BezierPath]()
|
|
166
|
-
|
|
177
|
+
|
|
167
178
|
var runningLength: CGFloat = 0
|
|
168
|
-
var finishedTrimming
|
|
179
|
+
var finishedTrimming = false
|
|
169
180
|
var pathElements = elements
|
|
170
|
-
|
|
181
|
+
|
|
171
182
|
var currentPath = BezierPath()
|
|
172
|
-
var i
|
|
173
|
-
|
|
183
|
+
var i = 0
|
|
184
|
+
|
|
174
185
|
while !finishedTrimming {
|
|
175
186
|
if pathElements.count <= i {
|
|
176
187
|
/// Do this for rounding errors
|
|
@@ -181,10 +192,10 @@ struct BezierPath {
|
|
|
181
192
|
/// Loop through and add elements within start->end range.
|
|
182
193
|
/// Get current element
|
|
183
194
|
let element = pathElements[i]
|
|
184
|
-
|
|
195
|
+
|
|
185
196
|
/// Calculate new running length.
|
|
186
197
|
let newLength = runningLength + element.length
|
|
187
|
-
|
|
198
|
+
|
|
188
199
|
if newLength < trim.start {
|
|
189
200
|
/// Element is not included in the trim, continue.
|
|
190
201
|
runningLength = newLength
|
|
@@ -192,7 +203,7 @@ struct BezierPath {
|
|
|
192
203
|
/// Increment index, we are done with this element.
|
|
193
204
|
continue
|
|
194
205
|
}
|
|
195
|
-
|
|
206
|
+
|
|
196
207
|
if newLength == trim.start {
|
|
197
208
|
/// Current element IS the start element.
|
|
198
209
|
/// For start we want to add a zero length element.
|
|
@@ -202,11 +213,11 @@ struct BezierPath {
|
|
|
202
213
|
/// Increment index, we are done with this element.
|
|
203
214
|
continue
|
|
204
215
|
}
|
|
205
|
-
|
|
216
|
+
|
|
206
217
|
if runningLength < trim.start, trim.start < newLength, currentPath.elements.count == 0 {
|
|
207
218
|
/// The start of the trim is between this element and the previous, trim.
|
|
208
219
|
/// Get previous element.
|
|
209
|
-
let previousElement = pathElements[i-1]
|
|
220
|
+
let previousElement = pathElements[i - 1]
|
|
210
221
|
/// Trim it
|
|
211
222
|
let trimLength = trim.start - runningLength
|
|
212
223
|
let trimResults = element.splitElementAtPosition(fromElement: previousElement, atLength: trimLength)
|
|
@@ -214,12 +225,12 @@ struct BezierPath {
|
|
|
214
225
|
currentPath.moveToStartPoint(trimResults.rightSpan.start.vertex)
|
|
215
226
|
|
|
216
227
|
pathElements[i] = trimResults.rightSpan.end
|
|
217
|
-
pathElements[i-1] = trimResults.rightSpan.start
|
|
228
|
+
pathElements[i - 1] = trimResults.rightSpan.start
|
|
218
229
|
runningLength = runningLength + trimResults.leftSpan.end.length
|
|
219
230
|
/// Dont increment index or the current length, the end of this path can be within this span.
|
|
220
231
|
continue
|
|
221
232
|
}
|
|
222
|
-
|
|
233
|
+
|
|
223
234
|
if trim.start < newLength, newLength < trim.end {
|
|
224
235
|
/// Element lies within the trim span.
|
|
225
236
|
currentPath.addElement(element)
|
|
@@ -227,7 +238,7 @@ struct BezierPath {
|
|
|
227
238
|
i = i + 1
|
|
228
239
|
continue
|
|
229
240
|
}
|
|
230
|
-
|
|
241
|
+
|
|
231
242
|
if newLength == trim.end {
|
|
232
243
|
/// Element is the end element.
|
|
233
244
|
/// The element could have a new length if it's added right after the start node.
|
|
@@ -238,28 +249,28 @@ struct BezierPath {
|
|
|
238
249
|
/// Allow the path to be finalized.
|
|
239
250
|
/// Fall through to finalize path and move to next position
|
|
240
251
|
}
|
|
241
|
-
|
|
252
|
+
|
|
242
253
|
if runningLength < trim.end, trim.end < newLength {
|
|
243
254
|
/// New element must be cut for end.
|
|
244
255
|
/// Get previous element.
|
|
245
|
-
let previousElement = pathElements[i-1]
|
|
256
|
+
let previousElement = pathElements[i - 1]
|
|
246
257
|
/// Trim it
|
|
247
258
|
let trimLength = trim.end - runningLength
|
|
248
259
|
let trimResults = element.splitElementAtPosition(fromElement: previousElement, atLength: trimLength)
|
|
249
260
|
/// Add the left span end.
|
|
250
|
-
|
|
261
|
+
|
|
251
262
|
currentPath.updateVertex(trimResults.leftSpan.start.vertex, atIndex: currentPath.elements.count - 1, remeasure: false)
|
|
252
263
|
currentPath.addElement(trimResults.leftSpan.end)
|
|
253
|
-
|
|
264
|
+
|
|
254
265
|
pathElements[i] = trimResults.rightSpan.end
|
|
255
|
-
pathElements[i-1] = trimResults.rightSpan.start
|
|
266
|
+
pathElements[i - 1] = trimResults.rightSpan.start
|
|
256
267
|
runningLength = runningLength + trimResults.leftSpan.end.length
|
|
257
268
|
/// Dont increment index or the current length, the start of the next path can be within this span.
|
|
258
269
|
/// We are done with this span.
|
|
259
270
|
/// Allow the path to be finalized.
|
|
260
271
|
/// Fall through to finalize path and move to next position
|
|
261
272
|
}
|
|
262
|
-
|
|
273
|
+
|
|
263
274
|
paths.append(currentPath)
|
|
264
275
|
currentPath = BezierPath()
|
|
265
276
|
if remainingPositions.count > 0 {
|
|
@@ -270,76 +281,63 @@ struct BezierPath {
|
|
|
270
281
|
}
|
|
271
282
|
return paths
|
|
272
283
|
}
|
|
273
|
-
|
|
284
|
+
|
|
274
285
|
}
|
|
275
286
|
|
|
287
|
+
// MARK: Codable
|
|
288
|
+
|
|
276
289
|
extension BezierPath: Codable {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
that defines points for a lottie animation.
|
|
281
|
-
|
|
282
|
-
{
|
|
283
|
-
"c" = Bool
|
|
284
|
-
"i" = [[Double]],
|
|
285
|
-
"o" = [[Double]],
|
|
286
|
-
"v" = [[Double]]
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
*/
|
|
290
|
-
|
|
291
|
-
enum CodingKeys : String, CodingKey {
|
|
292
|
-
case closed = "c"
|
|
293
|
-
case inPoints = "i"
|
|
294
|
-
case outPoints = "o"
|
|
295
|
-
case vertices = "v"
|
|
296
|
-
}
|
|
297
|
-
|
|
290
|
+
|
|
291
|
+
// MARK: Lifecycle
|
|
292
|
+
|
|
298
293
|
init(from decoder: Decoder) throws {
|
|
299
294
|
let container: KeyedDecodingContainer<BezierPath.CodingKeys>
|
|
300
|
-
|
|
295
|
+
|
|
301
296
|
if let keyedContainer = try? decoder.container(keyedBy: BezierPath.CodingKeys.self) {
|
|
302
297
|
container = keyedContainer
|
|
303
298
|
} else {
|
|
304
299
|
var unkeyedContainer = try decoder.unkeyedContainer()
|
|
305
300
|
container = try unkeyedContainer.nestedContainer(keyedBy: BezierPath.CodingKeys.self)
|
|
306
301
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
302
|
+
|
|
303
|
+
closed = try container.decodeIfPresent(Bool.self, forKey: .closed) ?? true
|
|
304
|
+
|
|
310
305
|
var vertexContainer = try container.nestedUnkeyedContainer(forKey: .vertices)
|
|
311
306
|
var inPointsContainer = try container.nestedUnkeyedContainer(forKey: .inPoints)
|
|
312
307
|
var outPointsContainer = try container.nestedUnkeyedContainer(forKey: .outPoints)
|
|
313
|
-
|
|
308
|
+
|
|
314
309
|
guard vertexContainer.count == inPointsContainer.count, inPointsContainer.count == outPointsContainer.count else {
|
|
315
310
|
/// Will throw an error if vertex, inpoints, and outpoints are not the same length.
|
|
316
311
|
/// This error is to be expected.
|
|
317
|
-
throw DecodingError.dataCorruptedError(
|
|
318
|
-
|
|
319
|
-
|
|
312
|
+
throw DecodingError.dataCorruptedError(
|
|
313
|
+
forKey: CodingKeys.vertices,
|
|
314
|
+
in: container,
|
|
315
|
+
debugDescription: "Vertex data does not match In Tangents and Out Tangents")
|
|
320
316
|
}
|
|
321
|
-
|
|
317
|
+
|
|
322
318
|
guard let count = vertexContainer.count, count > 0 else {
|
|
323
|
-
|
|
324
|
-
|
|
319
|
+
length = 0
|
|
320
|
+
elements = []
|
|
325
321
|
return
|
|
326
322
|
}
|
|
327
|
-
|
|
323
|
+
|
|
328
324
|
var decodedElements = [PathElement]()
|
|
329
|
-
|
|
325
|
+
|
|
330
326
|
/// Create first point
|
|
331
|
-
let firstVertex = CurveVertex(
|
|
332
|
-
|
|
333
|
-
|
|
327
|
+
let firstVertex = CurveVertex(
|
|
328
|
+
point: try vertexContainer.decode(CGPoint.self),
|
|
329
|
+
inTangentRelative: try inPointsContainer.decode(CGPoint.self),
|
|
330
|
+
outTangentRelative: try outPointsContainer.decode(CGPoint.self))
|
|
334
331
|
var previousElement = PathElement(vertex: firstVertex)
|
|
335
332
|
decodedElements.append(previousElement)
|
|
336
|
-
|
|
333
|
+
|
|
337
334
|
var totalLength: CGFloat = 0
|
|
338
335
|
while !vertexContainer.isAtEnd {
|
|
339
336
|
/// Get the next vertex data.
|
|
340
|
-
let vertex = CurveVertex(
|
|
341
|
-
|
|
342
|
-
|
|
337
|
+
let vertex = CurveVertex(
|
|
338
|
+
point: try vertexContainer.decode(CGPoint.self),
|
|
339
|
+
inTangentRelative: try inPointsContainer.decode(CGPoint.self),
|
|
340
|
+
outTangentRelative: try outPointsContainer.decode(CGPoint.self))
|
|
343
341
|
let pathElement = previousElement.pathElementTo(vertex)
|
|
344
342
|
decodedElements.append(pathElement)
|
|
345
343
|
previousElement = pathElement
|
|
@@ -350,39 +348,127 @@ extension BezierPath: Codable {
|
|
|
350
348
|
decodedElements.append(closeElement)
|
|
351
349
|
totalLength = totalLength + closeElement.length
|
|
352
350
|
}
|
|
353
|
-
|
|
354
|
-
|
|
351
|
+
length = totalLength
|
|
352
|
+
elements = decodedElements
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// MARK: Internal
|
|
356
|
+
|
|
357
|
+
/// The BezierPath container is encoded and decoded from the JSON format
|
|
358
|
+
/// that defines points for a lottie animation.
|
|
359
|
+
///
|
|
360
|
+
/// {
|
|
361
|
+
/// "c" = Bool
|
|
362
|
+
/// "i" = [[Double]],
|
|
363
|
+
/// "o" = [[Double]],
|
|
364
|
+
/// "v" = [[Double]]
|
|
365
|
+
/// }
|
|
366
|
+
///
|
|
367
|
+
|
|
368
|
+
enum CodingKeys: String, CodingKey {
|
|
369
|
+
case closed = "c"
|
|
370
|
+
case inPoints = "i"
|
|
371
|
+
case outPoints = "o"
|
|
372
|
+
case vertices = "v"
|
|
355
373
|
}
|
|
356
|
-
|
|
374
|
+
|
|
357
375
|
func encode(to encoder: Encoder) throws {
|
|
358
376
|
var container = encoder.container(keyedBy: BezierPath.CodingKeys.self)
|
|
359
377
|
try container.encode(closed, forKey: .closed)
|
|
360
|
-
|
|
378
|
+
|
|
361
379
|
var vertexContainer = container.nestedUnkeyedContainer(forKey: .vertices)
|
|
362
380
|
var inPointsContainer = container.nestedUnkeyedContainer(forKey: .inPoints)
|
|
363
381
|
var outPointsContainer = container.nestedUnkeyedContainer(forKey: .outPoints)
|
|
364
|
-
|
|
382
|
+
|
|
365
383
|
/// If closed path, ignore the final element.
|
|
366
|
-
let finalIndex = closed ?
|
|
384
|
+
let finalIndex = closed ? elements.endIndex - 1 : elements.endIndex
|
|
367
385
|
for i in 0..<finalIndex {
|
|
368
386
|
let element = elements[i]
|
|
369
387
|
try vertexContainer.encode(element.vertex.point)
|
|
370
388
|
try inPointsContainer.encode(element.vertex.inTangentRelative)
|
|
371
389
|
try outPointsContainer.encode(element.vertex.outTangentRelative)
|
|
372
390
|
}
|
|
373
|
-
|
|
374
391
|
}
|
|
375
392
|
}
|
|
376
393
|
|
|
394
|
+
// MARK: AnyInitializable
|
|
395
|
+
|
|
396
|
+
extension BezierPath: AnyInitializable {
|
|
397
|
+
|
|
398
|
+
init(value: Any) throws {
|
|
399
|
+
var pathDictionary: [String: Any]
|
|
400
|
+
if
|
|
401
|
+
let array = value as? [[String: Any]],
|
|
402
|
+
let firstDictionary = array.first
|
|
403
|
+
{
|
|
404
|
+
pathDictionary = firstDictionary
|
|
405
|
+
} else if let dictionary = value as? [String: Any] {
|
|
406
|
+
pathDictionary = dictionary
|
|
407
|
+
} else {
|
|
408
|
+
throw InitializableError.invalidInput
|
|
409
|
+
}
|
|
410
|
+
closed = (try? pathDictionary.value(for: CodingKeys.closed)) ?? true
|
|
411
|
+
var vertexDictionaries: [Any] = try pathDictionary.value(for: CodingKeys.vertices)
|
|
412
|
+
var inPointsDictionaries: [Any] = try pathDictionary.value(for: CodingKeys.inPoints)
|
|
413
|
+
var outPointsDictionaries: [Any] = try pathDictionary.value(for: CodingKeys.outPoints)
|
|
414
|
+
guard
|
|
415
|
+
vertexDictionaries.count == inPointsDictionaries.count,
|
|
416
|
+
inPointsDictionaries.count == outPointsDictionaries.count else
|
|
417
|
+
{
|
|
418
|
+
throw InitializableError.invalidInput
|
|
419
|
+
}
|
|
420
|
+
guard vertexDictionaries.count > 0 else {
|
|
421
|
+
length = 0
|
|
422
|
+
elements = []
|
|
423
|
+
return
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
var decodedElements = [PathElement]()
|
|
427
|
+
let firstVertexDictionary = vertexDictionaries.removeFirst()
|
|
428
|
+
let firstInPointsDictionary = inPointsDictionaries.removeFirst()
|
|
429
|
+
let firstOutPointsDictionary = outPointsDictionaries.removeFirst()
|
|
430
|
+
let firstVertex = CurveVertex(
|
|
431
|
+
point: try CGPoint(value: firstVertexDictionary),
|
|
432
|
+
inTangentRelative: try CGPoint(value: firstInPointsDictionary),
|
|
433
|
+
outTangentRelative: try CGPoint(value: firstOutPointsDictionary))
|
|
434
|
+
var previousElement = PathElement(vertex: firstVertex)
|
|
435
|
+
decodedElements.append(previousElement)
|
|
436
|
+
|
|
437
|
+
var totalLength: CGFloat = 0
|
|
438
|
+
while vertexDictionaries.count > 0 {
|
|
439
|
+
let vertexDictionary = vertexDictionaries.removeFirst()
|
|
440
|
+
let inPointsDictionary = inPointsDictionaries.removeFirst()
|
|
441
|
+
let outPointsDictionary = outPointsDictionaries.removeFirst()
|
|
442
|
+
let vertex = CurveVertex(
|
|
443
|
+
point: try CGPoint(value: vertexDictionary),
|
|
444
|
+
inTangentRelative: try CGPoint(value: inPointsDictionary),
|
|
445
|
+
outTangentRelative: try CGPoint(value: outPointsDictionary))
|
|
446
|
+
let pathElement = previousElement.pathElementTo(vertex)
|
|
447
|
+
decodedElements.append(pathElement)
|
|
448
|
+
previousElement = pathElement
|
|
449
|
+
totalLength = totalLength + pathElement.length
|
|
450
|
+
}
|
|
451
|
+
if closed {
|
|
452
|
+
let closeElement = previousElement.pathElementTo(firstVertex)
|
|
453
|
+
decodedElements.append(closeElement)
|
|
454
|
+
totalLength = totalLength + closeElement.length
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
length = totalLength
|
|
458
|
+
elements = decodedElements
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
}
|
|
462
|
+
|
|
377
463
|
extension BezierPath {
|
|
378
|
-
|
|
464
|
+
|
|
379
465
|
func cgPath() -> CGPath {
|
|
380
466
|
let cgPath = CGMutablePath()
|
|
381
|
-
|
|
467
|
+
|
|
382
468
|
var previousElement: PathElement?
|
|
383
469
|
for element in elements {
|
|
384
470
|
if let previous = previousElement {
|
|
385
|
-
if previous.vertex.outTangentRelative.isZero
|
|
471
|
+
if previous.vertex.outTangentRelative.isZero, element.vertex.inTangentRelative.isZero {
|
|
386
472
|
cgPath.addLine(to: element.vertex.point)
|
|
387
473
|
} else {
|
|
388
474
|
cgPath.addCurve(to: element.vertex.point, control1: previous.vertex.outTangent, control2: element.vertex.inTangent)
|
|
@@ -392,10 +478,10 @@ extension BezierPath {
|
|
|
392
478
|
}
|
|
393
479
|
previousElement = element
|
|
394
480
|
}
|
|
395
|
-
if
|
|
481
|
+
if closed {
|
|
396
482
|
cgPath.closeSubpath()
|
|
397
483
|
}
|
|
398
484
|
return cgPath
|
|
399
485
|
}
|
|
400
|
-
|
|
486
|
+
|
|
401
487
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//
|
|
2
|
+
// CGPointExtension.swift
|
|
3
|
+
// Lottie
|
|
4
|
+
//
|
|
5
|
+
// Created by Marcelo Fabri on 5/5/22.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import CoreGraphics
|
|
9
|
+
|
|
10
|
+
extension CGPoint: AnyInitializable {
|
|
11
|
+
|
|
12
|
+
// MARK: Lifecycle
|
|
13
|
+
|
|
14
|
+
init(value: Any) throws {
|
|
15
|
+
if let dictionary = value as? [String: CGFloat] {
|
|
16
|
+
let x: CGFloat = try dictionary.value(for: CodingKeys.x)
|
|
17
|
+
let y: CGFloat = try dictionary.value(for: CodingKeys.y)
|
|
18
|
+
self.init(x: x, y: y)
|
|
19
|
+
} else if
|
|
20
|
+
let array = value as? [CGFloat],
|
|
21
|
+
array.count > 1
|
|
22
|
+
{
|
|
23
|
+
self.init(x: array[0], y: array[1])
|
|
24
|
+
} else {
|
|
25
|
+
throw InitializableError.invalidInput
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// MARK: Private
|
|
30
|
+
|
|
31
|
+
private enum CodingKeys: String {
|
|
32
|
+
case x
|
|
33
|
+
case y
|
|
34
|
+
}
|
|
35
|
+
}
|