lottie-ios 3.4.4 → 4.0.0
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/.gitattributes +1 -0
- package/.github/workflows/main.yml +7 -7
- package/Gemfile.lock +1 -1
- package/Lottie.xcodeproj/project.pbxproj +286 -68
- package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +18 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +3 -24
- package/Package.swift +2 -2
- package/README.md +10 -3
- package/Rakefile +1 -1
- package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +6 -9
- package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +42 -3
- package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +5 -17
- package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +25 -17
- package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +2 -2
- package/Sources/Private/CoreAnimation/Animations/OpacityAnimation.swift +1 -1
- package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +9 -20
- package/Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift +39 -25
- package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +13 -32
- package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +4 -4
- package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +13 -13
- package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +4 -4
- package/Sources/Private/CoreAnimation/Extensions/KeyframeGroup+exactlyOneKeyframe.swift +4 -12
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift +222 -0
- package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +1 -1
- package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +8 -6
- package/Sources/Private/CoreAnimation/Layers/GradientRenderLayer.swift +13 -10
- package/Sources/Private/CoreAnimation/Layers/InfiniteOpaqueAnimationLayer.swift +56 -0
- package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +1 -1
- package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +2 -3
- package/Sources/Private/CoreAnimation/Layers/RepeaterLayer.swift +9 -9
- package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +9 -3
- package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +7 -18
- package/Sources/Private/CoreAnimation/ValueProviderStore.swift +2 -3
- package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +5 -5
- package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +3 -3
- package/Sources/Private/MainThread/LayerContainers/CompLayers/SolidCompositionLayer.swift +2 -2
- package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +7 -6
- package/Sources/Private/MainThread/LayerContainers/Utility/InvertedMatteLayer.swift +1 -3
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerTransformNode.swift +10 -10
- package/Sources/Private/MainThread/NodeRenderSystem/Extensions/ItemsExtension.swift +7 -0
- package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/GroupInterpolator.swift +2 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/RoundedCornersNode.swift +85 -0
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +4 -4
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +11 -12
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientStrokeRenderer.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift +10 -11
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +2 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +5 -5
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/RectNode.swift +3 -3
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/StarNode.swift +9 -9
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +14 -14
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/FillNode.swift +2 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +3 -3
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +10 -10
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +14 -14
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +11 -11
- package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +1 -1
- package/Sources/Private/Model/DotLottie/DotLottieAnimation.swift +52 -0
- package/Sources/Private/Model/DotLottie/DotLottieConfiguration.swift +15 -0
- package/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift +73 -0
- package/Sources/Private/Model/DotLottie/DotLottieManifest.swift +53 -0
- package/Sources/Private/Model/DotLottie/DotLottieUtils.swift +58 -0
- package/Sources/Private/Model/DotLottie/Zip/Data+Compression.swift +134 -0
- package/Sources/Private/Model/DotLottie/Zip/Data+Serialization.swift +87 -0
- package/Sources/Private/Model/DotLottie/Zip/FileManager+ZIP.swift +130 -0
- package/Sources/Private/Model/DotLottie/Zip/ZipArchive.swift +474 -0
- package/Sources/Private/Model/DotLottie/Zip/ZipEntry+Serialization.swift +189 -0
- package/Sources/Private/Model/DotLottie/Zip/ZipEntry+ZIP64.swift +179 -0
- package/Sources/Private/Model/DotLottie/Zip/ZipEntry.swift +227 -0
- package/Sources/Private/Model/Extensions/Bundle.swift +26 -0
- package/Sources/Private/Model/Keyframes/KeyframeData.swift +12 -12
- package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +9 -2
- package/Sources/Private/Model/Layers/LayerModel.swift +1 -1
- package/Sources/Private/Model/Layers/PreCompLayerModel.swift +3 -3
- package/Sources/Private/Model/Layers/TextLayerModel.swift +1 -1
- package/Sources/Private/Model/Objects/DashPattern.swift +2 -2
- package/Sources/Private/Model/Objects/Mask.swift +10 -8
- package/Sources/Private/Model/Objects/Transform.swift +39 -35
- package/Sources/Private/Model/ShapeItems/Ellipse.swift +6 -6
- package/Sources/Private/Model/ShapeItems/Fill.swift +6 -6
- package/Sources/Private/Model/ShapeItems/GradientFill.swift +15 -15
- package/Sources/Private/Model/ShapeItems/GradientStroke.swift +19 -19
- package/Sources/Private/Model/ShapeItems/Rectangle.swift +9 -9
- package/Sources/Private/Model/ShapeItems/Repeater.swift +37 -32
- package/Sources/Private/Model/ShapeItems/RoundedCorners.swift +47 -0
- package/Sources/Private/Model/ShapeItems/ShapeItem.swift +4 -0
- package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +34 -28
- package/Sources/Private/Model/ShapeItems/Star.swift +21 -21
- package/Sources/Private/Model/ShapeItems/Stroke.swift +10 -10
- package/Sources/Private/Model/ShapeItems/Trim.swift +9 -9
- package/Sources/Private/Model/Text/Font.swift +1 -1
- package/Sources/Private/Model/Text/TextAnimator.swift +33 -33
- package/Sources/Private/Model/Text/TextDocument.swift +8 -8
- package/Sources/Private/RootAnimationLayer.swift +4 -4
- package/Sources/Private/Utility/Debugging/LayerDebugging.swift +12 -18
- package/Sources/Private/Utility/Extensions/AnimationKeypathExtension.swift +2 -2
- package/Sources/Private/Utility/Extensions/CGColor+RGB.swift +12 -7
- package/Sources/Private/Utility/Interpolatable/InterpolatableExtensions.swift +1 -1
- package/Sources/Private/Utility/Interpolatable/KeyframeGroup+Extensions.swift +4 -4
- package/Sources/Private/Utility/Primitives/BezierPathRoundExtension.swift +147 -0
- package/Sources/Private/Utility/Primitives/ColorExtension.swift +8 -11
- package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +22 -22
- package/Sources/{Private/Model/Animation.swift → Public/Animation/LottieAnimation.swift} +8 -8
- package/Sources/Public/Animation/{AnimationPublic.swift → LottieAnimationHelpers.swift} +62 -27
- package/Sources/Public/Animation/{AnimationView.swift → LottieAnimationView.swift} +122 -26
- package/Sources/Public/Animation/LottieAnimationViewInitializers.swift +222 -0
- package/Sources/Public/AnimationCache/AnimationCacheProvider.swift +4 -4
- package/Sources/Public/AnimationCache/DefaultAnimationCache.swift +54 -0
- package/Sources/Public/AnimationCache/LRUAnimationCache.swift +4 -52
- package/Sources/Public/AnimationCache/LottieAnimationCache.swift +15 -0
- package/Sources/Public/DotLottie/Cache/DotLottieCache.swift +53 -0
- package/Sources/Public/DotLottie/Cache/DotLottieCacheProvider.swift +23 -0
- package/Sources/Public/DotLottie/DotLottieFile.swift +161 -0
- package/Sources/Public/DotLottie/DotLottieFileHelpers.swift +265 -0
- package/Sources/Public/DynamicProperties/AnimationKeypath.swift +3 -3
- package/Sources/Public/DynamicProperties/AnyValueProvider.swift +2 -2
- package/Sources/Public/DynamicProperties/ValueProviders/ColorValueProvider.swift +10 -10
- package/Sources/Public/DynamicProperties/ValueProviders/FloatValueProvider.swift +4 -4
- package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +5 -5
- package/Sources/Public/DynamicProperties/ValueProviders/PointValueProvider.swift +2 -2
- package/Sources/Public/DynamicProperties/ValueProviders/SizeValueProvider.swift +2 -2
- package/Sources/Public/FontProvider/AnimationFontProvider.swift +1 -1
- package/Sources/Public/ImageProvider/AnimationImageProvider.swift +2 -2
- package/Sources/Public/Keyframes/Interpolatable.swift +17 -17
- package/Sources/Public/Keyframes/Keyframe.swift +10 -10
- package/Sources/Public/LottieConfiguration.swift +25 -7
- package/Sources/Public/Primitives/{Color.swift → LottieColor.swift} +3 -3
- package/Sources/Public/Primitives/Vectors.swift +4 -4
- package/Sources/Public/TextProvider/AnimationTextProvider.swift +1 -1
- package/Sources/Public/iOS/AnimatedButton.swift +1 -1
- package/Sources/Public/iOS/AnimatedControl.swift +6 -6
- package/Sources/Public/iOS/AnimatedSwitch.swift +1 -1
- package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +8 -8
- package/Sources/Public/iOS/{AnimationViewBase.swift → LottieAnimationViewBase.swift} +4 -4
- package/Sources/Public/iOS/UIColorExtension.swift +2 -2
- package/Sources/Public/macOS/{AnimationViewBase.macOS.swift → LottieAnimationViewBase.macOS.swift} +4 -4
- package/Tests/AnimationCacheProviderTests.swift +40 -0
- package/Tests/AnimationKeypathTests.swift +20 -13
- package/Tests/AnimationViewTests.swift +64 -0
- package/Tests/AutomaticEngineTests.swift +11 -2
- package/Tests/ParsingTests.swift +4 -2
- package/Tests/PerformanceTests.swift +9 -9
- package/Tests/SnapshotConfiguration.swift +7 -7
- package/Tests/SnapshotTests.swift +57 -27
- package/Tests/ValueProvidersTests.swift +9 -6
- package/lottie-ios.podspec +4 -4
- package/package.json +2 -2
- package/script/test-carthage/Cartfile +1 -1
- package/script/test-carthage/CarthageTest/ViewController.swift +1 -1
- package/script/test-carthage/CarthageTest-macOS/ViewController.swift +1 -1
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+combinedIfPossible.swift +0 -154
- package/Sources/Public/Animation/AnimationViewInitializers.swift +0 -109
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -1
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~7IO4FqH8-VUsSfuA0_wMGUgfGdV7MwzpkzjwWbiB50jXZKQRHtU4G0A7ZXTvsR4mDdrWiawpNC_eriOALfZ7Og== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~ClRW5-6rvrgZHHbrPS1VEREaxelpVcKlERPzSa3f2rtFNXdoqATxFCsPge3a_nO4mhhtpmTmbYvyfI-obAu8Qg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Jr2dFGcJc1188nMoMha82z9wM99lCLm4MKzhjfVVjIxKeCZVGWGZH3HgJFNkTpozdk5p1u5o91dCiY4-cR1Zhg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~MBDeCFoahVzzmtSQrVhhy9VMJV6CmcnUkFya_qwe0XsMFscmY2nS8dxrTEYkY16sH68sEH7WVCCzTuW1z1Hocw== +0 -1
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~U4plJajEDM_uSZdglhDyj6gQO63mbeKxYP9X94aIaOtL0yErtfQnGz5SgsqQ0ToSZcJj6Ao9Wx-nesZVwBTRuw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~UsLY5O-vDMEHEe3bF8XJvkKkYxdsKlIytgJW7zgNuetw53fG3SssfZiiMfbuYnOtvvvYBXTwpbz07V6Czp029Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~cpg4cb7H0TaehHy4a-xINJMFfBM2_AEHal_0tIX8ymNVJPsjlCysi3-Cad0Ca_SvuGwVM7ONF55OBUuC9YKZvA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~cuHjdTCuciVumvEpvozxwDj2wAdgWe13bzd1pUAGN45-WOgY0kIid9aUlBX675OnS-xNEc_pyQWo0RO1dKAjcw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~f_-bfn-KRHHFg39_MtwgBulEAuWH6F05yqGYydXhil6kqZ51eAoRX6tsiqOr0Oa6eL3dK1tcCBD1bWX5orCZhw== +0 -1
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~jdIx7vWS6ej1cqYcbCS4KyZErSMF13ELR95YwClVc98tIXcsglh7KuGvI1gIxEPDtPXQpfC3XijIAGn1quL8Dw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~lz3e0YeBa8TvMBSSymToh--gc6zznUIdH2jO0AJ4so5OPNdw6wpYmJebhaENGsRoD3beUXvlyD5f7_WeZrzyNQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~u_5dWbliYJ__YkyUCDFjdxiFds9M8Epr_RvbU1rIRCbBQdhRJ_TUBXXcL_Qq-wVp4umNLTOzud4OpQItSpO6Rg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~v-YGzhC2l_icsAsyp1XAbEWYwxNook-rARAWlVZINioEsgT9LGvhg2oh78nYqoeH78m1fihr5HCcGNfF7SQj0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~7IO4FqH8-VUsSfuA0_wMGUgfGdV7MwzpkzjwWbiB50jXZKQRHtU4G0A7ZXTvsR4mDdrWiawpNC_eriOALfZ7Og== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~ClRW5-6rvrgZHHbrPS1VEREaxelpVcKlERPzSa3f2rtFNXdoqATxFCsPge3a_nO4mhhtpmTmbYvyfI-obAu8Qg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Jr2dFGcJc1188nMoMha82z9wM99lCLm4MKzhjfVVjIxKeCZVGWGZH3HgJFNkTpozdk5p1u5o91dCiY4-cR1Zhg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~MBDeCFoahVzzmtSQrVhhy9VMJV6CmcnUkFya_qwe0XsMFscmY2nS8dxrTEYkY16sH68sEH7WVCCzTuW1z1Hocw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~U4plJajEDM_uSZdglhDyj6gQO63mbeKxYP9X94aIaOtL0yErtfQnGz5SgsqQ0ToSZcJj6Ao9Wx-nesZVwBTRuw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~UsLY5O-vDMEHEe3bF8XJvkKkYxdsKlIytgJW7zgNuetw53fG3SssfZiiMfbuYnOtvvvYBXTwpbz07V6Czp029Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~cpg4cb7H0TaehHy4a-xINJMFfBM2_AEHal_0tIX8ymNVJPsjlCysi3-Cad0Ca_SvuGwVM7ONF55OBUuC9YKZvA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~cuHjdTCuciVumvEpvozxwDj2wAdgWe13bzd1pUAGN45-WOgY0kIid9aUlBX675OnS-xNEc_pyQWo0RO1dKAjcw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~f_-bfn-KRHHFg39_MtwgBulEAuWH6F05yqGYydXhil6kqZ51eAoRX6tsiqOr0Oa6eL3dK1tcCBD1bWX5orCZhw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~jdIx7vWS6ej1cqYcbCS4KyZErSMF13ELR95YwClVc98tIXcsglh7KuGvI1gIxEPDtPXQpfC3XijIAGn1quL8Dw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~lz3e0YeBa8TvMBSSymToh--gc6zznUIdH2jO0AJ4so5OPNdw6wpYmJebhaENGsRoD3beUXvlyD5f7_WeZrzyNQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~u_5dWbliYJ__YkyUCDFjdxiFds9M8Epr_RvbU1rIRCbBQdhRJ_TUBXXcL_Qq-wVp4umNLTOzud4OpQItSpO6Rg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~v-YGzhC2l_icsAsyp1XAbEWYwxNook-rARAWlVZINioEsgT9LGvhg2oh78nYqoeH78m1fihr5HCcGNfF7SQj0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Info.plist +0 -29
|
@@ -144,21 +144,9 @@ final class GroupLayer: BaseAnimationLayer {
|
|
|
144
144
|
!shapeRenderGroup.otherItems.contains(where: { $0.item is Trim })
|
|
145
145
|
{
|
|
146
146
|
let allPathKeyframes = shapeRenderGroup.pathItems.compactMap { ($0.item as? Shape)?.path }
|
|
147
|
-
let combinedShape
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
// we can combine the `[KeyframeGroup<BezierPath>]` (which have to animate in separate layers)
|
|
151
|
-
// into a single `KeyframeGroup<[BezierPath]>`, which can be combined into a single CGPath animation.
|
|
152
|
-
if let combinedShapeKeyframes = Keyframes.combinedIfPossible(allPathKeyframes) {
|
|
153
|
-
combinedShape = CombinedShapeItem(shapes: combinedShapeKeyframes, name: group.name)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Otherwise, in order for the path fills to be rendered correctly, we have to manually
|
|
157
|
-
// interpolate the path for each shape at each frame ahead of time so we can combine them
|
|
158
|
-
// into a single set of bezier path keyframes.
|
|
159
|
-
else {
|
|
160
|
-
combinedShape = .manuallyInterpolating(shapes: allPathKeyframes, name: group.name)
|
|
161
|
-
}
|
|
147
|
+
let combinedShape = CombinedShapeItem(
|
|
148
|
+
shapes: Keyframes.combined(allPathKeyframes),
|
|
149
|
+
name: group.name)
|
|
162
150
|
|
|
163
151
|
let sublayer = try ShapeItemLayer(
|
|
164
152
|
shape: ShapeItemLayer.Item(item: combinedShape, groupPath: shapeRenderGroup.pathItems[0].groupPath),
|
|
@@ -194,7 +182,8 @@ extension CALayer {
|
|
|
194
182
|
from items: [ShapeItem],
|
|
195
183
|
parentGroup: Group?,
|
|
196
184
|
parentGroupPath: [String],
|
|
197
|
-
context: LayerContext)
|
|
185
|
+
context: LayerContext)
|
|
186
|
+
throws
|
|
198
187
|
{
|
|
199
188
|
let groupLayers = try makeGroupLayers(
|
|
200
189
|
from: items,
|
|
@@ -214,8 +203,8 @@ extension CALayer {
|
|
|
214
203
|
from items: [ShapeItem],
|
|
215
204
|
parentGroup: Group?,
|
|
216
205
|
parentGroupPath: [String],
|
|
217
|
-
context: LayerContext)
|
|
218
|
-
-> [GroupLayer]
|
|
206
|
+
context: LayerContext)
|
|
207
|
+
throws -> [GroupLayer]
|
|
219
208
|
{
|
|
220
209
|
var (groupItems, otherItems) = items
|
|
221
210
|
.filter { !$0.hidden }
|
|
@@ -6,7 +6,7 @@ import QuartzCore
|
|
|
6
6
|
// MARK: - ValueProviderStore
|
|
7
7
|
|
|
8
8
|
/// Registration and storage for `AnyValueProvider`s that can dynamically
|
|
9
|
-
/// provide custom values for `AnimationKeypath`s within
|
|
9
|
+
/// provide custom values for `AnimationKeypath`s within a `LottieAnimation`.
|
|
10
10
|
final class ValueProviderStore {
|
|
11
11
|
|
|
12
12
|
// MARK: Lifecycle
|
|
@@ -40,8 +40,7 @@ final class ValueProviderStore {
|
|
|
40
40
|
of customizableProperty: CustomizableProperty<Value>,
|
|
41
41
|
for keypath: AnimationKeypath,
|
|
42
42
|
context: LayerAnimationContext)
|
|
43
|
-
throws
|
|
44
|
-
-> KeyframeGroup<Value>?
|
|
43
|
+
throws -> KeyframeGroup<Value>?
|
|
45
44
|
{
|
|
46
45
|
if context.logHierarchyKeypaths {
|
|
47
46
|
context.logger.info(keypath.fullPath)
|
|
@@ -73,7 +73,7 @@ final class MaskContainerLayer: CALayer {
|
|
|
73
73
|
// MARK: Internal
|
|
74
74
|
|
|
75
75
|
func updateWithFrame(frame: CGFloat, forceUpdates: Bool) {
|
|
76
|
-
maskLayers.forEach
|
|
76
|
+
maskLayers.forEach { $0.updateWithFrame(frame: frame, forceUpdates: forceUpdates) }
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// MARK: Fileprivate
|
|
@@ -103,8 +103,8 @@ private class MaskLayer: CALayer {
|
|
|
103
103
|
addSublayer(maskLayer)
|
|
104
104
|
anchorPoint = .zero
|
|
105
105
|
maskLayer.fillColor = mask.mode == .add
|
|
106
|
-
?
|
|
107
|
-
:
|
|
106
|
+
? .rgb(1, 0, 0)
|
|
107
|
+
: .rgb(0, 1, 0)
|
|
108
108
|
maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
|
|
109
109
|
actions = [
|
|
110
110
|
"opacity" : NSNull(),
|
|
@@ -183,7 +183,7 @@ private class MaskNodeProperties: NodePropertyMap {
|
|
|
183
183
|
let mode: MaskMode
|
|
184
184
|
let inverted: Bool
|
|
185
185
|
|
|
186
|
-
let opacity: NodeProperty<
|
|
186
|
+
let opacity: NodeProperty<LottieVector1D>
|
|
187
187
|
let shape: NodeProperty<BezierPath>
|
|
188
|
-
let expansion: NodeProperty<
|
|
188
|
+
let expansion: NodeProperty<LottieVector1D>
|
|
189
189
|
}
|
|
@@ -90,7 +90,7 @@ final class PreCompositionLayer: CompositionLayer {
|
|
|
90
90
|
// MARK: Internal
|
|
91
91
|
|
|
92
92
|
let frameRate: CGFloat
|
|
93
|
-
let remappingNode: NodeProperty<
|
|
93
|
+
let remappingNode: NodeProperty<LottieVector1D>?
|
|
94
94
|
|
|
95
95
|
override var keypathProperties: [String: AnyNodeProperty] {
|
|
96
96
|
guard let remappingNode = remappingNode else {
|
|
@@ -107,12 +107,12 @@ final class PreCompositionLayer: CompositionLayer {
|
|
|
107
107
|
} else {
|
|
108
108
|
localFrame = (frame - startFrame) / timeStretch
|
|
109
109
|
}
|
|
110
|
-
animationLayers.forEach
|
|
110
|
+
animationLayers.forEach { $0.displayWithFrame(frame: localFrame, forceUpdates: forceUpdates) }
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
override func updateRenderScale() {
|
|
114
114
|
super.updateRenderScale()
|
|
115
|
-
animationLayers.forEach
|
|
115
|
+
animationLayers.forEach { $0.renderScale = renderScale }
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// MARK: Fileprivate
|
|
@@ -15,7 +15,7 @@ final class SolidCompositionLayer: CompositionLayer {
|
|
|
15
15
|
init(solid: SolidLayerModel) {
|
|
16
16
|
let components = solid.colorHex.hexColorComponents()
|
|
17
17
|
colorProperty =
|
|
18
|
-
NodeProperty(provider: SingleValueProvider(
|
|
18
|
+
NodeProperty(provider: SingleValueProvider(LottieColor(
|
|
19
19
|
r: Double(components.red),
|
|
20
20
|
g: Double(components.green),
|
|
21
21
|
b: Double(components.blue),
|
|
@@ -41,7 +41,7 @@ final class SolidCompositionLayer: CompositionLayer {
|
|
|
41
41
|
|
|
42
42
|
// MARK: Internal
|
|
43
43
|
|
|
44
|
-
let colorProperty: NodeProperty<
|
|
44
|
+
let colorProperty: NodeProperty<LottieColor>?
|
|
45
45
|
let solidShape = CAShapeLayer()
|
|
46
46
|
|
|
47
47
|
override var keypathProperties: [String: AnyNodeProperty] {
|
|
@@ -19,7 +19,7 @@ final class MainThreadAnimationLayer: CALayer, RootAnimationLayer {
|
|
|
19
19
|
// MARK: Lifecycle
|
|
20
20
|
|
|
21
21
|
init(
|
|
22
|
-
animation:
|
|
22
|
+
animation: LottieAnimation,
|
|
23
23
|
imageProvider: AnimationImageProvider,
|
|
24
24
|
textProvider: AnimationTextProvider,
|
|
25
25
|
fontProvider: AnimationFontProvider,
|
|
@@ -31,6 +31,7 @@ final class MainThreadAnimationLayer: CALayer, RootAnimationLayer {
|
|
|
31
31
|
animationLayers = []
|
|
32
32
|
self.logger = logger
|
|
33
33
|
super.init()
|
|
34
|
+
masksToBounds = true
|
|
34
35
|
bounds = animation.bounds
|
|
35
36
|
let layers = animation.layers.initializeCompositionLayers(
|
|
36
37
|
assetLibrary: animation.assetLibrary,
|
|
@@ -152,7 +153,7 @@ final class MainThreadAnimationLayer: CALayer, RootAnimationLayer {
|
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
var isAnimationPlaying: Bool? {
|
|
155
|
-
nil // this state is managed by `
|
|
156
|
+
nil // this state is managed by `LottieAnimationView`
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
var _animationLayers: [CALayer] {
|
|
@@ -170,7 +171,7 @@ final class MainThreadAnimationLayer: CALayer, RootAnimationLayer {
|
|
|
170
171
|
|
|
171
172
|
var renderScale: CGFloat = 1 {
|
|
172
173
|
didSet {
|
|
173
|
-
animationLayers.forEach
|
|
174
|
+
animationLayers.forEach { $0.renderScale = renderScale }
|
|
174
175
|
}
|
|
175
176
|
}
|
|
176
177
|
|
|
@@ -189,17 +190,17 @@ final class MainThreadAnimationLayer: CALayer, RootAnimationLayer {
|
|
|
189
190
|
}
|
|
190
191
|
|
|
191
192
|
func removeAnimations() {
|
|
192
|
-
// no-op, since the primary animation is managed by the `
|
|
193
|
+
// no-op, since the primary animation is managed by the `LottieAnimationView`.
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
/// Forces the view to update its drawing.
|
|
196
197
|
func forceDisplayUpdate() {
|
|
197
|
-
animationLayers.forEach
|
|
198
|
+
animationLayers.forEach { $0.displayWithFrame(frame: currentFrame, forceUpdates: true) }
|
|
198
199
|
}
|
|
199
200
|
|
|
200
201
|
func logHierarchyKeypaths() {
|
|
201
202
|
logger.info("Lottie: Logging Animation Keypaths")
|
|
202
|
-
animationLayers.forEach
|
|
203
|
+
animationLayers.forEach { $0.logKeypaths(for: nil, logger: self.logger) }
|
|
203
204
|
}
|
|
204
205
|
|
|
205
206
|
func setValueProvider(_ valueProvider: AnyValueProvider, keypath: AnimationKeypath) {
|
|
@@ -48,9 +48,7 @@ final class InvertedMatteLayer: CALayer, CompositionLayerDelegate {
|
|
|
48
48
|
|
|
49
49
|
override func draw(in ctx: CGContext) {
|
|
50
50
|
guard let inputMatte = inputMatte else { return }
|
|
51
|
-
|
|
52
|
-
else { return }
|
|
53
|
-
ctx.setFillColor(fillColor)
|
|
51
|
+
ctx.setFillColor(.rgb(0, 0, 0))
|
|
54
52
|
ctx.fill(bounds)
|
|
55
53
|
ctx.setBlendMode(.destinationOut)
|
|
56
54
|
inputMatte.render(in: ctx)
|
|
@@ -32,15 +32,15 @@ final class LayerTransformProperties: NodePropertyMap, KeypathSearchable {
|
|
|
32
32
|
let positionKeyframesX = transform.positionX?.keyframes,
|
|
33
33
|
let positionKeyframesY = transform.positionY?.keyframes
|
|
34
34
|
{
|
|
35
|
-
let xPosition: NodeProperty<
|
|
36
|
-
let yPosition: NodeProperty<
|
|
35
|
+
let xPosition: NodeProperty<LottieVector1D> = NodeProperty(provider: KeyframeInterpolator(keyframes: positionKeyframesX))
|
|
36
|
+
let yPosition: NodeProperty<LottieVector1D> = NodeProperty(provider: KeyframeInterpolator(keyframes: positionKeyframesY))
|
|
37
37
|
propertyMap["X Position"] = xPosition
|
|
38
38
|
propertyMap["Y Position"] = yPosition
|
|
39
39
|
positionX = xPosition
|
|
40
40
|
positionY = yPosition
|
|
41
41
|
position = nil
|
|
42
42
|
} else if let positionKeyframes = transform.position?.keyframes {
|
|
43
|
-
let position: NodeProperty<
|
|
43
|
+
let position: NodeProperty<LottieVector3D> = NodeProperty(provider: KeyframeInterpolator(keyframes: positionKeyframes))
|
|
44
44
|
propertyMap["Position"] = position
|
|
45
45
|
self.position = position
|
|
46
46
|
positionX = nil
|
|
@@ -62,13 +62,13 @@ final class LayerTransformProperties: NodePropertyMap, KeypathSearchable {
|
|
|
62
62
|
|
|
63
63
|
let properties: [AnyNodeProperty]
|
|
64
64
|
|
|
65
|
-
let anchor: NodeProperty<
|
|
66
|
-
let scale: NodeProperty<
|
|
67
|
-
let rotation: NodeProperty<
|
|
68
|
-
let position: NodeProperty<
|
|
69
|
-
let positionX: NodeProperty<
|
|
70
|
-
let positionY: NodeProperty<
|
|
71
|
-
let opacity: NodeProperty<
|
|
65
|
+
let anchor: NodeProperty<LottieVector3D>
|
|
66
|
+
let scale: NodeProperty<LottieVector3D>
|
|
67
|
+
let rotation: NodeProperty<LottieVector1D>
|
|
68
|
+
let position: NodeProperty<LottieVector3D>?
|
|
69
|
+
let positionX: NodeProperty<LottieVector1D>?
|
|
70
|
+
let positionY: NodeProperty<LottieVector1D>?
|
|
71
|
+
let opacity: NodeProperty<LottieVector1D>
|
|
72
72
|
|
|
73
73
|
var childKeypaths: [KeypathSearchable] {
|
|
74
74
|
[]
|
|
@@ -68,6 +68,13 @@ extension Array where Element == ShapeItem {
|
|
|
68
68
|
let node = TrimPathNode(parentNode: nodeTree.rootNode, trim: trim, upstreamPaths: nodeTree.paths)
|
|
69
69
|
nodeTree.rootNode = node
|
|
70
70
|
nodeTree.childrenNodes.append(node)
|
|
71
|
+
} else if let roundedCorners = item as? RoundedCorners {
|
|
72
|
+
let node = RoundedCornersNode(
|
|
73
|
+
parentNode: nodeTree.rootNode,
|
|
74
|
+
roundedCorners: roundedCorners,
|
|
75
|
+
upstreamPaths: nodeTree.paths)
|
|
76
|
+
nodeTree.rootNode = node
|
|
77
|
+
nodeTree.childrenNodes.append(node)
|
|
71
78
|
} else if let xform = item as? ShapeTransform {
|
|
72
79
|
nodeTree.transform = xform
|
|
73
80
|
continue
|
|
@@ -15,7 +15,7 @@ final class GroupInterpolator<ValueType>: ValueProvider where ValueType: Interpo
|
|
|
15
15
|
|
|
16
16
|
/// Initialize with an array of array of keyframes.
|
|
17
17
|
init(keyframeGroups: ContiguousArray<ContiguousArray<Keyframe<ValueType>>>) {
|
|
18
|
-
keyframeInterpolators = ContiguousArray(keyframeGroups.map
|
|
18
|
+
keyframeInterpolators = ContiguousArray(keyframeGroups.map { KeyframeInterpolator(keyframes: $0) })
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
// MARK: Internal
|
|
@@ -28,7 +28,7 @@ final class GroupInterpolator<ValueType>: ValueProvider where ValueType: Interpo
|
|
|
28
28
|
|
|
29
29
|
var storage: ValueProviderStorage<[ValueType]> {
|
|
30
30
|
.closure { frame in
|
|
31
|
-
self.keyframeInterpolators.map
|
|
31
|
+
self.keyframeInterpolators.map { $0.value(frame: frame) as! ValueType }
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/RoundedCornersNode.swift
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RoundedCornersNode.swift
|
|
3
|
+
// Lottie
|
|
4
|
+
//
|
|
5
|
+
// Created by Duolingo on 10/31/22.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import QuartzCore
|
|
10
|
+
|
|
11
|
+
// MARK: - RoundedCornersProperties
|
|
12
|
+
|
|
13
|
+
final class RoundedCornersProperties: NodePropertyMap, KeypathSearchable {
|
|
14
|
+
|
|
15
|
+
// MARK: Lifecycle
|
|
16
|
+
|
|
17
|
+
init(roundedCorners: RoundedCorners) {
|
|
18
|
+
keypathName = roundedCorners.name
|
|
19
|
+
radius = NodeProperty(provider: KeyframeInterpolator(keyframes: roundedCorners.radius.keyframes))
|
|
20
|
+
keypathProperties = ["Radius" : radius]
|
|
21
|
+
properties = Array(keypathProperties.values)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// MARK: Internal
|
|
25
|
+
|
|
26
|
+
let keypathProperties: [String: AnyNodeProperty]
|
|
27
|
+
let properties: [AnyNodeProperty]
|
|
28
|
+
let keypathName: String
|
|
29
|
+
|
|
30
|
+
let radius: NodeProperty<LottieVector1D>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// MARK: - RoundedCornersNode
|
|
34
|
+
|
|
35
|
+
final class RoundedCornersNode: AnimatorNode {
|
|
36
|
+
|
|
37
|
+
// MARK: Lifecycle
|
|
38
|
+
|
|
39
|
+
init(parentNode: AnimatorNode?, roundedCorners: RoundedCorners, upstreamPaths: [PathOutputNode]) {
|
|
40
|
+
outputNode = PassThroughOutputNode(parent: parentNode?.outputNode)
|
|
41
|
+
self.parentNode = parentNode
|
|
42
|
+
properties = RoundedCornersProperties(roundedCorners: roundedCorners)
|
|
43
|
+
self.upstreamPaths = upstreamPaths
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// MARK: Internal
|
|
47
|
+
|
|
48
|
+
let properties: RoundedCornersProperties
|
|
49
|
+
|
|
50
|
+
let parentNode: AnimatorNode?
|
|
51
|
+
let outputNode: NodeOutput
|
|
52
|
+
var hasLocalUpdates = false
|
|
53
|
+
var hasUpstreamUpdates = false
|
|
54
|
+
var lastUpdateFrame: CGFloat? = nil
|
|
55
|
+
var isEnabled = true
|
|
56
|
+
|
|
57
|
+
// MARK: Animator Node
|
|
58
|
+
var propertyMap: NodePropertyMap & KeypathSearchable {
|
|
59
|
+
properties
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
func forceUpstreamOutputUpdates() -> Bool {
|
|
63
|
+
hasLocalUpdates || hasUpstreamUpdates
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
func rebuildOutputs(frame: CGFloat) {
|
|
67
|
+
for pathContainer in upstreamPaths {
|
|
68
|
+
let pathObjects = pathContainer.removePaths(updateFrame: frame)
|
|
69
|
+
for path in pathObjects {
|
|
70
|
+
let cornerRadius = properties.radius.value.cgFloatValue
|
|
71
|
+
if cornerRadius != 0 {
|
|
72
|
+
pathContainer.appendPath(
|
|
73
|
+
path.roundCorners(radius: cornerRadius),
|
|
74
|
+
updateFrame: frame)
|
|
75
|
+
} else {
|
|
76
|
+
pathContainer.appendPath(path, updateFrame: frame)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// MARK: Fileprivate
|
|
83
|
+
|
|
84
|
+
fileprivate let upstreamPaths: [PathOutputNode]
|
|
85
|
+
}
|
|
@@ -34,9 +34,9 @@ final class TrimPathProperties: NodePropertyMap, KeypathSearchable {
|
|
|
34
34
|
let properties: [AnyNodeProperty]
|
|
35
35
|
let keypathName: String
|
|
36
36
|
|
|
37
|
-
let start: NodeProperty<
|
|
38
|
-
let end: NodeProperty<
|
|
39
|
-
let offset: NodeProperty<
|
|
37
|
+
let start: NodeProperty<LottieVector1D>
|
|
38
|
+
let end: NodeProperty<LottieVector1D>
|
|
39
|
+
let offset: NodeProperty<LottieVector1D>
|
|
40
40
|
let type: TrimType
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -133,7 +133,7 @@ final class TrimPathNode: AnimatorNode {
|
|
|
133
133
|
|
|
134
134
|
/// First get the total length of all paths.
|
|
135
135
|
var totalLength: CGFloat = 0
|
|
136
|
-
upstreamPaths.forEach
|
|
136
|
+
upstreamPaths.forEach { totalLength = totalLength + $0.totalLength }
|
|
137
137
|
|
|
138
138
|
/// Now determine the start and end cut lengths
|
|
139
139
|
let startLength = startPosition * totalLength
|
|
@@ -48,15 +48,11 @@ private final class GradientFillLayer: CALayer {
|
|
|
48
48
|
|
|
49
49
|
var gradientColors = [CGColor]()
|
|
50
50
|
var colorLocations = [CGFloat]()
|
|
51
|
-
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
|
52
51
|
let maskColorSpace = CGColorSpaceCreateDeviceGray()
|
|
53
52
|
for i in 0..<numberOfColors {
|
|
54
53
|
let ix = i * 4
|
|
55
|
-
if
|
|
56
|
-
colors
|
|
57
|
-
colorSpace: colorSpace,
|
|
58
|
-
components: [colors[ix + 1], colors[ix + 2], colors[ix + 3], 1])
|
|
59
|
-
{
|
|
54
|
+
if colors.count > ix {
|
|
55
|
+
let color = CGColor.rgb(colors[ix + 1], colors[ix + 2], colors[ix + 3])
|
|
60
56
|
gradientColors.append(color)
|
|
61
57
|
colorLocations.append(colors[ix])
|
|
62
58
|
}
|
|
@@ -68,10 +64,8 @@ private final class GradientFillLayer: CALayer {
|
|
|
68
64
|
if alpha < 1 {
|
|
69
65
|
drawMask = true
|
|
70
66
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
alphaColors.append(color)
|
|
74
|
-
}
|
|
67
|
+
alphaLocations.append(colors[i])
|
|
68
|
+
alphaColors.append(.gray(alpha))
|
|
75
69
|
}
|
|
76
70
|
|
|
77
71
|
/// First draw a mask is necessary.
|
|
@@ -114,8 +108,13 @@ private final class GradientFillLayer: CALayer {
|
|
|
114
108
|
}
|
|
115
109
|
|
|
116
110
|
/// Now draw the gradient
|
|
117
|
-
guard
|
|
111
|
+
guard
|
|
112
|
+
let gradient = CGGradient(
|
|
113
|
+
colorsSpace: CGColorSpaceCreateDeviceRGB(),
|
|
114
|
+
colors: gradientColors as CFArray,
|
|
115
|
+
locations: colorLocations)
|
|
118
116
|
else { return }
|
|
117
|
+
|
|
119
118
|
if type == .linear {
|
|
120
119
|
ctx.drawLinearGradient(gradient, start: start, end: end, options: [.drawsAfterEndLocation, .drawsBeforeStartLocation])
|
|
121
120
|
} else {
|
|
@@ -141,7 +140,7 @@ final class GradientFillRenderer: PassThroughOutputNode, Renderable {
|
|
|
141
140
|
override init(parent: NodeOutput?) {
|
|
142
141
|
super.init(parent: parent)
|
|
143
142
|
|
|
144
|
-
maskLayer.fillColor =
|
|
143
|
+
maskLayer.fillColor = .rgb(1, 1, 1)
|
|
145
144
|
gradientLayer.mask = maskLayer
|
|
146
145
|
|
|
147
146
|
maskLayer.actions = [
|
|
@@ -17,7 +17,7 @@ final class GradientStrokeRenderer: PassThroughOutputNode, Renderable {
|
|
|
17
17
|
override init(parent: NodeOutput?) {
|
|
18
18
|
strokeRender = StrokeRenderer(parent: nil)
|
|
19
19
|
gradientRender = LegacyGradientFillRenderer(parent: nil)
|
|
20
|
-
strokeRender.color =
|
|
20
|
+
strokeRender.color = .rgb(1, 1, 1)
|
|
21
21
|
super.init(parent: parent)
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -67,15 +67,11 @@ final class LegacyGradientFillRenderer: PassThroughOutputNode, Renderable {
|
|
|
67
67
|
|
|
68
68
|
var gradientColors = [CGColor]()
|
|
69
69
|
var colorLocations = [CGFloat]()
|
|
70
|
-
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
|
71
70
|
let maskColorSpace = CGColorSpaceCreateDeviceGray()
|
|
72
71
|
for i in 0..<numberOfColors {
|
|
73
72
|
let ix = i * 4
|
|
74
|
-
if
|
|
75
|
-
colors
|
|
76
|
-
colorSpace: colorSpace,
|
|
77
|
-
components: [colors[ix + 1], colors[ix + 2], colors[ix + 3], 1])
|
|
78
|
-
{
|
|
73
|
+
if colors.count > ix {
|
|
74
|
+
let color = CGColor.rgb(colors[ix + 1], colors[ix + 2], colors[ix + 3])
|
|
79
75
|
gradientColors.append(color)
|
|
80
76
|
colorLocations.append(colors[ix])
|
|
81
77
|
}
|
|
@@ -87,10 +83,8 @@ final class LegacyGradientFillRenderer: PassThroughOutputNode, Renderable {
|
|
|
87
83
|
if alpha < 1 {
|
|
88
84
|
drawMask = true
|
|
89
85
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
alphaColors.append(color)
|
|
93
|
-
}
|
|
86
|
+
alphaLocations.append(colors[i])
|
|
87
|
+
alphaColors.append(.gray(alpha))
|
|
94
88
|
}
|
|
95
89
|
|
|
96
90
|
inContext.setAlpha(opacity)
|
|
@@ -136,8 +130,13 @@ final class LegacyGradientFillRenderer: PassThroughOutputNode, Renderable {
|
|
|
136
130
|
}
|
|
137
131
|
|
|
138
132
|
/// Now draw the gradient
|
|
139
|
-
guard
|
|
133
|
+
guard
|
|
134
|
+
let gradient = CGGradient(
|
|
135
|
+
colorsSpace: CGColorSpaceCreateDeviceRGB(),
|
|
136
|
+
colors: gradientColors as CFArray,
|
|
137
|
+
locations: colorLocations)
|
|
140
138
|
else { return }
|
|
139
|
+
|
|
141
140
|
if type == .linear {
|
|
142
141
|
inContext.drawLinearGradient(gradient, start: start, end: end, options: [.drawsAfterEndLocation, .drawsBeforeStartLocation])
|
|
143
142
|
} else {
|
|
@@ -160,7 +160,7 @@ final class StrokeRenderer: PassThroughOutputNode, Renderable {
|
|
|
160
160
|
layer.lineDashPhase = dashPhase ?? 0
|
|
161
161
|
layer.fillColor = nil
|
|
162
162
|
if let dashPattern = dashLengths {
|
|
163
|
-
layer.lineDashPattern = dashPattern.map
|
|
163
|
+
layer.lineDashPattern = dashPattern.map { NSNumber(value: Double($0)) }
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
}
|
|
@@ -31,8 +31,8 @@ final class EllipseNodeProperties: NodePropertyMap, KeypathSearchable {
|
|
|
31
31
|
var keypathName: String
|
|
32
32
|
|
|
33
33
|
let direction: PathDirection
|
|
34
|
-
let position: NodeProperty<
|
|
35
|
-
let size: NodeProperty<
|
|
34
|
+
let position: NodeProperty<LottieVector3D>
|
|
35
|
+
let size: NodeProperty<LottieVector3D>
|
|
36
36
|
|
|
37
37
|
let keypathProperties: [String: AnyNodeProperty]
|
|
38
38
|
let properties: [AnyNodeProperty]
|
|
@@ -42,11 +42,11 @@ final class PolygonNodeProperties: NodePropertyMap, KeypathSearchable {
|
|
|
42
42
|
let properties: [AnyNodeProperty]
|
|
43
43
|
|
|
44
44
|
let direction: PathDirection
|
|
45
|
-
let position: NodeProperty<
|
|
46
|
-
let outerRadius: NodeProperty<
|
|
47
|
-
let outerRoundedness: NodeProperty<
|
|
48
|
-
let rotation: NodeProperty<
|
|
49
|
-
let points: NodeProperty<
|
|
45
|
+
let position: NodeProperty<LottieVector3D>
|
|
46
|
+
let outerRadius: NodeProperty<LottieVector1D>
|
|
47
|
+
let outerRoundedness: NodeProperty<LottieVector1D>
|
|
48
|
+
let rotation: NodeProperty<LottieVector1D>
|
|
49
|
+
let points: NodeProperty<LottieVector1D>
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// MARK: - PolygonNode
|
|
@@ -38,9 +38,9 @@ final class RectNodeProperties: NodePropertyMap, KeypathSearchable {
|
|
|
38
38
|
let properties: [AnyNodeProperty]
|
|
39
39
|
|
|
40
40
|
let direction: PathDirection
|
|
41
|
-
let position: NodeProperty<
|
|
42
|
-
let size: NodeProperty<
|
|
43
|
-
let cornerRadius: NodeProperty<
|
|
41
|
+
let position: NodeProperty<LottieVector3D>
|
|
42
|
+
let size: NodeProperty<LottieVector3D>
|
|
43
|
+
let cornerRadius: NodeProperty<LottieVector1D>
|
|
44
44
|
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -23,12 +23,12 @@ final class StarNodeProperties: NodePropertyMap, KeypathSearchable {
|
|
|
23
23
|
if let innerRadiusKeyframes = star.innerRadius?.keyframes {
|
|
24
24
|
innerRadius = NodeProperty(provider: KeyframeInterpolator(keyframes: innerRadiusKeyframes))
|
|
25
25
|
} else {
|
|
26
|
-
innerRadius = NodeProperty(provider: SingleValueProvider(
|
|
26
|
+
innerRadius = NodeProperty(provider: SingleValueProvider(LottieVector1D(0)))
|
|
27
27
|
}
|
|
28
28
|
if let innderRoundedness = star.innerRoundness?.keyframes {
|
|
29
29
|
innerRoundedness = NodeProperty(provider: KeyframeInterpolator(keyframes: innderRoundedness))
|
|
30
30
|
} else {
|
|
31
|
-
innerRoundedness = NodeProperty(provider: SingleValueProvider(
|
|
31
|
+
innerRoundedness = NodeProperty(provider: SingleValueProvider(LottieVector1D(0)))
|
|
32
32
|
}
|
|
33
33
|
rotation = NodeProperty(provider: KeyframeInterpolator(keyframes: star.rotation.keyframes))
|
|
34
34
|
points = NodeProperty(provider: KeyframeInterpolator(keyframes: star.points.keyframes))
|
|
@@ -52,13 +52,13 @@ final class StarNodeProperties: NodePropertyMap, KeypathSearchable {
|
|
|
52
52
|
let properties: [AnyNodeProperty]
|
|
53
53
|
|
|
54
54
|
let direction: PathDirection
|
|
55
|
-
let position: NodeProperty<
|
|
56
|
-
let outerRadius: NodeProperty<
|
|
57
|
-
let outerRoundedness: NodeProperty<
|
|
58
|
-
let innerRadius: NodeProperty<
|
|
59
|
-
let innerRoundedness: NodeProperty<
|
|
60
|
-
let rotation: NodeProperty<
|
|
61
|
-
let points: NodeProperty<
|
|
55
|
+
let position: NodeProperty<LottieVector3D>
|
|
56
|
+
let outerRadius: NodeProperty<LottieVector1D>
|
|
57
|
+
let outerRoundedness: NodeProperty<LottieVector1D>
|
|
58
|
+
let innerRadius: NodeProperty<LottieVector1D>
|
|
59
|
+
let innerRoundedness: NodeProperty<LottieVector1D>
|
|
60
|
+
let rotation: NodeProperty<LottieVector1D>
|
|
61
|
+
let points: NodeProperty<LottieVector1D>
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// MARK: - StarNode
|
|
@@ -26,13 +26,13 @@ final class GroupNodeProperties: NodePropertyMap, KeypathSearchable {
|
|
|
26
26
|
skewAxis = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.skewAxis.keyframes))
|
|
27
27
|
} else {
|
|
28
28
|
/// Transform node missing. Default to empty transform.
|
|
29
|
-
anchor = NodeProperty(provider: SingleValueProvider(
|
|
30
|
-
position = NodeProperty(provider: SingleValueProvider(
|
|
31
|
-
scale = NodeProperty(provider: SingleValueProvider(
|
|
32
|
-
rotation = NodeProperty(provider: SingleValueProvider(
|
|
33
|
-
opacity = NodeProperty(provider: SingleValueProvider(
|
|
34
|
-
skew = NodeProperty(provider: SingleValueProvider(
|
|
35
|
-
skewAxis = NodeProperty(provider: SingleValueProvider(
|
|
29
|
+
anchor = NodeProperty(provider: SingleValueProvider(LottieVector3D(x: CGFloat(0), y: CGFloat(0), z: CGFloat(0))))
|
|
30
|
+
position = NodeProperty(provider: SingleValueProvider(LottieVector3D(x: CGFloat(0), y: CGFloat(0), z: CGFloat(0))))
|
|
31
|
+
scale = NodeProperty(provider: SingleValueProvider(LottieVector3D(x: CGFloat(100), y: CGFloat(100), z: CGFloat(100))))
|
|
32
|
+
rotation = NodeProperty(provider: SingleValueProvider(LottieVector1D(0)))
|
|
33
|
+
opacity = NodeProperty(provider: SingleValueProvider(LottieVector1D(100)))
|
|
34
|
+
skew = NodeProperty(provider: SingleValueProvider(LottieVector1D(0)))
|
|
35
|
+
skewAxis = NodeProperty(provider: SingleValueProvider(LottieVector1D(0)))
|
|
36
36
|
}
|
|
37
37
|
keypathProperties = [
|
|
38
38
|
"Anchor Point" : anchor,
|
|
@@ -55,13 +55,13 @@ final class GroupNodeProperties: NodePropertyMap, KeypathSearchable {
|
|
|
55
55
|
let keypathProperties: [String: AnyNodeProperty]
|
|
56
56
|
let properties: [AnyNodeProperty]
|
|
57
57
|
|
|
58
|
-
let anchor: NodeProperty<
|
|
59
|
-
let position: NodeProperty<
|
|
60
|
-
let scale: NodeProperty<
|
|
61
|
-
let rotation: NodeProperty<
|
|
62
|
-
let opacity: NodeProperty<
|
|
63
|
-
let skew: NodeProperty<
|
|
64
|
-
let skewAxis: NodeProperty<
|
|
58
|
+
let anchor: NodeProperty<LottieVector3D>
|
|
59
|
+
let position: NodeProperty<LottieVector3D>
|
|
60
|
+
let scale: NodeProperty<LottieVector3D>
|
|
61
|
+
let rotation: NodeProperty<LottieVector1D>
|
|
62
|
+
let opacity: NodeProperty<LottieVector1D>
|
|
63
|
+
let skew: NodeProperty<LottieVector1D>
|
|
64
|
+
let skewAxis: NodeProperty<LottieVector1D>
|
|
65
65
|
|
|
66
66
|
var caTransform: CATransform3D {
|
|
67
67
|
CATransform3D.makeTransform(
|
|
@@ -30,8 +30,8 @@ final class FillNodeProperties: NodePropertyMap, KeypathSearchable {
|
|
|
30
30
|
|
|
31
31
|
var keypathName: String
|
|
32
32
|
|
|
33
|
-
let opacity: NodeProperty<
|
|
34
|
-
let color: NodeProperty<
|
|
33
|
+
let opacity: NodeProperty<LottieVector1D>
|
|
34
|
+
let color: NodeProperty<LottieColor>
|
|
35
35
|
let type: FillRule
|
|
36
36
|
|
|
37
37
|
let keypathProperties: [String: AnyNodeProperty]
|