lottie-ios 4.2.0 → 4.3.1
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 +117 -11
- package/Gemfile +1 -0
- package/Gemfile.lock +5 -0
- package/Lottie.xcodeproj/project.pbxproj +1546 -194
- package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (iOS).xcscheme +1 -1
- package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (macOS).xcscheme +1 -1
- package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (tvOS).xcscheme +4 -5
- package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (visionOS).xcscheme +66 -0
- package/Lottie.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +18 -0
- package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +2 -11
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +374 -116
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +16 -5
- package/Package.resolved +2 -2
- package/Package.swift +16 -9
- package/README.md +2 -2
- package/Rakefile +122 -25
- package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +3 -4
- package/Sources/Private/CoreAnimation/Animations/DropShadowAnimation.swift +160 -0
- package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +83 -10
- package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +85 -79
- package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +11 -7
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift +67 -6
- package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +21 -2
- package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +9 -0
- package/Sources/Private/CoreAnimation/Layers/ImageLayer.swift +1 -0
- package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +1 -1
- package/Sources/Private/CoreAnimation/Layers/RepeaterLayer.swift +2 -0
- package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +11 -13
- package/Sources/Private/CoreAnimation/Layers/SolidLayer.swift +20 -5
- package/Sources/Private/CoreAnimation/Layers/TextLayer.swift +13 -3
- package/Sources/Private/CoreAnimation/ValueProviderStore.swift +6 -4
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Collection+Diff.swift +263 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Diffable.swift +18 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/DiffableSection.swift +16 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/IndexChangeset.swift +187 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/SectionedChangeset.swift +32 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Logging/EpoxyLogger.swift +99 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/CallbackContextEpoxyModeled.swift +8 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelArrayBuilder.swift +48 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelProperty.swift +158 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelStorage.swift +88 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModeled.swift +54 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/AnyEpoxyModelProperty.swift +29 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/ClassReference.swift +39 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/AnimatedProviding.swift +10 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DataIDProviding.swift +57 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidDisplayProviding.swift +41 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidEndDisplayingProviding.swift +41 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidSelectProviding.swift +36 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ErasedContentProviding.swift +49 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/MakeViewProviding.swift +60 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetBehaviorsProviding.swift +38 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetContentProviding.swift +38 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/StyleIDProviding.swift +37 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/TraitCollectionProviding.swift +14 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewDifferentiatorProviding.swift +34 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewProviding.swift +13 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/WillDisplayProviding.swift +41 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/ViewEpoxyModeled.swift +10 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/README.md +31 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingController.swift +46 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift +391 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIIntrinsicContentSizeInvalidator.swift +44 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUILayoutMargins.swift +51 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxyableView+SwiftUIView.swift +172 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/MeasuringViewRepresentable.swift +128 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift +452 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift +148 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIView+SwiftUIView.swift +40 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIViewConfiguringSwiftUIView.swift +43 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/BehaviorsConfigurableView.swift +45 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ContentConfigurableView.swift +36 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/EpoxyableView.swift +5 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/StyledView.swift +42 -0
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ViewType.swift +51 -0
- package/Sources/Private/EmbeddedLibraries/README.md +27 -0
- package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+BackingConfiguration.swift +4 -4
- package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+MemoryFile.swift +2 -2
- package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+Writing.swift +4 -4
- package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive.swift +8 -7
- package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Data+Compression.swift +5 -5
- package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/FileManager+ZIP.swift +4 -4
- package/Sources/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.swift +6 -0
- package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +3 -1
- package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +18 -5
- package/Sources/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.swift +31 -3
- package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +33 -8
- package/Sources/Private/MainThread/LayerContainers/Utility/CachedImageProvider.swift +8 -1
- package/Sources/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.swift +13 -4
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerFontProvider.swift +2 -2
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerImageProvider.swift +1 -0
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerTextProvider.swift +4 -4
- package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +3 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +2 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift +2 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +2 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +6 -2
- package/Sources/Private/Model/Assets/Asset.swift +8 -0
- package/Sources/Private/Model/Assets/AssetLibrary.swift +2 -2
- package/Sources/Private/Model/Assets/ImageAsset.swift +3 -3
- package/Sources/Private/Model/DotLottie/DotLottieAnimation.swift +16 -2
- package/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift +20 -7
- package/Sources/Private/Model/Extensions/KeyedDecodingContainerExtensions.swift +26 -0
- package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +8 -5
- package/Sources/Private/Model/LayerEffects/DropShadowEffect.swift +45 -0
- package/Sources/Private/Model/LayerEffects/EffectValues/ColorEffectValue.swift +38 -0
- package/Sources/Private/Model/LayerEffects/EffectValues/EffectValue.swift +98 -0
- package/Sources/Private/Model/LayerEffects/EffectValues/Vector1DEffectValue.swift +38 -0
- package/Sources/Private/Model/LayerEffects/LayerEffect.swift +103 -0
- package/Sources/Private/Model/LayerStyles/DropShadowStyle.swift +72 -0
- package/Sources/Private/Model/LayerStyles/LayerStyle.swift +85 -0
- package/Sources/Private/Model/Layers/LayerModel.swift +27 -0
- package/Sources/Private/Model/Objects/Marker.swift +1 -1
- package/Sources/Private/Model/Objects/Transform.swift +1 -2
- package/Sources/Private/Model/ShapeItems/GradientFill.swift +1 -1
- package/Sources/Private/Model/ShapeItems/GradientStroke.swift +2 -2
- package/Sources/Private/Model/ShapeItems/Merge.swift +1 -1
- package/Sources/Private/Model/ShapeItems/ShapeItem.swift +31 -26
- package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +0 -9
- package/Sources/Private/Model/ShapeItems/Star.swift +1 -1
- package/Sources/Private/Model/Text/Font.swift +2 -2
- package/Sources/Private/Model/Text/Glyph.swift +1 -1
- package/Sources/Private/RootAnimationLayer.swift +2 -2
- package/Sources/Private/Utility/Debugging/LayerDebugging.swift +3 -1
- package/Sources/Private/Utility/Extensions/AnimationKeypathExtension.swift +32 -2
- package/Sources/Private/Utility/Helpers/AnimationContext.swift +4 -2
- package/Sources/Private/Utility/Helpers/AnyEquatable.swift +24 -0
- package/Sources/Private/Utility/Helpers/Binding+Map.swift +18 -0
- package/Sources/Private/Utility/Helpers/View+ValueChanged.swift +20 -0
- package/Sources/Private/Utility/LottieAnimationSource.swift +41 -0
- package/Sources/Private/Utility/Primitives/BezierPath.swift +2 -2
- package/Sources/Private/Utility/Primitives/BezierPathRoundExtension.swift +2 -2
- package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +1 -1
- package/Sources/Public/Animation/LottieAnimation.swift +21 -2
- package/Sources/Public/Animation/LottieAnimationLayer.swift +1464 -0
- package/Sources/Public/Animation/LottieAnimationView.swift +259 -736
- package/Sources/Public/Animation/LottiePlaybackMode.swift +117 -0
- package/Sources/Public/Animation/LottieView.swift +462 -0
- package/Sources/Public/AnimationCache/AnimationCacheProvider.swift +2 -1
- package/Sources/Public/AnimationCache/DefaultAnimationCache.swift +5 -6
- package/Sources/Public/Configuration/DecodingStrategy.swift +15 -0
- package/Sources/Public/Configuration/LottieConfiguration.swift +47 -0
- package/Sources/Public/Configuration/ReducedMotionOption.swift +114 -0
- package/Sources/Public/{LottieConfiguration.swift → Configuration/RenderingEngineOption.swift} +2 -57
- package/Sources/Public/{iOS → Controls}/AnimatedButton.swift +56 -13
- package/Sources/Public/{iOS → Controls}/AnimatedControl.swift +80 -8
- package/Sources/Public/{iOS → Controls}/AnimatedSwitch.swift +71 -31
- package/Sources/Public/Controls/LottieButton.swift +122 -0
- package/Sources/Public/Controls/LottieSwitch.swift +144 -0
- package/Sources/Public/Controls/LottieViewType.swift +79 -0
- package/Sources/Public/DotLottie/DotLottieConfiguration.swift +24 -0
- package/Sources/Public/DotLottie/DotLottieFile.swift +21 -6
- package/Sources/Public/DotLottie/DotLottieFileHelpers.swift +79 -0
- package/Sources/Public/DynamicProperties/AnimationKeypath.swift +11 -1
- package/Sources/Public/DynamicProperties/ValueProviders/ColorValueProvider.swift +14 -0
- package/Sources/Public/DynamicProperties/ValueProviders/FloatValueProvider.swift +13 -0
- package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +22 -5
- package/Sources/Public/DynamicProperties/ValueProviders/PointValueProvider.swift +14 -0
- package/Sources/Public/DynamicProperties/ValueProviders/SizeValueProvider.swift +13 -0
- package/Sources/Public/FontProvider/AnimationFontProvider.swift +8 -0
- package/Sources/Public/ImageProvider/AnimationImageProvider.swift +24 -0
- package/Sources/Public/Keyframes/Keyframe.swift +6 -0
- package/Sources/Public/Primitives/Vectors.swift +2 -2
- package/Sources/Public/TextProvider/AnimationTextProvider.swift +79 -6
- package/Sources/Public/iOS/AnimationSubview.swift +1 -1
- package/Sources/Public/iOS/BundleImageProvider.swift +16 -2
- package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +6 -4
- package/Sources/Public/iOS/FilepathImageProvider.swift +22 -3
- package/Sources/Public/iOS/LottieAnimationViewBase.swift +7 -1
- package/Sources/Public/macOS/BundleImageProvider.macOS.swift +15 -1
- package/Sources/Public/macOS/FilepathImageProvider.macOS.swift +21 -2
- package/lottie-ios.podspec +2 -1
- package/package.json +1 -1
- package/Sources/Private/Model/DotLottie/DotLottieConfiguration.swift +0 -15
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+Helpers.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+Progress.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+Reading.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+ReadingDeprecated.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+WritingDeprecated.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+ZIP64.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Data+CompressionDeprecated.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Data+Serialization.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Entry+Serialization.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Entry+ZIP64.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Entry.swift +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/README.md +0 -0
- /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/URL+ZIP.swift +0 -0
package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist
CHANGED
|
@@ -102,9 +102,6 @@
|
|
|
102
102
|
<ContextState
|
|
103
103
|
contextName = "closure #4 in CALayer.makeGroupLayers(from:parentGroup:parentGroupPath:context:):ShapeLayer.swift">
|
|
104
104
|
</ContextState>
|
|
105
|
-
<ContextState
|
|
106
|
-
contextName = "GroupLayer.init(group:items:groupPath:context:):ShapeLayer.swift">
|
|
107
|
-
</ContextState>
|
|
108
105
|
<ContextState
|
|
109
106
|
contextName = "RoundedCornersNode.rebuildOutputs(frame:):RoundedCornersNode.swift">
|
|
110
107
|
<PersistentStrings>
|
|
@@ -116,6 +113,20 @@
|
|
|
116
113
|
</PersistentString>
|
|
117
114
|
</PersistentStrings>
|
|
118
115
|
</ContextState>
|
|
116
|
+
<ContextState
|
|
117
|
+
contextName = "GroupLayer.init(group:items:groupPath:context:):ShapeLayer.swift">
|
|
118
|
+
</ContextState>
|
|
119
|
+
<ContextState
|
|
120
|
+
contextName = "ParsingTests.testParsingIsTheSameForBothImplementations():ParsingTests.swift">
|
|
121
|
+
<PersistentStrings>
|
|
122
|
+
<PersistentString
|
|
123
|
+
value = "codableAnimation.layers.flatMap { $0.effects }.filter { $0.effects.isEmpty }">
|
|
124
|
+
</PersistentString>
|
|
125
|
+
<PersistentString
|
|
126
|
+
value = "dictAnimation.layers.flatMap { $0.effects }.filter { $0.name == "Rotation Offset" }">
|
|
127
|
+
</PersistentString>
|
|
128
|
+
</PersistentStrings>
|
|
129
|
+
</ContextState>
|
|
119
130
|
<ContextState
|
|
120
131
|
contextName = "CALayer.addTransformAnimations(for:context:):TransformAnimations.swift">
|
|
121
132
|
</ContextState>
|
|
@@ -129,10 +140,10 @@
|
|
|
129
140
|
contextName = "CoreAnimationLayer.display():CoreAnimationLayer.swift">
|
|
130
141
|
<PersistentStrings>
|
|
131
142
|
<PersistentString
|
|
132
|
-
value = "(superlayer!.delegate! as! UIView).
|
|
143
|
+
value = "(superlayer!.delegate! as! UIView).superview!">
|
|
133
144
|
</PersistentString>
|
|
134
145
|
<PersistentString
|
|
135
|
-
value = "(superlayer!.delegate! as! UIView).
|
|
146
|
+
value = "(superlayer!.delegate! as! UIView).window">
|
|
136
147
|
</PersistentString>
|
|
137
148
|
</PersistentStrings>
|
|
138
149
|
</ContextState>
|
package/Package.resolved
CHANGED
package/Package.swift
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
// swift-tools-version:5.
|
|
1
|
+
// swift-tools-version:5.6
|
|
2
2
|
import PackageDescription
|
|
3
3
|
|
|
4
4
|
let package = Package(
|
|
5
5
|
name: "Lottie",
|
|
6
|
-
// Minimum platform versions should be kept in sync with the per-platform targets in Lottie.xcodeproj and lottie-
|
|
7
|
-
platforms: [.iOS("11.0"), .macOS("10.11"), .tvOS("11.0")],
|
|
6
|
+
// Minimum platform versions should be kept in sync with the per-platform targets in Lottie.xcodeproj, lottie-ios.podspec, and lottie-spm's Package.swift
|
|
7
|
+
platforms: [.iOS("11.0"), .macOS("10.11"), .tvOS("11.0"), .custom("visionOS", versionString: "1.0")],
|
|
8
8
|
products: [.library(name: "Lottie", targets: ["Lottie"])],
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
dependencies: [
|
|
10
|
+
.package(url: "https://github.com/airbnb/swift", .upToNextMajor(from: "1.0.1")),
|
|
11
|
+
],
|
|
12
|
+
targets: [
|
|
13
|
+
.target(
|
|
14
|
+
name: "Lottie",
|
|
15
|
+
path: "Sources",
|
|
16
|
+
exclude: [
|
|
17
|
+
"Private/EmbeddedLibraries/README.md",
|
|
18
|
+
"Private/EmbeddedLibraries/ZipFoundation/README.md",
|
|
19
|
+
"Private/EmbeddedLibraries/EpoxyCore/README.md",
|
|
20
|
+
]),
|
|
21
|
+
])
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
**View documentation, FAQ, help, examples, and more at [airbnb.io/lottie](https://airbnb.io/lottie/)**
|
|
5
5
|
|
|
6
|
-
Lottie is a cross-platform library for iOS, macOS, tvOS, [Android](https://github.com/airbnb/lottie-android), and [Web](https://github.com/airbnb/lottie-web) that natively renders vector-based animations and art in realtime with minimal code.
|
|
6
|
+
Lottie is a cross-platform library for iOS, macOS, tvOS, visionOS, [Android](https://github.com/airbnb/lottie-android), and [Web](https://github.com/airbnb/lottie-web) that natively renders vector-based animations and art in realtime with minimal code.
|
|
7
7
|
|
|
8
8
|
Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with [bodymovin](https://github.com/bodymovin/bodymovin), Sketch with [Lottie Sketch Export](https://github.com/buba447/Lottie-Sketch-Export), and from [Haiku](https://www.haiku.ai).
|
|
9
9
|
|
|
@@ -41,7 +41,7 @@ To install Lottie using [Swift Package Manager](https://github.com/apple/swift-p
|
|
|
41
41
|
or you can add the following dependency to your `Package.swift`:
|
|
42
42
|
|
|
43
43
|
```swift
|
|
44
|
-
.package(url: "https://github.com/airbnb/lottie-spm.git", from: "4.
|
|
44
|
+
.package(url: "https://github.com/airbnb/lottie-spm.git", from: "4.3.1")
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
When using Swift Package Manager we recommend using the [lottie-spm](https://github.com/airbnb/lottie-spm) repo instead of the main lottie-ios repo. The main git repository for [lottie-ios](https://github.com/airbnb/lottie-ios) is somewhat large (300+ MB), and Swift Package Manager always downloads the full repository with all git history. The [lottie-spm](https://github.com/airbnb/lottie-spm) repo is much smaller (less than 500kb), so can be downloaded much more quickly.
|
package/Rakefile
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'git'
|
|
3
|
+
|
|
1
4
|
namespace :build do
|
|
2
5
|
desc 'Builds all packages and executables'
|
|
3
6
|
task all: ['package:all', 'example:all', 'xcframework']
|
|
@@ -5,7 +8,7 @@ namespace :build do
|
|
|
5
8
|
desc 'Builds the Lottie package for supported platforms'
|
|
6
9
|
namespace :package do
|
|
7
10
|
desc 'Builds the Lottie package for all supported platforms'
|
|
8
|
-
task all: ['iOS', 'macOS', 'tvOS']
|
|
11
|
+
task all: ['iOS', 'macOS', 'tvOS', 'visionOS']
|
|
9
12
|
|
|
10
13
|
desc 'Builds the Lottie package for iOS'
|
|
11
14
|
task :iOS do
|
|
@@ -21,56 +24,90 @@ namespace :build do
|
|
|
21
24
|
task :tvOS do
|
|
22
25
|
xcodebuild('build -scheme "Lottie (tvOS)" -destination generic/platform=tvOS -workspace Lottie.xcworkspace')
|
|
23
26
|
end
|
|
27
|
+
|
|
28
|
+
desc 'Builds the Lottie package for visionOS'
|
|
29
|
+
task :visionOS do
|
|
30
|
+
ifVisionOSEnabled {
|
|
31
|
+
xcodebuild('build -scheme "Lottie (visionOS)" -destination generic/platform=visionOS -workspace Lottie.xcworkspace')
|
|
32
|
+
}
|
|
33
|
+
end
|
|
24
34
|
end
|
|
25
35
|
|
|
26
36
|
desc 'Builds the Lottie example app for supported platforms'
|
|
27
37
|
namespace :example do
|
|
28
38
|
desc 'Builds the Lottie example apps for all supported platforms'
|
|
29
|
-
task all: ['iOS', 'macOS', 'tvOS']
|
|
39
|
+
task all: ['iOS', 'macOS', 'tvOS', 'visionOS']
|
|
30
40
|
|
|
31
41
|
desc 'Builds the iOS Lottie Example app'
|
|
32
42
|
task :iOS do
|
|
33
|
-
xcodebuild('build -scheme "Example (
|
|
43
|
+
xcodebuild('build -scheme "Example (Multiplatform)" -destination "platform=iOS Simulator,name=iPhone SE (3rd generation)" -workspace Lottie.xcworkspace')
|
|
34
44
|
end
|
|
35
45
|
|
|
36
46
|
desc 'Builds the macOS Lottie Example app'
|
|
37
47
|
task :macOS do
|
|
38
|
-
xcodebuild('build -scheme "Example (
|
|
48
|
+
xcodebuild('build -scheme "Example (Multiplatform)" -workspace Lottie.xcworkspace')
|
|
39
49
|
end
|
|
40
50
|
|
|
41
51
|
desc 'Builds the tvOS Lottie Example app'
|
|
42
52
|
task :tvOS do
|
|
43
|
-
xcodebuild('build -scheme "Example (
|
|
53
|
+
xcodebuild('build -scheme "Example (Multiplatform)" -destination "platform=tvOS Simulator,name=Apple TV" -workspace Lottie.xcworkspace')
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
desc 'Builds the visionOS Lottie Example app'
|
|
57
|
+
task :visionOS do
|
|
58
|
+
ifVisionOSEnabled {
|
|
59
|
+
xcodebuild('build -scheme "Example (Multiplatform)" -destination "platform=visionOS Simulator,name=Apple Vision Pro" -workspace Lottie.xcworkspace')
|
|
60
|
+
}
|
|
44
61
|
end
|
|
45
62
|
end
|
|
46
63
|
|
|
47
64
|
desc 'Builds an xcframework for all supported platforms'
|
|
48
|
-
task :xcframework do
|
|
65
|
+
task :xcframework, [:zip_archive_name] do |_t, args|
|
|
66
|
+
args.with_defaults(:zip_archive_name => 'Lottie')
|
|
67
|
+
|
|
49
68
|
sh 'rm -rf .build/archives'
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (iOS)" -destination
|
|
53
|
-
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (
|
|
54
|
-
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (
|
|
55
|
-
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (
|
|
56
|
-
xcodebuild(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
|
|
70
|
+
# Build the framework for each supported platform, including simulators
|
|
71
|
+
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (iOS)" -destination generic/platform=iOS -archivePath ".build/archives/Lottie_iOS" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_BITCODE=NO')
|
|
72
|
+
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (iOS)" -destination "generic/platform=iOS Simulator" -archivePath ".build/archives/Lottie_iOS_Simulator" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_BITCODE=NO')
|
|
73
|
+
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (iOS)" -destination "generic/platform=macOS,variant=Mac Catalyst" -archivePath ".build/archives/Lottie_Mac_Catalyst" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_BITCODE=NO')
|
|
74
|
+
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (macOS)" -destination generic/platform=macOS -archivePath ".build/archives/Lottie_macOS" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_BITCODE=NO')
|
|
75
|
+
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (tvOS)" -destination generic/platform=tvOS -archivePath ".build/archives/Lottie_tvOS" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_BITCODE=NO')
|
|
76
|
+
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (tvOS)" -destination "generic/platform=tvOS Simulator" -archivePath ".build/archives/Lottie_tvOS_Simulator" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_BITCODE=NO')
|
|
77
|
+
|
|
78
|
+
ifVisionOSEnabled {
|
|
79
|
+
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (visionOS)" -destination generic/platform=visionOS -archivePath ".build/archives/Lottie_visionOS" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_BITCODE=NO')
|
|
80
|
+
xcodebuild('archive -workspace Lottie.xcworkspace -scheme "Lottie (visionOS)" -destination "generic/platform=visionOS Simulator" -archivePath ".build/archives/Lottie_visionOS_Simulator" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_BITCODE=NO')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# Combine all of the platforms into a single XCFramework
|
|
84
|
+
xcframeworkInvocation = [
|
|
85
|
+
'-create-xcframework',
|
|
86
|
+
'-framework .build/archives/Lottie_iOS.xcarchive/Products/Library/Frameworks/Lottie.framework',
|
|
87
|
+
'-framework .build/archives/Lottie_iOS_Simulator.xcarchive/Products/Library/Frameworks/Lottie.framework',
|
|
88
|
+
'-framework .build/archives/Lottie_Mac_Catalyst.xcarchive/Products/Library/Frameworks/Lottie.framework',
|
|
89
|
+
'-framework .build/archives/Lottie_tvOS.xcarchive/Products/Library/Frameworks/Lottie.framework',
|
|
90
|
+
'-framework .build/archives/Lottie_tvOS_Simulator.xcarchive/Products/Library/Frameworks/Lottie.framework',
|
|
91
|
+
'-framework .build/archives/Lottie_macOS.xcarchive/Products/Library/Frameworks/Lottie.framework',
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
ifVisionOSEnabled {
|
|
95
|
+
xcframeworkInvocation.push('-framework .build/archives/Lottie_visionOS.xcarchive/Products/Library/Frameworks/Lottie.framework')
|
|
96
|
+
xcframeworkInvocation.push('-framework .build/archives/Lottie_visionOS_Simulator.xcarchive/Products/Library/Frameworks/Lottie.framework')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
xcframeworkInvocation.push('-output .build/archives/Lottie.xcframework')
|
|
100
|
+
|
|
101
|
+
xcodebuild(xcframeworkInvocation.join(" "))
|
|
102
|
+
|
|
103
|
+
# Archive the XCFramework into a zip file
|
|
67
104
|
Dir.chdir('.build/archives') do
|
|
68
105
|
# Use --symlinks to avoid "Multiple binaries share the same codesign path. This can happen if your build process copies frameworks by following symlinks."
|
|
69
106
|
# error when validating macOS apps (#1948)
|
|
70
|
-
sh
|
|
107
|
+
sh "zip -r --symlinks #{args[:zip_archive_name]}.xcframework.zip Lottie.xcframework"
|
|
71
108
|
sh 'rm -rf Lottie.xcframework'
|
|
72
109
|
end
|
|
73
|
-
sh
|
|
110
|
+
sh "swift package compute-checksum .build/archives/#{args[:zip_archive_name]}.xcframework.zip"
|
|
74
111
|
end
|
|
75
112
|
end
|
|
76
113
|
|
|
@@ -115,6 +152,10 @@ namespace :test do
|
|
|
115
152
|
xcodebuild('build -scheme "Lottie" -destination generic/platform=iOS')
|
|
116
153
|
xcodebuild('build -scheme "Lottie" -destination generic/platform=macOS')
|
|
117
154
|
xcodebuild('build -scheme "Lottie" -destination generic/platform=tvOS')
|
|
155
|
+
|
|
156
|
+
ifVisionOSEnabled {
|
|
157
|
+
xcodebuild('build -scheme "Lottie" -destination generic/platform=visionOS')
|
|
158
|
+
}
|
|
118
159
|
end
|
|
119
160
|
end
|
|
120
161
|
end
|
|
@@ -129,6 +170,12 @@ namespace :lint do
|
|
|
129
170
|
task :podspec do
|
|
130
171
|
sh 'pod lib lint lottie-ios.podspec'
|
|
131
172
|
end
|
|
173
|
+
|
|
174
|
+
desc 'Lints the EmbeddedLibraries directory'
|
|
175
|
+
task :EmbeddedLibraries do
|
|
176
|
+
sh 'echo "Linting /Sources/Private/EmbeddedLibraries (should not contain any public symbols)"'
|
|
177
|
+
sh '! grep -r "public" Sources/Private/EmbeddedLibraries --include \*.swift'
|
|
178
|
+
end
|
|
132
179
|
end
|
|
133
180
|
|
|
134
181
|
namespace :format do
|
|
@@ -138,6 +185,41 @@ namespace :format do
|
|
|
138
185
|
end
|
|
139
186
|
end
|
|
140
187
|
|
|
188
|
+
namespace :emerge do
|
|
189
|
+
desc 'Uploads to emerge'
|
|
190
|
+
task :upload do
|
|
191
|
+
xcodebuild('build -scheme "SizeTest" -destination generic/platform=iOS -project script/SizeTest/SizeTest.xcodeproj -archivePath test.xcarchive archive CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO')
|
|
192
|
+
sh "zip -r -qq test.zip test.xcarchive"
|
|
193
|
+
|
|
194
|
+
g = Git.open('.')
|
|
195
|
+
|
|
196
|
+
upload_data = {
|
|
197
|
+
repoName: 'airbnb/lottie-ios',
|
|
198
|
+
filename: 'test.zip'
|
|
199
|
+
}
|
|
200
|
+
if ENV["PR_NUMBER"] != "" && ENV["PR_NUMBER"] != "false"
|
|
201
|
+
upload_data[:sha] = g.log[0].parents[1].sha
|
|
202
|
+
upload_data[:baseSha] = g.log[0].parent.sha
|
|
203
|
+
upload_data[:prNumber] = ENV["PR_NUMBER"]
|
|
204
|
+
upload_data[:buildType] = 'pull_request'
|
|
205
|
+
else
|
|
206
|
+
upload_data[:sha] = g.log[0].sha
|
|
207
|
+
upload_data[:buildType] = 'master'
|
|
208
|
+
end
|
|
209
|
+
api_token = ENV['EMERGE_API_TOKEN']
|
|
210
|
+
if api_token.nil? || api_token.empty?
|
|
211
|
+
puts "Skipping Emerge upload because API token was not provided."
|
|
212
|
+
next
|
|
213
|
+
end
|
|
214
|
+
api_token_header = "X-API-Token: #{api_token}"
|
|
215
|
+
url = "https://api.emergetools.com/upload"
|
|
216
|
+
cmd = "curl --fail -s --request POST --url #{url} --header 'Accept: application/json' --header 'Content-Type: application/json' --header '#{api_token_header}' --data '#{upload_data.to_json}'"
|
|
217
|
+
upload_json = %x(#{cmd})
|
|
218
|
+
upload_url = JSON.parse(upload_json)['uploadURL']
|
|
219
|
+
%x(curl --fail -s -H 'Content-Type: application/zip' -T test.zip '#{upload_url}')
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
141
223
|
def xcodebuild(command)
|
|
142
224
|
# Check if the mint tool is installed -- if so, pipe the xcodebuild output through xcbeautify
|
|
143
225
|
`which mint`
|
|
@@ -148,3 +230,18 @@ def xcodebuild(command)
|
|
|
148
230
|
sh "xcodebuild #{command}"
|
|
149
231
|
end
|
|
150
232
|
end
|
|
233
|
+
|
|
234
|
+
# Runs the given code block, unless `SKIP_VISION_OS=true`.
|
|
235
|
+
# This can be removed once CI only uses Xcode 15+.
|
|
236
|
+
def ifVisionOSEnabled
|
|
237
|
+
if ENV["SKIP_VISION_OS"] == "true"
|
|
238
|
+
puts "Skipping visionOS build"
|
|
239
|
+
else
|
|
240
|
+
# As of 9/5/23 the GitHub Actions runner doesn't include the visionOS SDK by default,
|
|
241
|
+
# so we have to download it manually. Following the suggested workaround from
|
|
242
|
+
# https://github.com/actions/runner-images/issues/8144#issuecomment-1702786388
|
|
243
|
+
`brew install xcodesorg/made/xcodes`
|
|
244
|
+
`xcodes runtimes install 'visionOS 1.0-beta3'`
|
|
245
|
+
yield
|
|
246
|
+
end
|
|
247
|
+
end
|
|
@@ -50,15 +50,14 @@ extension CALayer {
|
|
|
50
50
|
guard !keyframes.isEmpty else { return nil }
|
|
51
51
|
|
|
52
52
|
// Check if this set of keyframes uses After Effects expressions, which aren't supported.
|
|
53
|
-
|
|
53
|
+
// - We only log this once per `CoreAnimationLayer` instance.
|
|
54
|
+
if keyframeGroup.unsupportedAfterEffectsExpression != nil, !context.loggingState.hasLoggedAfterEffectsExpressionsWarning {
|
|
55
|
+
context.loggingState.hasLoggedAfterEffectsExpressionsWarning = true
|
|
54
56
|
context.logger.info("""
|
|
55
57
|
`\(property.caLayerKeypath)` animation for "\(context.currentKeypath.fullPath)" \
|
|
56
58
|
includes an After Effects expression (https://helpx.adobe.com/after-effects/using/expression-language.html), \
|
|
57
59
|
which is not supported by lottie-ios (expressions are only supported by lottie-web). \
|
|
58
60
|
This animation may not play correctly.
|
|
59
|
-
|
|
60
|
-
\(unsupportedAfterEffectsExpression.replacingOccurrences(of: "\n", with: "\n "))
|
|
61
|
-
|
|
62
61
|
""")
|
|
63
62
|
}
|
|
64
63
|
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Created by Cal Stephens on 8/15/23.
|
|
2
|
+
// Copyright © 2023 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
// MARK: - DropShadowModel
|
|
7
|
+
|
|
8
|
+
protocol DropShadowModel {
|
|
9
|
+
/// The opacity of the drop shadow, from 0 to 100.
|
|
10
|
+
var _opacity: KeyframeGroup<LottieVector1D>? { get }
|
|
11
|
+
|
|
12
|
+
/// The shadow radius of the blur
|
|
13
|
+
var _radius: KeyframeGroup<LottieVector1D>? { get }
|
|
14
|
+
|
|
15
|
+
/// The color of the drop shadow
|
|
16
|
+
var _color: KeyframeGroup<LottieColor>? { get }
|
|
17
|
+
|
|
18
|
+
/// The angle of the drop shadow, in degrees,
|
|
19
|
+
/// with "90" resulting in a shadow directly beneath the layer.
|
|
20
|
+
/// Combines with the `distance` to form the `shadowOffset`.
|
|
21
|
+
var _angle: KeyframeGroup<LottieVector1D>? { get }
|
|
22
|
+
|
|
23
|
+
/// The distance of the drop shadow offset.
|
|
24
|
+
/// Combines with the `angle` to form the `shadowOffset`.
|
|
25
|
+
var _distance: KeyframeGroup<LottieVector1D>? { get }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// MARK: - DropShadowStyle + DropShadowModel
|
|
29
|
+
|
|
30
|
+
extension DropShadowStyle: DropShadowModel {
|
|
31
|
+
var _opacity: KeyframeGroup<LottieVector1D>? { opacity }
|
|
32
|
+
var _color: KeyframeGroup<LottieColor>? { color }
|
|
33
|
+
var _angle: KeyframeGroup<LottieVector1D>? { angle }
|
|
34
|
+
var _distance: KeyframeGroup<LottieVector1D>? { distance }
|
|
35
|
+
|
|
36
|
+
var _radius: KeyframeGroup<LottieVector1D>? {
|
|
37
|
+
size.map { sizeValue in
|
|
38
|
+
// After Effects shadow softness uses a different range of values than CALayer.shadowRadius,
|
|
39
|
+
// so shadows render too softly if we directly use the value from After Effects. We find that
|
|
40
|
+
// dividing this value from After Effects by 2 produces results that are visually similar.
|
|
41
|
+
LottieVector1D(sizeValue.cgFloatValue / 2)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// MARK: - DropShadowEffect + DropShadowModel
|
|
47
|
+
|
|
48
|
+
extension DropShadowEffect: DropShadowModel {
|
|
49
|
+
var _color: KeyframeGroup<LottieColor>? { color?.value }
|
|
50
|
+
var _distance: KeyframeGroup<LottieVector1D>? { distance?.value }
|
|
51
|
+
|
|
52
|
+
var _radius: KeyframeGroup<LottieVector1D>? {
|
|
53
|
+
softness?.value?.map { softnessValue in
|
|
54
|
+
// After Effects shadow softness uses a different range of values than CALayer.shadowRadius,
|
|
55
|
+
// so shadows render too softly if we directly use the value from After Effects. We find that
|
|
56
|
+
// dividing this value from After Effects by 5 produces results that are visually similar.
|
|
57
|
+
LottieVector1D(softnessValue.cgFloatValue / 5)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var _opacity: KeyframeGroup<LottieVector1D>? {
|
|
62
|
+
opacity?.value?.map { originalOpacityValue in
|
|
63
|
+
// `DropShadowEffect.opacity` is a value between 0 and 255,
|
|
64
|
+
// but `DropShadowModel._opacity` expects a value between 0 and 100.
|
|
65
|
+
LottieVector1D((originalOpacityValue.value / 255.0) * 100)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
var _angle: KeyframeGroup<LottieVector1D>? {
|
|
70
|
+
direction?.value?.map { originalAngleValue in
|
|
71
|
+
// `DropShadowEffect.distance` is rotated 90º from the
|
|
72
|
+
// angle value representation expected by `DropShadowModel._angle`
|
|
73
|
+
LottieVector1D(originalAngleValue.value - 90)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// MARK: - CALayer + DropShadowModel
|
|
79
|
+
|
|
80
|
+
extension CALayer {
|
|
81
|
+
|
|
82
|
+
// MARK: Internal
|
|
83
|
+
|
|
84
|
+
/// Adds drop shadow animations from the given `DropShadowModel` to this layer
|
|
85
|
+
@nonobjc
|
|
86
|
+
func addDropShadowAnimations(
|
|
87
|
+
for dropShadowModel: DropShadowModel,
|
|
88
|
+
context: LayerAnimationContext)
|
|
89
|
+
throws
|
|
90
|
+
{
|
|
91
|
+
try addShadowOpacityAnimation(from: dropShadowModel, context: context)
|
|
92
|
+
try addShadowColorAnimation(from: dropShadowModel, context: context)
|
|
93
|
+
try addShadowRadiusAnimation(from: dropShadowModel, context: context)
|
|
94
|
+
try addShadowOffsetAnimation(from: dropShadowModel, context: context)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// MARK: Private
|
|
98
|
+
|
|
99
|
+
private func addShadowOpacityAnimation(from model: DropShadowModel, context: LayerAnimationContext) throws {
|
|
100
|
+
guard let opacityKeyframes = model._opacity else { return }
|
|
101
|
+
|
|
102
|
+
try addAnimation(
|
|
103
|
+
for: .shadowOpacity,
|
|
104
|
+
keyframes: opacityKeyframes,
|
|
105
|
+
value: {
|
|
106
|
+
// Lottie animation files express opacity as a numerical percentage value
|
|
107
|
+
// (e.g. 0%, 50%, 100%) so we divide by 100 to get the decimal values
|
|
108
|
+
// expected by Core Animation (e.g. 0.0, 0.5, 1.0).
|
|
109
|
+
$0.cgFloatValue / 100
|
|
110
|
+
},
|
|
111
|
+
context: context)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private func addShadowColorAnimation(from model: DropShadowModel, context: LayerAnimationContext) throws {
|
|
115
|
+
guard let shadowColorKeyframes = model._color else { return }
|
|
116
|
+
|
|
117
|
+
try addAnimation(
|
|
118
|
+
for: .shadowColor,
|
|
119
|
+
keyframes: shadowColorKeyframes,
|
|
120
|
+
value: \.cgColorValue,
|
|
121
|
+
context: context)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private func addShadowRadiusAnimation(from model: DropShadowModel, context: LayerAnimationContext) throws {
|
|
125
|
+
guard let shadowSizeKeyframes = model._radius else { return }
|
|
126
|
+
|
|
127
|
+
try addAnimation(
|
|
128
|
+
for: .shadowRadius,
|
|
129
|
+
keyframes: shadowSizeKeyframes,
|
|
130
|
+
value: \.cgFloatValue,
|
|
131
|
+
context: context)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private func addShadowOffsetAnimation(from model: DropShadowModel, context: LayerAnimationContext) throws {
|
|
135
|
+
guard
|
|
136
|
+
let angleKeyframes = model._angle,
|
|
137
|
+
let distanceKeyframes = model._distance
|
|
138
|
+
else { return }
|
|
139
|
+
|
|
140
|
+
let offsetKeyframes = Keyframes.combined(angleKeyframes, distanceKeyframes) { angleDegrees, distance -> CGSize in
|
|
141
|
+
// Lottie animation files express rotation in degrees
|
|
142
|
+
// (e.g. 90º, 180º, 360º) so we convert to radians to get the
|
|
143
|
+
// values expected by Core Animation (e.g. π/2, π, 2π)
|
|
144
|
+
let angleRadians = (angleDegrees.cgFloatValue * .pi) / 180
|
|
145
|
+
|
|
146
|
+
// Lottie animation files express the `shadowOffset` as (angle, distance) pair,
|
|
147
|
+
// which we convert to the expected x / y offset values:
|
|
148
|
+
let offsetX = distance.cgFloatValue * cos(angleRadians)
|
|
149
|
+
let offsetY = distance.cgFloatValue * sin(angleRadians)
|
|
150
|
+
return CGSize(width: offsetX, height: offsetY)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
try addAnimation(
|
|
154
|
+
for: .shadowOffset,
|
|
155
|
+
keyframes: offsetKeyframes,
|
|
156
|
+
value: { $0 },
|
|
157
|
+
context: context)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
}
|