lottie-ios 4.1.2 → 4.2.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 +27 -9
- package/Lottie.xcodeproj/project.pbxproj +158 -70
- package/Lottie.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +2 -2
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/IDEFindNavigatorScopes.plist +5 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +258 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +13 -2
- package/Package.swift +2 -1
- package/README.md +3 -3
- package/Rakefile +8 -4
- package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +16 -2
- package/Sources/Private/CoreAnimation/Animations/CombinedShapeAnimation.swift +1 -1
- package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +1 -1
- package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +1 -1
- package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +6 -6
- package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +76 -7
- package/Sources/Private/CoreAnimation/Animations/OpacityAnimation.swift +1 -1
- package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +1 -1
- package/Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift +66 -102
- package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +2 -2
- package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +3 -3
- package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +66 -17
- package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +55 -32
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift +16 -12
- package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +3 -3
- package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +24 -11
- package/Sources/Private/CoreAnimation/Layers/ImageLayer.swift +2 -2
- package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +1 -1
- package/Sources/Private/CoreAnimation/Layers/RepeaterLayer.swift +13 -2
- package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +9 -1
- package/Sources/Private/CoreAnimation/ValueProviderStore.swift +22 -11
- package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +1 -1
- package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +13 -2
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerTransformNode.swift +16 -7
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +2 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/RectNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/StarNode.swift +2 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +20 -8
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/FillNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +28 -9
- package/Sources/Private/Model/Assets/ImageAsset.swift +4 -3
- package/Sources/Private/Model/DotLottie/DotLottieAnimation.swift +2 -8
- package/Sources/Private/Model/DotLottie/DotLottieManifest.swift +3 -14
- package/Sources/Private/Model/DotLottie/DotLottieUtils.swift +11 -1
- package/Sources/Private/Model/DotLottie/ZipFoundation/Archive+BackingConfiguration.swift +147 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/Archive+Helpers.swift +351 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/Archive+MemoryFile.swift +183 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/Archive+Progress.swift +66 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/Archive+Reading.swift +144 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/Archive+ReadingDeprecated.swift +49 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/Archive+Writing.swift +385 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/Archive+WritingDeprecated.swift +91 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/Archive+ZIP64.swift +170 -0
- package/Sources/Private/Model/DotLottie/{Zip/ZipArchive.swift → ZipFoundation/Archive.swift} +150 -227
- package/Sources/Private/Model/DotLottie/ZipFoundation/Data+Compression.swift +403 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/Data+CompressionDeprecated.swift +44 -0
- package/Sources/Private/Model/DotLottie/{Zip → ZipFoundation}/Data+Serialization.swift +62 -0
- package/Sources/Private/Model/DotLottie/{Zip/ZipEntry+Serialization.swift → ZipFoundation/Entry+Serialization.swift} +7 -7
- package/Sources/Private/Model/DotLottie/{Zip/ZipEntry+ZIP64.swift → ZipFoundation/Entry+ZIP64.swift} +13 -19
- package/Sources/Private/Model/DotLottie/{Zip/ZipEntry.swift → ZipFoundation/Entry.swift} +141 -10
- package/Sources/Private/Model/DotLottie/ZipFoundation/FileManager+ZIP.swift +368 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/README.md +24 -0
- package/Sources/Private/Model/DotLottie/ZipFoundation/URL+ZIP.swift +32 -0
- package/Sources/Private/Model/Extensions/Bundle.swift +5 -14
- package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +31 -8
- package/Sources/Private/Model/Objects/Transform.swift +58 -17
- package/Sources/Private/Model/ShapeItems/Repeater.swift +41 -7
- package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +61 -7
- package/Sources/Private/Model/Text/TextAnimator.swift +37 -5
- package/Sources/Private/RootAnimationLayer.swift +3 -1
- package/Sources/Private/Utility/Extensions/AnimationKeypathExtension.swift +12 -4
- package/Sources/Private/Utility/Extensions/DataExtension.swift +14 -4
- package/Sources/Private/Utility/Primitives/BezierPathRoundExtension.swift +11 -0
- package/Sources/Private/Utility/Primitives/ColorExtension.swift +10 -13
- package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +28 -6
- package/Sources/Public/Animation/LottieAnimationHelpers.swift +12 -10
- package/Sources/Public/Animation/LottieAnimationView.swift +213 -186
- package/Sources/Public/DotLottie/DotLottieFile.swift +11 -34
- package/Sources/Public/DotLottie/DotLottieFileHelpers.swift +101 -74
- package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +90 -0
- package/Sources/Public/iOS/LottieAnimationViewBase.swift +1 -1
- package/Sources/Public/macOS/LottieAnimationViewBase.macOS.swift +1 -1
- package/lottie-ios.podspec +1 -1
- package/package.json +1 -1
- package/LottieAnimation/LottieAnimation.xcodeproj/project.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/LottieAnimation/LottieAnimation.xcodeproj/project.xcworkspace/xcuserdata/valentinperignon.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/LottieAnimation/LottieAnimation.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/LottieAnimation/LottieAnimation.xcodeproj/xcuserdata/valentinperignon.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -6
- package/LottieAnimation/LottieAnimation.xcodeproj/xcuserdata/valentinperignon.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/Sources/Private/Model/DotLottie/Zip/Data+Compression.swift +0 -134
- package/Sources/Private/Model/DotLottie/Zip/FileManager+ZIP.swift +0 -130
- package/Sources/Private/Utility/Interpolatable/KeyframeGroup+Extensions.swift +0 -59
|
@@ -9,6 +9,77 @@ import Foundation
|
|
|
9
9
|
|
|
10
10
|
extension DotLottieFile {
|
|
11
11
|
|
|
12
|
+
public enum SynchronouslyBlockingCurrentThread {
|
|
13
|
+
/// Loads an DotLottie from a specific filepath synchronously. Returns a `Result<DotLottieFile, Error>`
|
|
14
|
+
/// Please use the asynchronous methods whenever possible. This operation will block the Thread it is running in.
|
|
15
|
+
///
|
|
16
|
+
/// - Parameter filepath: The absolute filepath of the lottie to load. EG "/User/Me/starAnimation.lottie"
|
|
17
|
+
/// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional.
|
|
18
|
+
public static func loadedFrom(
|
|
19
|
+
filepath: String,
|
|
20
|
+
dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache)
|
|
21
|
+
-> Result<DotLottieFile, Error>
|
|
22
|
+
{
|
|
23
|
+
/// Check cache for lottie
|
|
24
|
+
if
|
|
25
|
+
let dotLottieCache = dotLottieCache,
|
|
26
|
+
let lottie = dotLottieCache.file(forKey: filepath)
|
|
27
|
+
{
|
|
28
|
+
return .success(lottie)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
do {
|
|
32
|
+
/// Decode the lottie.
|
|
33
|
+
let url = URL(fileURLWithPath: filepath)
|
|
34
|
+
let data = try Data(contentsOf: url)
|
|
35
|
+
let lottie = try DotLottieFile(data: data, filename: url.deletingPathExtension().lastPathComponent)
|
|
36
|
+
dotLottieCache?.setFile(lottie, forKey: filepath)
|
|
37
|
+
return .success(lottie)
|
|
38
|
+
} catch {
|
|
39
|
+
/// Decoding Error.
|
|
40
|
+
return .failure(error)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// Loads a DotLottie model from a bundle by its name synchronously. Returns a `Result<DotLottieFile, Error>`
|
|
45
|
+
/// Please use the asynchronous methods whenever possible. This operation will block the Thread it is running in.
|
|
46
|
+
///
|
|
47
|
+
/// - Parameter name: The name of the lottie file without the lottie extension. EG "StarAnimation"
|
|
48
|
+
/// - Parameter bundle: The bundle in which the lottie is located. Defaults to `Bundle.main`
|
|
49
|
+
/// - Parameter subdirectory: A subdirectory in the bundle in which the lottie is located. Optional.
|
|
50
|
+
/// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional.
|
|
51
|
+
public static func named(
|
|
52
|
+
_ name: String,
|
|
53
|
+
bundle: Bundle = Bundle.main,
|
|
54
|
+
subdirectory: String? = nil,
|
|
55
|
+
dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache)
|
|
56
|
+
-> Result<DotLottieFile, Error>
|
|
57
|
+
{
|
|
58
|
+
/// Create a cache key for the lottie.
|
|
59
|
+
let cacheKey = bundle.bundlePath + (subdirectory ?? "") + "/" + name
|
|
60
|
+
|
|
61
|
+
/// Check cache for lottie
|
|
62
|
+
if
|
|
63
|
+
let dotLottieCache = dotLottieCache,
|
|
64
|
+
let lottie = dotLottieCache.file(forKey: cacheKey)
|
|
65
|
+
{
|
|
66
|
+
return .success(lottie)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
do {
|
|
70
|
+
/// Decode animation.
|
|
71
|
+
let data = try bundle.dotLottieData(name, subdirectory: subdirectory)
|
|
72
|
+
let lottie = try DotLottieFile(data: data, filename: name)
|
|
73
|
+
dotLottieCache?.setFile(lottie, forKey: cacheKey)
|
|
74
|
+
return .success(lottie)
|
|
75
|
+
} catch {
|
|
76
|
+
/// Decoding error.
|
|
77
|
+
LottieLogger.shared.warn("Error when decoding lottie \"\(name)\": \(error)")
|
|
78
|
+
return .failure(error)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
12
83
|
/// Loads a DotLottie model from a bundle by its name. Returns `nil` if a file is not found.
|
|
13
84
|
///
|
|
14
85
|
/// - Parameter name: The name of the lottie file without the lottie extension. EG "StarAnimation"
|
|
@@ -36,49 +107,25 @@ extension DotLottieFile {
|
|
|
36
107
|
/// - Parameter bundle: The bundle in which the lottie is located. Defaults to `Bundle.main`
|
|
37
108
|
/// - Parameter subdirectory: A subdirectory in the bundle in which the lottie is located. Optional.
|
|
38
109
|
/// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional.
|
|
110
|
+
/// - Parameter dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional.
|
|
39
111
|
/// - Parameter handleResult: A closure to be called when the file has loaded.
|
|
40
112
|
public static func named(
|
|
41
113
|
_ name: String,
|
|
42
114
|
bundle: Bundle = Bundle.main,
|
|
43
115
|
subdirectory: String? = nil,
|
|
44
116
|
dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache,
|
|
117
|
+
dispatchQueue: DispatchQueue = .global(),
|
|
45
118
|
handleResult: @escaping (Result<DotLottieFile, Error>) -> Void)
|
|
46
119
|
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
120
|
+
dispatchQueue.async {
|
|
121
|
+
let result = SynchronouslyBlockingCurrentThread.named(
|
|
122
|
+
name,
|
|
123
|
+
bundle: bundle,
|
|
124
|
+
subdirectory: subdirectory,
|
|
125
|
+
dotLottieCache: dotLottieCache)
|
|
50
126
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
let dotLottieCache = dotLottieCache,
|
|
54
|
-
let lottie = dotLottieCache.file(forKey: cacheKey)
|
|
55
|
-
{
|
|
56
|
-
DispatchQueue.main.async {
|
|
57
|
-
/// If found, return the lottie.
|
|
58
|
-
handleResult(.success(lottie))
|
|
59
|
-
}
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
do {
|
|
64
|
-
/// Decode animation.
|
|
65
|
-
guard let data = try bundle.dotLottieData(name, subdirectory: subdirectory) else {
|
|
66
|
-
DispatchQueue.main.async {
|
|
67
|
-
handleResult(.failure(DotLottieError.invalidData))
|
|
68
|
-
}
|
|
69
|
-
return
|
|
70
|
-
}
|
|
71
|
-
let lottie = try DotLottieFile(data: data, filename: name)
|
|
72
|
-
dotLottieCache?.setFile(lottie, forKey: cacheKey)
|
|
73
|
-
DispatchQueue.main.async {
|
|
74
|
-
handleResult(.success(lottie))
|
|
75
|
-
}
|
|
76
|
-
} catch {
|
|
77
|
-
/// Decoding error.
|
|
78
|
-
LottieLogger.shared.warn("Error when decoding lottie \"\(name)\": \(error)")
|
|
79
|
-
DispatchQueue.main.async {
|
|
80
|
-
handleResult(.failure(error))
|
|
81
|
-
}
|
|
127
|
+
DispatchQueue.main.async {
|
|
128
|
+
handleResult(result)
|
|
82
129
|
}
|
|
83
130
|
}
|
|
84
131
|
}
|
|
@@ -102,38 +149,21 @@ extension DotLottieFile {
|
|
|
102
149
|
/// Loads an DotLottie from a specific filepath.
|
|
103
150
|
/// - Parameter filepath: The absolute filepath of the lottie to load. EG "/User/Me/starAnimation.lottie"
|
|
104
151
|
/// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional.
|
|
152
|
+
/// - Parameter dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional.
|
|
105
153
|
/// - Parameter handleResult: A closure to be called when the file has loaded.
|
|
106
154
|
public static func loadedFrom(
|
|
107
155
|
filepath: String,
|
|
108
156
|
dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache,
|
|
157
|
+
dispatchQueue: DispatchQueue = .global(),
|
|
109
158
|
handleResult: @escaping (Result<DotLottieFile, Error>) -> Void)
|
|
110
159
|
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
let lottie = dotLottieCache.file(forKey: filepath)
|
|
116
|
-
{
|
|
117
|
-
DispatchQueue.main.async {
|
|
118
|
-
handleResult(.success(lottie))
|
|
119
|
-
}
|
|
120
|
-
return
|
|
121
|
-
}
|
|
160
|
+
dispatchQueue.async {
|
|
161
|
+
let result = SynchronouslyBlockingCurrentThread.loadedFrom(
|
|
162
|
+
filepath: filepath,
|
|
163
|
+
dotLottieCache: dotLottieCache)
|
|
122
164
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
let url = URL(fileURLWithPath: filepath)
|
|
126
|
-
let data = try Data(contentsOf: url)
|
|
127
|
-
let lottie = try DotLottieFile(data: data, filename: url.deletingPathExtension().lastPathComponent)
|
|
128
|
-
dotLottieCache?.setFile(lottie, forKey: filepath)
|
|
129
|
-
DispatchQueue.main.async {
|
|
130
|
-
handleResult(.success(lottie))
|
|
131
|
-
}
|
|
132
|
-
} catch {
|
|
133
|
-
/// Decoding Error.
|
|
134
|
-
DispatchQueue.main.async {
|
|
135
|
-
handleResult(.failure(error))
|
|
136
|
-
}
|
|
165
|
+
DispatchQueue.main.async {
|
|
166
|
+
handleResult(result)
|
|
137
167
|
}
|
|
138
168
|
}
|
|
139
169
|
}
|
|
@@ -160,14 +190,16 @@ extension DotLottieFile {
|
|
|
160
190
|
/// - Parameter name: The name of the lottie file in the asset catalog. EG "StarAnimation"
|
|
161
191
|
/// - Parameter bundle: The bundle in which the lottie is located. Defaults to `Bundle.main`
|
|
162
192
|
/// - Parameter dotLottieCache: A cache for holding loaded lottie files. Defaults to `LRUDotLottieCache.sharedCache` Optional.
|
|
193
|
+
/// - Parameter dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional.
|
|
163
194
|
/// - Parameter handleResult: A closure to be called when the file has loaded.
|
|
164
195
|
public static func asset(
|
|
165
196
|
named name: String,
|
|
166
197
|
bundle: Bundle = Bundle.main,
|
|
167
198
|
dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache,
|
|
199
|
+
dispatchQueue: DispatchQueue = .global(),
|
|
168
200
|
handleResult: @escaping (Result<DotLottieFile, Error>) -> Void)
|
|
169
201
|
{
|
|
170
|
-
|
|
202
|
+
dispatchQueue.async {
|
|
171
203
|
/// Create a cache key for the lottie.
|
|
172
204
|
let cacheKey = bundle.bundlePath + "/" + name
|
|
173
205
|
|
|
@@ -183,15 +215,10 @@ extension DotLottieFile {
|
|
|
183
215
|
return
|
|
184
216
|
}
|
|
185
217
|
|
|
186
|
-
/// Load data from Asset
|
|
187
|
-
guard let data = Data.jsonData(from: name, in: bundle) else {
|
|
188
|
-
DispatchQueue.main.async {
|
|
189
|
-
handleResult(.failure(DotLottieError.invalidData))
|
|
190
|
-
}
|
|
191
|
-
return
|
|
192
|
-
}
|
|
193
|
-
|
|
194
218
|
do {
|
|
219
|
+
/// Load data from Asset
|
|
220
|
+
let data = try Data(assetName: name, in: bundle)
|
|
221
|
+
|
|
195
222
|
/// Decode lottie.
|
|
196
223
|
let lottie = try DotLottieFile(data: data, filename: name)
|
|
197
224
|
dotLottieCache?.setFile(lottie, forKey: cacheKey)
|
|
@@ -240,13 +267,13 @@ extension DotLottieFile {
|
|
|
240
267
|
handleResult(.success(lottie))
|
|
241
268
|
} else {
|
|
242
269
|
let task = session.dataTask(with: url) { data, _, error in
|
|
243
|
-
guard error == nil, let data = data else {
|
|
244
|
-
DispatchQueue.main.async {
|
|
245
|
-
handleResult(.failure(DotLottieError.invalidData))
|
|
246
|
-
}
|
|
247
|
-
return
|
|
248
|
-
}
|
|
249
270
|
do {
|
|
271
|
+
if let error = error {
|
|
272
|
+
throw error
|
|
273
|
+
}
|
|
274
|
+
guard let data = data else {
|
|
275
|
+
throw DotLottieError.noDataLoaded
|
|
276
|
+
}
|
|
250
277
|
let lottie = try DotLottieFile(data: data, filename: url.deletingPathExtension().lastPathComponent)
|
|
251
278
|
DispatchQueue.main.async {
|
|
252
279
|
dotLottieCache?.setFile(lottie, forKey: url.absoluteString)
|
|
@@ -90,6 +90,32 @@ public enum CompatibleRenderingEngineOption: Int {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
/// An Objective-C compatible version of `LottieBackgroundBehavior`.
|
|
94
|
+
@objc
|
|
95
|
+
public enum CompatibleBackgroundBehavior: Int {
|
|
96
|
+
/// Stop the animation and reset it to the beginning of its current play time. The completion block is called.
|
|
97
|
+
case stop
|
|
98
|
+
|
|
99
|
+
/// Pause the animation in its current state. The completion block is called.
|
|
100
|
+
case pause
|
|
101
|
+
|
|
102
|
+
/// Pause the animation and restart it when the application moves to the foreground.
|
|
103
|
+
/// The completion block is stored and called when the animation completes.
|
|
104
|
+
/// - This is the default when using the Main Thread rendering engine.
|
|
105
|
+
case pauseAndRestore
|
|
106
|
+
|
|
107
|
+
/// Stops the animation and sets it to the end of its current play time. The completion block is called.
|
|
108
|
+
case forceFinish
|
|
109
|
+
|
|
110
|
+
/// The animation continues playing in the background.
|
|
111
|
+
/// - This is the default when using the Core Animation rendering engine.
|
|
112
|
+
/// Playing an animation using the Core Animation engine doesn't come with any CPU overhead,
|
|
113
|
+
/// so using `.continuePlaying` avoids the need to stop and then resume the animation
|
|
114
|
+
/// (which does come with some CPU overhead).
|
|
115
|
+
/// - This mode should not be used with the Main Thread rendering engine.
|
|
116
|
+
case continuePlaying
|
|
117
|
+
}
|
|
118
|
+
|
|
93
119
|
/// An Objective-C compatible wrapper around Lottie's LottieAnimationView.
|
|
94
120
|
@objc
|
|
95
121
|
public final class CompatibleAnimationView: UIView {
|
|
@@ -187,6 +213,13 @@ public final class CompatibleAnimationView: UIView {
|
|
|
187
213
|
}
|
|
188
214
|
}
|
|
189
215
|
|
|
216
|
+
@objc
|
|
217
|
+
public var compatibleDictionaryTextProvider: CompatibleDictionaryTextProvider? {
|
|
218
|
+
didSet {
|
|
219
|
+
animationView.textProvider = compatibleDictionaryTextProvider?.textProvider ?? DefaultTextProvider()
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
190
223
|
@objc
|
|
191
224
|
public override var contentMode: UIView.ContentMode {
|
|
192
225
|
set { animationView.contentMode = newValue }
|
|
@@ -249,6 +282,38 @@ public final class CompatibleAnimationView: UIView {
|
|
|
249
282
|
animationView.isAnimationPlaying
|
|
250
283
|
}
|
|
251
284
|
|
|
285
|
+
@objc
|
|
286
|
+
public var backgroundMode: CompatibleBackgroundBehavior {
|
|
287
|
+
get {
|
|
288
|
+
switch animationView.backgroundBehavior {
|
|
289
|
+
case .stop:
|
|
290
|
+
return .stop
|
|
291
|
+
case .pause:
|
|
292
|
+
return .pause
|
|
293
|
+
case .pauseAndRestore:
|
|
294
|
+
return .pauseAndRestore
|
|
295
|
+
case .forceFinish:
|
|
296
|
+
return .forceFinish
|
|
297
|
+
case .continuePlaying:
|
|
298
|
+
return .continuePlaying
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
set {
|
|
302
|
+
switch newValue {
|
|
303
|
+
case .stop:
|
|
304
|
+
animationView.backgroundBehavior = .stop
|
|
305
|
+
case .pause:
|
|
306
|
+
animationView.backgroundBehavior = .pause
|
|
307
|
+
case .pauseAndRestore:
|
|
308
|
+
animationView.backgroundBehavior = .pauseAndRestore
|
|
309
|
+
case .forceFinish:
|
|
310
|
+
animationView.backgroundBehavior = .forceFinish
|
|
311
|
+
case .continuePlaying:
|
|
312
|
+
animationView.backgroundBehavior = .continuePlaying
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
252
317
|
@objc
|
|
253
318
|
public func play() {
|
|
254
319
|
play(completion: nil)
|
|
@@ -451,4 +516,29 @@ public final class CompatibleAnimationView: UIView {
|
|
|
451
516
|
animationView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
|
|
452
517
|
}
|
|
453
518
|
}
|
|
519
|
+
|
|
520
|
+
/// An Objective-C compatible wrapper around Lottie's DictionaryTextProvider.
|
|
521
|
+
/// Use in tandem with CompatibleAnimationView to supply text to LottieAnimationView
|
|
522
|
+
/// when using Lottie in Objective-C.
|
|
523
|
+
@objc
|
|
524
|
+
public final class CompatibleDictionaryTextProvider: NSObject {
|
|
525
|
+
|
|
526
|
+
// MARK: Lifecycle
|
|
527
|
+
|
|
528
|
+
@objc
|
|
529
|
+
public init(values: [String: String]) {
|
|
530
|
+
self.values = values
|
|
531
|
+
super.init()
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// MARK: Internal
|
|
535
|
+
|
|
536
|
+
internal var textProvider: AnimationTextProvider? {
|
|
537
|
+
DictionaryTextProvider(values)
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// MARK: Private
|
|
541
|
+
|
|
542
|
+
private let values: [String: String]
|
|
543
|
+
}
|
|
454
544
|
#endif
|
|
@@ -11,7 +11,7 @@ import UIKit
|
|
|
11
11
|
/// The base view for `LottieAnimationView` on iOS, tvOS, watchOS, and macCatalyst.
|
|
12
12
|
///
|
|
13
13
|
/// Enables the `LottieAnimationView` implementation to be shared across platforms.
|
|
14
|
-
|
|
14
|
+
open class LottieAnimationViewBase: UIView {
|
|
15
15
|
|
|
16
16
|
// MARK: Public
|
|
17
17
|
|
|
@@ -27,7 +27,7 @@ public enum LottieContentMode: Int {
|
|
|
27
27
|
/// The base view for `LottieAnimationView` on macOs.
|
|
28
28
|
///
|
|
29
29
|
/// Enables the `LottieAnimationView` implementation to be shared across platforms.
|
|
30
|
-
|
|
30
|
+
open class LottieAnimationViewBase: NSView {
|
|
31
31
|
|
|
32
32
|
// MARK: Public
|
|
33
33
|
|
package/lottie-ios.podspec
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lottie-ios",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Lottie is a mobile library for Android and iOS that parses Adobe After Effects animations exported as json with bodymovin and renders the vector animations natively on mobile and through React Native!",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
Binary file
|
|
Binary file
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
-
<plist version="1.0">
|
|
4
|
-
<dict>
|
|
5
|
-
<key>SchemeUserState</key>
|
|
6
|
-
<dict>
|
|
7
|
-
<key>LottieAnimation.xcscheme_^#shared#^_</key>
|
|
8
|
-
<dict>
|
|
9
|
-
<key>orderHint</key>
|
|
10
|
-
<integer>6</integer>
|
|
11
|
-
</dict>
|
|
12
|
-
</dict>
|
|
13
|
-
</dict>
|
|
14
|
-
</plist>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
-
<plist version="1.0">
|
|
4
|
-
<dict>
|
|
5
|
-
<key>SchemeUserState</key>
|
|
6
|
-
<dict>
|
|
7
|
-
<key>LottieAnimation.xcscheme_^#shared#^_</key>
|
|
8
|
-
<dict>
|
|
9
|
-
<key>orderHint</key>
|
|
10
|
-
<integer>0</integer>
|
|
11
|
-
</dict>
|
|
12
|
-
</dict>
|
|
13
|
-
</dict>
|
|
14
|
-
</plist>
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Data+Compression.swift
|
|
3
|
-
// ZIPFoundation
|
|
4
|
-
//
|
|
5
|
-
// Copyright © 2017-2021 Thomas Zoechling, https://www.peakstep.com and the ZIP Foundation project authors.
|
|
6
|
-
// Released under the MIT License.
|
|
7
|
-
//
|
|
8
|
-
// See https://github.com/weichsel/ZIPFoundation/blob/master/LICENSE for license information.
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
import Foundation
|
|
12
|
-
|
|
13
|
-
#if canImport(zlib)
|
|
14
|
-
import zlib
|
|
15
|
-
#endif
|
|
16
|
-
|
|
17
|
-
/// A custom handler that consumes a `Data` object containing partial entry data.
|
|
18
|
-
/// - Parameters:
|
|
19
|
-
/// - data: A chunk of `Data` to consume.
|
|
20
|
-
/// - Throws: Can throw to indicate errors during data consumption.
|
|
21
|
-
typealias ZipDataCallback = (_ data: Data) throws -> Void
|
|
22
|
-
/// A custom handler that receives a position and a size that can be used to provide data from an arbitrary source.
|
|
23
|
-
/// - Parameters:
|
|
24
|
-
/// - position: The current read position.
|
|
25
|
-
/// - size: The size of the chunk to provide.
|
|
26
|
-
/// - Returns: A chunk of `Data`.
|
|
27
|
-
/// - Throws: Can throw to indicate errors in the data source.
|
|
28
|
-
typealias ZipDataProvider = (_ position: Int64, _ size: Int) throws -> Data
|
|
29
|
-
|
|
30
|
-
extension Data {
|
|
31
|
-
enum CompressionError: Error {
|
|
32
|
-
case invalidStream
|
|
33
|
-
case corruptedData
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/// Decompress the output of `provider` and pass it to `consumer`.
|
|
37
|
-
/// - Parameters:
|
|
38
|
-
/// - size: The compressed size of the data to be decompressed.
|
|
39
|
-
/// - bufferSize: The maximum size of the decompression buffer.
|
|
40
|
-
/// - provider: A closure that accepts a position and a chunk size. Returns a `Data` chunk.
|
|
41
|
-
/// - consumer: A closure that processes the result of the decompress operation.
|
|
42
|
-
/// - Returns: The checksum of the processed content.
|
|
43
|
-
static func decompress(size: Int64, bufferSize: Int, provider: ZipDataProvider, consumer: ZipDataCallback) throws -> UInt32 {
|
|
44
|
-
try process(
|
|
45
|
-
operation: COMPRESSION_STREAM_DECODE,
|
|
46
|
-
size: size,
|
|
47
|
-
bufferSize: bufferSize,
|
|
48
|
-
provider: provider,
|
|
49
|
-
consumer: consumer)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/// Calculate the `CRC32` checksum of the receiver.
|
|
53
|
-
///
|
|
54
|
-
/// - Parameter checksum: The starting seed.
|
|
55
|
-
/// - Returns: The checksum calculated from the bytes of the receiver and the starting seed.
|
|
56
|
-
func crc32(checksum: UInt32) -> UInt32 {
|
|
57
|
-
#if canImport(zlib)
|
|
58
|
-
return withUnsafeBytes { bufferPointer in
|
|
59
|
-
let length = UInt32(count)
|
|
60
|
-
return UInt32(zlib.crc32(UInt(checksum), bufferPointer.bindMemory(to: UInt8.self).baseAddress, length))
|
|
61
|
-
}
|
|
62
|
-
#else
|
|
63
|
-
return builtInCRC32(checksum: checksum)
|
|
64
|
-
#endif
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
import Compression
|
|
70
|
-
|
|
71
|
-
extension Data {
|
|
72
|
-
static func process(
|
|
73
|
-
operation: compression_stream_operation,
|
|
74
|
-
size: Int64,
|
|
75
|
-
bufferSize: Int,
|
|
76
|
-
provider: ZipDataProvider,
|
|
77
|
-
consumer: ZipDataCallback)
|
|
78
|
-
throws -> UInt32
|
|
79
|
-
{
|
|
80
|
-
var crc32 = UInt32(0)
|
|
81
|
-
let destPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
|
|
82
|
-
defer { destPointer.deallocate() }
|
|
83
|
-
let streamPointer = UnsafeMutablePointer<compression_stream>.allocate(capacity: 1)
|
|
84
|
-
defer { streamPointer.deallocate() }
|
|
85
|
-
var stream = streamPointer.pointee
|
|
86
|
-
var status = compression_stream_init(&stream, operation, COMPRESSION_ZLIB)
|
|
87
|
-
guard status != COMPRESSION_STATUS_ERROR else { throw CompressionError.invalidStream }
|
|
88
|
-
defer { compression_stream_destroy(&stream) }
|
|
89
|
-
stream.src_size = 0
|
|
90
|
-
stream.dst_ptr = destPointer
|
|
91
|
-
stream.dst_size = bufferSize
|
|
92
|
-
var position: Int64 = 0
|
|
93
|
-
var sourceData: Data?
|
|
94
|
-
repeat {
|
|
95
|
-
let isExhausted = stream.src_size == 0
|
|
96
|
-
if isExhausted {
|
|
97
|
-
do {
|
|
98
|
-
sourceData = try provider(position, Int(Swift.min(size - position, Int64(bufferSize))))
|
|
99
|
-
position += Int64(stream.prepare(for: sourceData))
|
|
100
|
-
} catch { throw error }
|
|
101
|
-
}
|
|
102
|
-
if let sourceData = sourceData {
|
|
103
|
-
sourceData.withUnsafeBytes { rawBufferPointer in
|
|
104
|
-
if let baseAddress = rawBufferPointer.baseAddress {
|
|
105
|
-
let pointer = baseAddress.assumingMemoryBound(to: UInt8.self)
|
|
106
|
-
stream.src_ptr = pointer.advanced(by: sourceData.count - stream.src_size)
|
|
107
|
-
let flags = sourceData.count < bufferSize ? Int32(COMPRESSION_STREAM_FINALIZE.rawValue) : 0
|
|
108
|
-
status = compression_stream_process(&stream, flags)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if operation == COMPRESSION_STREAM_ENCODE, isExhausted { crc32 = sourceData.crc32(checksum: crc32) }
|
|
112
|
-
}
|
|
113
|
-
switch status {
|
|
114
|
-
case COMPRESSION_STATUS_OK, COMPRESSION_STATUS_END:
|
|
115
|
-
let outputData = Data(bytesNoCopy: destPointer, count: bufferSize - stream.dst_size, deallocator: .none)
|
|
116
|
-
try consumer(outputData)
|
|
117
|
-
if operation == COMPRESSION_STREAM_DECODE { crc32 = outputData.crc32(checksum: crc32) }
|
|
118
|
-
stream.dst_ptr = destPointer
|
|
119
|
-
stream.dst_size = bufferSize
|
|
120
|
-
default: throw CompressionError.corruptedData
|
|
121
|
-
}
|
|
122
|
-
} while status == COMPRESSION_STATUS_OK
|
|
123
|
-
return crc32
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
extension compression_stream {
|
|
128
|
-
fileprivate mutating func prepare(for sourceData: Data?) -> Int {
|
|
129
|
-
guard let sourceData = sourceData else { return 0 }
|
|
130
|
-
|
|
131
|
-
src_size = sourceData.count
|
|
132
|
-
return sourceData.count
|
|
133
|
-
}
|
|
134
|
-
}
|