lottie-ios 4.3.3 → 4.4.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/.github/workflows/main.yml +51 -58
- package/Lottie.xcodeproj/project.pbxproj +40 -0
- package/Lottie.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +4 -17
- package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +37 -40
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +9 -666
- package/Package.resolved +20 -22
- package/Package.swift +4 -2
- package/README.md +21 -3
- package/Rakefile +52 -28
- package/Sources/PrivacyInfo.xcprivacy +23 -0
- package/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift +1 -1
- package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +23 -13
- package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +8 -2
- package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +7 -1
- package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +15 -2
- package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +8 -1
- package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +8 -1
- package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +12 -1
- package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +0 -1
- package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +19 -11
- package/Sources/Private/CoreAnimation/Animations/VisibilityAnimation.swift +45 -19
- package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +38 -3
- package/Sources/Private/CoreAnimation/Extensions/CALayer+fillBounds.swift +1 -1
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift +9 -2
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+timeRemapping.swift +46 -0
- package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +77 -13
- package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +1 -1
- package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +2 -2
- package/Sources/Private/CoreAnimation/Layers/ImageLayer.swift +1 -1
- package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +1 -7
- package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +19 -53
- package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +2 -2
- package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +97 -31
- package/Sources/Private/CoreAnimation/Layers/SolidLayer.swift +5 -2
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelArrayBuilder.swift +1 -1
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelProperty.swift +10 -10
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingController.swift +1 -1
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift +1 -3
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIIntrinsicContentSizeInvalidator.swift +2 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUILayoutMargins.swift +2 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxyableView+SwiftUIView.swift +2 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/MeasuringViewRepresentable.swift +2 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift +2 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift +2 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIView+SwiftUIView.swift +2 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIViewConfiguringSwiftUIView.swift +2 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ViewType.swift +2 -1
- package/Sources/Private/EmbeddedLibraries/LRUCache/LRUCache.swift +256 -0
- package/Sources/Private/EmbeddedLibraries/LRUCache/README.md +24 -0
- package/Sources/Private/EmbeddedLibraries/README.md +16 -0
- package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Helpers.swift +2 -2
- package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+MemoryFile.swift +7 -7
- package/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Compression.swift +2 -2
- package/Sources/Private/EmbeddedLibraries/ZipFoundation/FileManager+ZIP.swift +5 -5
- package/Sources/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.swift +1 -2
- package/Sources/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.swift +1 -3
- package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +1 -2
- package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +2 -3
- package/Sources/Private/MainThread/LayerContainers/CompLayers/SolidCompositionLayer.swift +2 -3
- package/Sources/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.swift +5 -12
- package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +0 -1
- package/Sources/Private/MainThread/LayerContainers/Utility/CachedImageProvider.swift +11 -7
- package/Sources/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.swift +3 -3
- package/Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift +12 -12
- package/Sources/Private/MainThread/LayerContainers/Utility/InvertedMatteLayer.swift +1 -3
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerFontProvider.swift +0 -2
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerImageProvider.swift +1 -3
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerTextProvider.swift +0 -2
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerTransformNode.swift +0 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Extensions/ItemsExtension.swift +1 -3
- package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.swift +0 -1
- package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.swift +0 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/GroupOutputNode.swift +1 -3
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.swift +1 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/PathOutputNode.swift +0 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/FillRenderer.swift +0 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +0 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientStrokeRenderer.swift +0 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift +0 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +2 -3
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +1 -3
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +2 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +0 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.swift +0 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Protocols/PathNode.swift +0 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Protocols/RenderNode.swift +0 -2
- package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +0 -1
- package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeRenderLayer.swift +0 -1
- package/Sources/Private/Model/Assets/Asset.swift +2 -3
- package/Sources/Private/Model/Assets/AssetLibrary.swift +11 -11
- package/Sources/Private/Model/Assets/ImageAsset.swift +20 -0
- package/Sources/Private/Model/Assets/PrecompAsset.swift +0 -2
- package/Sources/Private/Model/DictionaryInitializable.swift +18 -10
- package/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift +9 -6
- package/Sources/Private/Model/DotLottie/DotLottieUtils.swift +1 -1
- package/Sources/Private/Model/Extensions/KeyedDecodingContainerExtensions.swift +5 -4
- package/Sources/Private/Model/Keyframes/KeyframeData.swift +1 -4
- package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +1 -3
- package/Sources/Private/Model/LayerEffects/DropShadowEffect.swift +0 -2
- package/Sources/Private/Model/LayerEffects/EffectValues/ColorEffectValue.swift +0 -2
- package/Sources/Private/Model/LayerEffects/EffectValues/EffectValue.swift +4 -5
- package/Sources/Private/Model/LayerEffects/EffectValues/Vector1DEffectValue.swift +0 -2
- package/Sources/Private/Model/LayerEffects/LayerEffect.swift +2 -3
- package/Sources/Private/Model/LayerStyles/DropShadowStyle.swift +0 -2
- package/Sources/Private/Model/LayerStyles/LayerStyle.swift +2 -3
- package/Sources/Private/Model/Layers/ImageLayerModel.swift +0 -2
- package/Sources/Private/Model/Layers/LayerModel.swift +16 -5
- package/Sources/Private/Model/Layers/PreCompLayerModel.swift +0 -2
- package/Sources/Private/Model/Layers/ShapeLayerModel.swift +0 -2
- package/Sources/Private/Model/Layers/SolidLayerModel.swift +0 -2
- package/Sources/Private/Model/Layers/TextLayerModel.swift +0 -2
- package/Sources/Private/Model/Objects/DashPattern.swift +1 -3
- package/Sources/Private/Model/Objects/Marker.swift +0 -2
- package/Sources/Private/Model/Objects/Mask.swift +0 -2
- package/Sources/Private/Model/Objects/Transform.swift +46 -9
- package/Sources/Private/Model/ShapeItems/Ellipse.swift +0 -2
- package/Sources/Private/Model/ShapeItems/Fill.swift +0 -2
- package/Sources/Private/Model/ShapeItems/GradientFill.swift +1 -3
- package/Sources/Private/Model/ShapeItems/GradientStroke.swift +1 -3
- package/Sources/Private/Model/ShapeItems/Group.swift +0 -2
- package/Sources/Private/Model/ShapeItems/Merge.swift +1 -3
- package/Sources/Private/Model/ShapeItems/Rectangle.swift +0 -2
- package/Sources/Private/Model/ShapeItems/Repeater.swift +0 -2
- package/Sources/Private/Model/ShapeItems/RoundedCorners.swift +0 -2
- package/Sources/Private/Model/ShapeItems/Shape.swift +0 -2
- package/Sources/Private/Model/ShapeItems/ShapeItem.swift +2 -3
- package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +0 -2
- package/Sources/Private/Model/ShapeItems/Star.swift +1 -3
- package/Sources/Private/Model/ShapeItems/Stroke.swift +0 -2
- package/Sources/Private/Model/ShapeItems/Trim.swift +1 -3
- package/Sources/Private/Model/Text/Font.swift +0 -2
- package/Sources/Private/Model/Text/Glyph.swift +0 -2
- package/Sources/Private/Model/Text/TextAnimator.swift +0 -2
- package/Sources/Private/Model/Text/TextDocument.swift +2 -4
- package/Sources/Private/Utility/Debugging/AnimatorNodeDebugging.swift +0 -2
- package/Sources/Private/Utility/Debugging/LayerDebugging.swift +4 -5
- package/Sources/Private/Utility/Extensions/AnimationKeypathExtension.swift +2 -3
- package/Sources/Private/Utility/Extensions/DataExtension.swift +0 -1
- package/Sources/Private/Utility/Extensions/StringExtensions.swift +5 -0
- package/Sources/Private/Utility/Helpers/AnimationContext.swift +2 -3
- package/Sources/Private/Utility/Helpers/AnyEquatable.swift +0 -2
- package/Sources/Private/Utility/Helpers/Binding+Map.swift +2 -0
- package/Sources/Private/Utility/Helpers/View+ValueChanged.swift +2 -0
- package/Sources/Private/Utility/LottieAnimationSource.swift +11 -1
- package/Sources/Private/Utility/Primitives/BezierPath.swift +2 -3
- package/Sources/Private/Utility/Primitives/CGPointExtension.swift +1 -1
- package/Sources/Private/Utility/Primitives/ColorExtension.swift +1 -2
- package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +6 -6
- package/Sources/Public/Animation/LottieAnimation.swift +2 -2
- package/Sources/Public/Animation/LottieAnimationHelpers.swift +7 -5
- package/Sources/Public/Animation/LottieAnimationLayer.swift +30 -43
- package/Sources/Public/Animation/LottieAnimationView.swift +18 -8
- package/Sources/Public/Animation/LottieAnimationViewInitializers.swift +3 -3
- package/Sources/Public/Animation/LottiePlaybackMode.swift +53 -0
- package/Sources/Public/Animation/LottieView.swift +145 -48
- package/Sources/Public/AnimationCache/AnimationCacheProvider.swift +0 -2
- package/Sources/Public/AnimationCache/DefaultAnimationCache.swift +21 -7
- package/Sources/Public/AnimationCache/LRUAnimationCache.swift +0 -2
- package/Sources/Public/Controls/AnimatedButton.swift +4 -6
- package/Sources/Public/Controls/AnimatedControl.swift +1 -3
- package/Sources/Public/Controls/AnimatedSwitch.swift +1 -3
- package/Sources/Public/Controls/LottieButton.swift +2 -1
- package/Sources/Public/Controls/LottieSwitch.swift +2 -0
- package/Sources/Public/DotLottie/Cache/DotLottieCache.swift +17 -4
- package/Sources/Public/DotLottie/Cache/DotLottieCacheProvider.swift +1 -3
- package/Sources/Public/DotLottie/DotLottieConfiguration.swift +53 -5
- package/Sources/Public/DotLottie/DotLottieFile.swift +4 -3
- package/Sources/Public/DotLottie/DotLottieFileHelpers.swift +18 -11
- package/Sources/Public/DynamicProperties/AnimationKeypath.swift +0 -2
- package/Sources/Public/DynamicProperties/AnyValueProvider.swift +0 -1
- package/Sources/Public/DynamicProperties/ValueProviders/ColorValueProvider.swift +2 -2
- package/Sources/Public/DynamicProperties/ValueProviders/FloatValueProvider.swift +1 -1
- package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +1 -1
- package/Sources/Public/DynamicProperties/ValueProviders/PointValueProvider.swift +1 -1
- package/Sources/Public/DynamicProperties/ValueProviders/SizeValueProvider.swift +1 -1
- package/Sources/Public/FontProvider/AnimationFontProvider.swift +0 -2
- package/Sources/Public/ImageProvider/AnimationImageProvider.swift +0 -2
- package/Sources/Public/Keyframes/Interpolatable.swift +26 -0
- package/Sources/Public/Primitives/LottieColor.swift +0 -2
- package/Sources/Public/Primitives/Vectors.swift +0 -2
- package/Sources/Public/TextProvider/AnimationTextProvider.swift +0 -2
- package/Sources/Public/iOS/AnimationSubview.swift +0 -1
- package/Sources/Public/iOS/BundleImageProvider.swift +3 -8
- package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +4 -8
- package/Sources/Public/iOS/LottieAnimationViewBase.swift +5 -2
- package/Sources/Public/iOS/UIColorExtension.swift +1 -2
- package/Sources/Public/macOS/BundleImageProvider.macOS.swift +3 -6
- package/lottie-ios.podspec +6 -2
- package/package.json +1 -1
- package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +0 -37
- package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -6
- package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/xcdebugger/Expressions.xcexplist +0 -153
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/IDEFindNavigatorScopes.plist +0 -5
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +0 -231
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +0 -37
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/30/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
8
|
import QuartzCore
|
|
10
9
|
|
|
11
10
|
extension LineJoin {
|
|
@@ -132,7 +131,7 @@ final class StrokeRenderer: PassThroughOutputNode, Renderable {
|
|
|
132
131
|
inContext.setMiterLimit(miterLimit)
|
|
133
132
|
inContext.setLineCap(lineCap.cgLineCap)
|
|
134
133
|
inContext.setLineJoin(lineJoin.cgLineJoin)
|
|
135
|
-
if let dashPhase
|
|
134
|
+
if let dashPhase, let lengths = dashLengths {
|
|
136
135
|
inContext.setLineDash(phase: dashPhase, lengths: lengths)
|
|
137
136
|
} else {
|
|
138
137
|
inContext.setLineDash(phase: 0, lengths: [])
|
|
@@ -143,7 +142,7 @@ final class StrokeRenderer: PassThroughOutputNode, Renderable {
|
|
|
143
142
|
guard inContext.path != nil, inContext.path!.isEmpty == false else {
|
|
144
143
|
return
|
|
145
144
|
}
|
|
146
|
-
guard let color
|
|
145
|
+
guard let color else { return }
|
|
147
146
|
hasUpdate = false
|
|
148
147
|
setupForStroke(inContext)
|
|
149
148
|
inContext.setAlpha(opacity)
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/18/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import CoreGraphics
|
|
9
|
-
import Foundation
|
|
10
8
|
import QuartzCore
|
|
11
9
|
|
|
12
10
|
// MARK: - GroupNodeProperties
|
|
@@ -16,7 +14,7 @@ final class GroupNodeProperties: NodePropertyMap, KeypathSearchable {
|
|
|
16
14
|
// MARK: Lifecycle
|
|
17
15
|
|
|
18
16
|
init(transform: ShapeTransform?) {
|
|
19
|
-
if let transform
|
|
17
|
+
if let transform {
|
|
20
18
|
anchor = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.anchor.keyframes))
|
|
21
19
|
position = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.position.keyframes))
|
|
22
20
|
scale = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.scale.keyframes))
|
|
@@ -131,7 +131,7 @@ final class StrokeNode: AnimatorNode, RenderNode {
|
|
|
131
131
|
|
|
132
132
|
// MARK: - [DashElement] + shapeLayerConfiguration
|
|
133
133
|
|
|
134
|
-
extension
|
|
134
|
+
extension [DashElement] {
|
|
135
135
|
typealias ShapeLayerConfiguration = (
|
|
136
136
|
dashPatterns: ContiguousArray<ContiguousArray<Keyframe<LottieVector1D>>>,
|
|
137
137
|
dashPhase: ContiguousArray<Keyframe<LottieVector1D>>)
|
|
@@ -168,7 +168,7 @@ extension Array where Element == DashElement {
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
extension
|
|
171
|
+
extension [CGFloat] {
|
|
172
172
|
// If all of the items in the dash pattern are zeros, then we shouldn't attempt to render it.
|
|
173
173
|
// This causes Core Animation to have extremely poor performance for some reason, even though
|
|
174
174
|
// it doesn't affect the appearance of the animation.
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/9/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
|
-
|
|
10
8
|
// MARK: - Asset
|
|
11
9
|
|
|
12
10
|
public class Asset: Codable, DictionaryInitializable {
|
|
@@ -28,7 +26,7 @@ public class Asset: Codable, DictionaryInitializable {
|
|
|
28
26
|
} else if let id = dictionary[CodingKeys.id.rawValue] as? Int {
|
|
29
27
|
self.id = String(id)
|
|
30
28
|
} else {
|
|
31
|
-
throw InitializableError.invalidInput
|
|
29
|
+
throw InitializableError.invalidInput()
|
|
32
30
|
}
|
|
33
31
|
}
|
|
34
32
|
|
|
@@ -48,4 +46,5 @@ public class Asset: Codable, DictionaryInitializable {
|
|
|
48
46
|
|
|
49
47
|
/// Since `Asset` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
|
|
50
48
|
/// All `Asset` subclasses are immutable `Sendable` values.
|
|
49
|
+
// swiftlint:disable:next no_unchecked_sendable
|
|
51
50
|
extension Asset: @unchecked Sendable { }
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/9/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
|
-
|
|
10
8
|
final class AssetLibrary: Codable, AnyInitializable, Sendable {
|
|
11
9
|
|
|
12
10
|
// MARK: Lifecycle
|
|
@@ -20,14 +18,17 @@ final class AssetLibrary: Codable, AnyInitializable, Sendable {
|
|
|
20
18
|
var imageAssets = [String : ImageAsset]()
|
|
21
19
|
var precompAssets = [String : PrecompAsset]()
|
|
22
20
|
|
|
23
|
-
while
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
while
|
|
22
|
+
!container.isAtEnd,
|
|
23
|
+
let keyContainer = try? containerForKeys.nestedContainer(keyedBy: PrecompAsset.CodingKeys.self)
|
|
24
|
+
{
|
|
25
|
+
if
|
|
26
|
+
keyContainer.contains(.layers),
|
|
27
|
+
let precompAsset = try? container.decode(PrecompAsset.self)
|
|
28
|
+
{
|
|
27
29
|
decodedAssets[precompAsset.id] = precompAsset
|
|
28
30
|
precompAssets[precompAsset.id] = precompAsset
|
|
29
|
-
} else {
|
|
30
|
-
let imageAsset = try container.decode(ImageAsset.self)
|
|
31
|
+
} else if let imageAsset = try? container.decode(ImageAsset.self) {
|
|
31
32
|
decodedAssets[imageAsset.id] = imageAsset
|
|
32
33
|
imageAssets[imageAsset.id] = imageAsset
|
|
33
34
|
}
|
|
@@ -39,7 +40,7 @@ final class AssetLibrary: Codable, AnyInitializable, Sendable {
|
|
|
39
40
|
|
|
40
41
|
init(value: Any) throws {
|
|
41
42
|
guard let dictionaries = value as? [[String: Any]] else {
|
|
42
|
-
throw InitializableError.invalidInput
|
|
43
|
+
throw InitializableError.invalidInput()
|
|
43
44
|
}
|
|
44
45
|
var decodedAssets = [String : Asset]()
|
|
45
46
|
var imageAssets = [String : ImageAsset]()
|
|
@@ -49,8 +50,7 @@ final class AssetLibrary: Codable, AnyInitializable, Sendable {
|
|
|
49
50
|
let asset = try PrecompAsset(dictionary: dictionary)
|
|
50
51
|
decodedAssets[asset.id] = asset
|
|
51
52
|
precompAssets[asset.id] = asset
|
|
52
|
-
} else {
|
|
53
|
-
let asset = try ImageAsset(dictionary: dictionary)
|
|
53
|
+
} else if let asset = try? ImageAsset(dictionary: dictionary) {
|
|
54
54
|
decodedAssets[asset.id] = asset
|
|
55
55
|
imageAssets[asset.id] = asset
|
|
56
56
|
}
|
|
@@ -5,8 +5,15 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/9/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
+
import CoreGraphics
|
|
8
9
|
import Foundation
|
|
9
10
|
|
|
11
|
+
#if canImport(UIKit)
|
|
12
|
+
import UIKit
|
|
13
|
+
#elseif canImport(AppKit)
|
|
14
|
+
import AppKit
|
|
15
|
+
#endif
|
|
16
|
+
|
|
10
17
|
// MARK: - ImageAsset
|
|
11
18
|
|
|
12
19
|
public final class ImageAsset: Asset {
|
|
@@ -111,3 +118,16 @@ extension Data {
|
|
|
111
118
|
}
|
|
112
119
|
|
|
113
120
|
}
|
|
121
|
+
|
|
122
|
+
extension ImageAsset {
|
|
123
|
+
/// A `CGImage` loaded from this asset if represented using a Base 64 encoding
|
|
124
|
+
var base64Image: CGImage? {
|
|
125
|
+
guard let data = Data(imageAsset: self) else { return nil }
|
|
126
|
+
|
|
127
|
+
#if canImport(UIKit)
|
|
128
|
+
return UIImage(data: data)?.cgImage
|
|
129
|
+
#elseif canImport(AppKit)
|
|
130
|
+
return NSImage(data: data)?.lottie_CGImage
|
|
131
|
+
#endif
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -5,12 +5,10 @@
|
|
|
5
5
|
// Created by Marcelo Fabri on 5/5/22.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
|
-
|
|
10
8
|
// MARK: - InitializableError
|
|
11
9
|
|
|
12
10
|
enum InitializableError: Error {
|
|
13
|
-
case invalidInput
|
|
11
|
+
case invalidInput(file: StaticString = #file, line: UInt = #line)
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
// MARK: - DictionaryInitializable
|
|
@@ -32,14 +30,24 @@ protocol AnyInitializable {
|
|
|
32
30
|
extension Dictionary {
|
|
33
31
|
|
|
34
32
|
@_disfavoredOverload
|
|
35
|
-
func value<T, KeyType: RawRepresentable>(
|
|
33
|
+
func value<T, KeyType: RawRepresentable>(
|
|
34
|
+
for key: KeyType,
|
|
35
|
+
file: StaticString = #file,
|
|
36
|
+
line: UInt = #line)
|
|
37
|
+
throws -> T where KeyType.RawValue == Key
|
|
38
|
+
{
|
|
36
39
|
guard let value = self[key.rawValue] as? T else {
|
|
37
|
-
throw InitializableError.invalidInput
|
|
40
|
+
throw InitializableError.invalidInput(file: file, line: line)
|
|
38
41
|
}
|
|
39
42
|
return value
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
func value<T: AnyInitializable, KeyType: RawRepresentable>(
|
|
45
|
+
func value<T: AnyInitializable, KeyType: RawRepresentable>(
|
|
46
|
+
for key: KeyType,
|
|
47
|
+
file: StaticString = #file,
|
|
48
|
+
line: UInt = #line)
|
|
49
|
+
throws -> T where KeyType.RawValue == Key
|
|
50
|
+
{
|
|
43
51
|
if let value = self[key.rawValue] as? T {
|
|
44
52
|
return value
|
|
45
53
|
}
|
|
@@ -48,18 +56,18 @@ extension Dictionary {
|
|
|
48
56
|
return try T(value: value)
|
|
49
57
|
}
|
|
50
58
|
|
|
51
|
-
throw InitializableError.invalidInput
|
|
59
|
+
throw InitializableError.invalidInput(file: file, line: line)
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
}
|
|
55
63
|
|
|
56
|
-
// MARK: -
|
|
64
|
+
// MARK: - AnyInitializable + AnyInitializable
|
|
57
65
|
|
|
58
|
-
extension
|
|
66
|
+
extension [Double]: AnyInitializable {
|
|
59
67
|
|
|
60
68
|
init(value: Any) throws {
|
|
61
69
|
guard let array = value as? [Double] else {
|
|
62
|
-
throw InitializableError.invalidInput
|
|
70
|
+
throw InitializableError.invalidInput()
|
|
63
71
|
}
|
|
64
72
|
self = array
|
|
65
73
|
}
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
// Created by Evandro Hoffmann on 20/10/22.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
8
|
#if canImport(UIKit)
|
|
10
9
|
import UIKit
|
|
11
10
|
#elseif canImport(AppKit)
|
|
@@ -23,12 +22,12 @@ class DotLottieImageProvider: AnimationImageProvider {
|
|
|
23
22
|
///
|
|
24
23
|
/// - Parameter filepath: The absolute filepath containing the images.
|
|
25
24
|
///
|
|
26
|
-
init(filepath: String) {
|
|
27
|
-
self.filepath
|
|
28
|
-
loadImages()
|
|
25
|
+
convenience init?(filepath: String) {
|
|
26
|
+
self.init(filepath: URL(fileURLWithPath: filepath))
|
|
29
27
|
}
|
|
30
28
|
|
|
31
|
-
init(filepath: URL) {
|
|
29
|
+
init?(filepath: URL) {
|
|
30
|
+
guard filepath.urls.count > 0 else { return nil }
|
|
32
31
|
self.filepath = filepath
|
|
33
32
|
loadImages()
|
|
34
33
|
}
|
|
@@ -38,7 +37,11 @@ class DotLottieImageProvider: AnimationImageProvider {
|
|
|
38
37
|
let filepath: URL
|
|
39
38
|
|
|
40
39
|
func imageForAsset(asset: ImageAsset) -> CGImage? {
|
|
41
|
-
|
|
40
|
+
if let base64Image = asset.base64Image {
|
|
41
|
+
return base64Image
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return images[asset.name]
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
// MARK: Private
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
// From: https://medium.com/@kewindannerfjordremeczki/swift-4-0-decodable-heterogeneous-collections-ecc0e6b468cf
|
|
2
2
|
|
|
3
|
-
import Foundation
|
|
4
|
-
|
|
5
3
|
// MARK: - ClassFamily
|
|
6
4
|
|
|
7
5
|
/// To support a new class family, create an enum that conforms to this protocol and contains the different types.
|
|
@@ -9,6 +7,9 @@ protocol ClassFamily: Decodable {
|
|
|
9
7
|
/// The discriminator key.
|
|
10
8
|
static var discriminator: Discriminator { get }
|
|
11
9
|
|
|
10
|
+
/// The "unknown" fallback case if the type discriminator could not be parsed successfully.
|
|
11
|
+
static var unknown: Self { get }
|
|
12
|
+
|
|
12
13
|
/// Returns the class type of the object corresponding to the value.
|
|
13
14
|
func getType() -> AnyObject.Type
|
|
14
15
|
}
|
|
@@ -34,7 +35,7 @@ extension KeyedDecodingContainer {
|
|
|
34
35
|
var tmpContainer = container
|
|
35
36
|
while !container.isAtEnd {
|
|
36
37
|
let typeContainer = try container.nestedContainer(keyedBy: Discriminator.self)
|
|
37
|
-
let family: U = try typeContainer.
|
|
38
|
+
let family: U = (try? typeContainer.decodeIfPresent(U.self, forKey: U.discriminator)) ?? .unknown
|
|
38
39
|
if let type = family.getType() as? T.Type {
|
|
39
40
|
list.append(try tmpContainer.decode(type))
|
|
40
41
|
}
|
|
@@ -60,7 +61,7 @@ extension KeyedDecodingContainer {
|
|
|
60
61
|
var tmpContainer = container
|
|
61
62
|
while !container.isAtEnd {
|
|
62
63
|
let typeContainer = try container.nestedContainer(keyedBy: Discriminator.self)
|
|
63
|
-
let family: U = try typeContainer.
|
|
64
|
+
let family: U = (try? typeContainer.decodeIfPresent(U.self, forKey: U.discriminator)) ?? .unknown
|
|
64
65
|
if let type = family.getType() as? T.Type {
|
|
65
66
|
list.append(try tmpContainer.decode(type))
|
|
66
67
|
}
|
|
@@ -5,9 +5,6 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/7/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import CoreGraphics
|
|
9
|
-
import Foundation
|
|
10
|
-
|
|
11
8
|
// MARK: - KeyframeData
|
|
12
9
|
|
|
13
10
|
/// A generic class used to parse and remap keyframe json.
|
|
@@ -72,7 +69,7 @@ final class KeyframeData<T> {
|
|
|
72
69
|
let spatialOutTangent: LottieVector3D?
|
|
73
70
|
|
|
74
71
|
var isHold: Bool {
|
|
75
|
-
if let hold
|
|
72
|
+
if let hold {
|
|
76
73
|
return hold > 0
|
|
77
74
|
}
|
|
78
75
|
return false
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/14/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
|
-
|
|
10
8
|
// MARK: - KeyframeGroup
|
|
11
9
|
|
|
12
10
|
/// Used for coding/decoding a group of Keyframes by type.
|
|
@@ -166,7 +164,7 @@ extension KeyframeGroup: DictionaryInitializable where T: AnyInitializable {
|
|
|
166
164
|
let value: T = data.startValue ?? previousKeyframeData?.endValue,
|
|
167
165
|
let time = data.time
|
|
168
166
|
else {
|
|
169
|
-
throw InitializableError.invalidInput
|
|
167
|
+
throw InitializableError.invalidInput()
|
|
170
168
|
}
|
|
171
169
|
keyframes.append(Keyframe<T>(
|
|
172
170
|
value: value,
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Created by Cal Stephens on 8/15/23.
|
|
2
2
|
// Copyright © 2023 Airbnb Inc. All rights reserved.
|
|
3
3
|
|
|
4
|
-
import Foundation
|
|
5
|
-
|
|
6
4
|
// MARK: - EffectValueType
|
|
7
5
|
|
|
8
6
|
/// https://lottiefiles.github.io/lottie-docs/schema/#/$defs/effect-values
|
|
@@ -50,8 +48,8 @@ class EffectValue: Codable, DictionaryInitializable {
|
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
required init(dictionary: [String: Any]) throws {
|
|
53
|
-
type =
|
|
54
|
-
name = try dictionary.value(for: CodingKeys.name) ?? "Effect"
|
|
51
|
+
type = (try? dictionary.value(for: CodingKeys.type)).flatMap(EffectValueType.init(rawValue:)) ?? .unknown
|
|
52
|
+
name = (try? dictionary.value(for: CodingKeys.name)) ?? "Effect"
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
// MARK: Internal
|
|
@@ -70,7 +68,7 @@ class EffectValue: Codable, DictionaryInitializable {
|
|
|
70
68
|
}
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
extension
|
|
71
|
+
extension [EffectValue] {
|
|
74
72
|
static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [EffectValue] {
|
|
75
73
|
try dictionaries.compactMap { dictionary in
|
|
76
74
|
let shapeType = dictionary[EffectValue.CodingKeys.type.rawValue] as? Int
|
|
@@ -95,4 +93,5 @@ extension Array where Element == EffectValue {
|
|
|
95
93
|
|
|
96
94
|
/// Since `EffectValue` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
|
|
97
95
|
/// All `EffectValue` subclasses are immutable `Sendable` values.
|
|
96
|
+
// swiftlint:disable:next no_unchecked_sendable
|
|
98
97
|
extension EffectValue: @unchecked Sendable { }
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Created by Cal Stephens on 8/14/23.
|
|
2
2
|
// Copyright © 2023 Airbnb Inc. All rights reserved.
|
|
3
3
|
|
|
4
|
-
import Foundation
|
|
5
|
-
|
|
6
4
|
// MARK: - LayerEffectType
|
|
7
5
|
|
|
8
6
|
/// https://lottiefiles.github.io/lottie-docs/schema/#/$defs/effects
|
|
@@ -81,7 +79,7 @@ class LayerEffect: Codable, DictionaryInitializable {
|
|
|
81
79
|
}
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
extension
|
|
82
|
+
extension [LayerEffect] {
|
|
85
83
|
static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [LayerEffect] {
|
|
86
84
|
try dictionaries.compactMap { dictionary in
|
|
87
85
|
let shapeType = dictionary[LayerEffect.CodingKeys.type.rawValue] as? Int
|
|
@@ -100,4 +98,5 @@ extension Array where Element == LayerEffect {
|
|
|
100
98
|
|
|
101
99
|
/// Since `LayerEffect` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
|
|
102
100
|
/// All `LayerEffect` subclasses are immutable `Sendable` values.
|
|
101
|
+
// swiftlint:disable:next no_unchecked_sendable
|
|
103
102
|
extension LayerEffect: @unchecked Sendable { }
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Created by Cal Stephens on 8/14/23.
|
|
2
2
|
// Copyright © 2023 Airbnb Inc. All rights reserved.
|
|
3
3
|
|
|
4
|
-
import Foundation
|
|
5
|
-
|
|
6
4
|
// MARK: - LayerStyleType
|
|
7
5
|
|
|
8
6
|
enum LayerStyleType: Int, Codable, Sendable {
|
|
@@ -63,7 +61,7 @@ class LayerStyle: Codable, DictionaryInitializable {
|
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
extension
|
|
64
|
+
extension [LayerStyle] {
|
|
67
65
|
static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [LayerStyle] {
|
|
68
66
|
try dictionaries.compactMap { dictionary in
|
|
69
67
|
let shapeType = dictionary[LayerStyle.CodingKeys.type.rawValue] as? Int
|
|
@@ -82,4 +80,5 @@ extension Array where Element == LayerStyle {
|
|
|
82
80
|
|
|
83
81
|
/// Since `LayerStyle` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
|
|
84
82
|
/// All `LayerStyle` subclasses are immutable `Sendable` values.
|
|
83
|
+
// swiftlint:disable:next no_unchecked_sendable
|
|
85
84
|
extension LayerStyle: @unchecked Sendable { }
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
// Created by Brandon Withrow on 1/7/19.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
import Foundation
|
|
9
|
-
|
|
10
8
|
// MARK: - LayerType + ClassFamily
|
|
11
9
|
|
|
12
10
|
/// Used for mapping a heterogeneous list to classes for parsing.
|
|
@@ -27,6 +25,8 @@ extension LayerType: ClassFamily {
|
|
|
27
25
|
return ShapeLayerModel.self
|
|
28
26
|
case .text:
|
|
29
27
|
return TextLayerModel.self
|
|
28
|
+
case .unknown:
|
|
29
|
+
return LayerModel.self
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -40,6 +40,7 @@ public enum LayerType: Int, Codable {
|
|
|
40
40
|
case null
|
|
41
41
|
case shape
|
|
42
42
|
case text
|
|
43
|
+
case unknown
|
|
43
44
|
|
|
44
45
|
public init(from decoder: Decoder) throws {
|
|
45
46
|
self = try LayerType(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .null
|
|
@@ -92,7 +93,7 @@ class LayerModel: Codable, DictionaryInitializable {
|
|
|
92
93
|
inFrame = try container.decode(Double.self, forKey: .inFrame)
|
|
93
94
|
outFrame = try container.decode(Double.self, forKey: .outFrame)
|
|
94
95
|
startTime = try container.decode(Double.self, forKey: .startTime)
|
|
95
|
-
transform = try container.
|
|
96
|
+
transform = try container.decodeIfPresent(Transform.self, forKey: .transform) ?? .default
|
|
96
97
|
parent = try container.decodeIfPresent(Int.self, forKey: .parent)
|
|
97
98
|
blendMode = try container.decodeIfPresent(BlendMode.self, forKey: .blendMode) ?? .normal
|
|
98
99
|
masks = try container.decodeIfPresent([Mask].self, forKey: .masks)
|
|
@@ -118,8 +119,15 @@ class LayerModel: Codable, DictionaryInitializable {
|
|
|
118
119
|
inFrame = try dictionary.value(for: CodingKeys.inFrame)
|
|
119
120
|
outFrame = try dictionary.value(for: CodingKeys.outFrame)
|
|
120
121
|
startTime = try dictionary.value(for: CodingKeys.startTime)
|
|
121
|
-
transform = try Transform(dictionary: try dictionary.value(for: CodingKeys.transform))
|
|
122
122
|
parent = try? dictionary.value(for: CodingKeys.parent)
|
|
123
|
+
if
|
|
124
|
+
let transformDictionary: [String: Any] = try dictionary.value(for: CodingKeys.transform),
|
|
125
|
+
let transform = try? Transform(dictionary: transformDictionary)
|
|
126
|
+
{
|
|
127
|
+
self.transform = transform
|
|
128
|
+
} else {
|
|
129
|
+
transform = .default
|
|
130
|
+
}
|
|
123
131
|
if
|
|
124
132
|
let blendModeRawValue = dictionary[CodingKeys.blendMode.rawValue] as? Int,
|
|
125
133
|
let blendMode = BlendMode(rawValue: blendModeRawValue)
|
|
@@ -223,7 +231,7 @@ class LayerModel: Codable, DictionaryInitializable {
|
|
|
223
231
|
}
|
|
224
232
|
}
|
|
225
233
|
|
|
226
|
-
extension
|
|
234
|
+
extension [LayerModel] {
|
|
227
235
|
|
|
228
236
|
static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [LayerModel] {
|
|
229
237
|
try dictionaries.compactMap { dictionary in
|
|
@@ -241,6 +249,8 @@ extension Array where Element == LayerModel {
|
|
|
241
249
|
return try ShapeLayerModel(dictionary: dictionary)
|
|
242
250
|
case .text:
|
|
243
251
|
return try TextLayerModel(dictionary: dictionary)
|
|
252
|
+
case .unknown:
|
|
253
|
+
return try LayerModel(dictionary: dictionary)
|
|
244
254
|
case .none:
|
|
245
255
|
return nil
|
|
246
256
|
}
|
|
@@ -252,4 +262,5 @@ extension Array where Element == LayerModel {
|
|
|
252
262
|
|
|
253
263
|
/// Since `LayerModel` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
|
|
254
264
|
/// All `LayerModel` subclasses are immutable `Sendable` values.
|
|
265
|
+
// swiftlint:disable:next no_unchecked_sendable
|
|
255
266
|
extension LayerModel: @unchecked Sendable { }
|