lottie-ios 4.2.0 → 4.3.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 +117 -11
- package/Gemfile +1 -0
- package/Gemfile.lock +5 -0
- package/Lottie.xcodeproj/project.pbxproj +1542 -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 +346 -102
- 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/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 +7 -7
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift +67 -6
- package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +2 -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 +258 -735
- 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 +2 -2
- 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/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.0")
|
|
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
|
|
@@ -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
|
+
}
|
|
@@ -26,6 +26,16 @@ struct LayerProperty<ValueRepresentation> {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
extension LayerProperty where ValueRepresentation: Equatable {
|
|
29
|
+
/// Initializes a `LayerProperty` that corresponds to a property on `CALayer`
|
|
30
|
+
/// or some other `CALayer` subclass like `CAShapeLayer`.
|
|
31
|
+
/// - Parameters:
|
|
32
|
+
/// - caLayerKeypath: The Objective-C `#keyPath` to the `CALayer` property,
|
|
33
|
+
/// e.g. `#keyPath(CALayer.opacity)` or `#keyPath(CAShapeLayer.path)`.
|
|
34
|
+
/// - defaultValue: The default value of the property (e.g. the value of the
|
|
35
|
+
/// property immediately after calling `CALayer.init()`). Knowing this value
|
|
36
|
+
/// lets us perform some optimizations in `CALayer+addAnimation`.
|
|
37
|
+
/// - customizableProperty: A description of how this property can be customized
|
|
38
|
+
/// dynamically at runtime using `AnimationView.setValueProvider(_:keypath:)`.
|
|
29
39
|
init(
|
|
30
40
|
caLayerKeypath: String,
|
|
31
41
|
defaultValue: ValueRepresentation?,
|
|
@@ -52,7 +62,10 @@ struct CustomizableProperty<ValueRepresentation> {
|
|
|
52
62
|
|
|
53
63
|
/// A closure that coverts the type-erased value of an `AnyValueProvider`
|
|
54
64
|
/// to the strongly-typed representation used by this property, if possible.
|
|
55
|
-
|
|
65
|
+
/// - `value` is the value for the current frame that should be converted,
|
|
66
|
+
/// as returned by `AnyValueProvider.typeErasedStorage`.
|
|
67
|
+
/// - `valueProvider` is the `AnyValueProvider` that returned the type-erased value.
|
|
68
|
+
let conversion: (_ value: Any, _ valueProvider: AnyValueProvider) -> ValueRepresentation?
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
// MARK: - PropertyName
|
|
@@ -66,6 +79,8 @@ enum PropertyName: String, CaseIterable {
|
|
|
66
79
|
case scale = "Scale"
|
|
67
80
|
case position = "Position"
|
|
68
81
|
case rotation = "Rotation"
|
|
82
|
+
case strokeWidth = "Stroke Width"
|
|
83
|
+
case gradientColors = "Colors"
|
|
69
84
|
}
|
|
70
85
|
|
|
71
86
|
// MARK: CALayer properties
|
|
@@ -159,6 +174,34 @@ extension LayerProperty {
|
|
|
159
174
|
},
|
|
160
175
|
customizableProperty: nil /* currently unsupported */ )
|
|
161
176
|
}
|
|
177
|
+
|
|
178
|
+
static var shadowOpacity: LayerProperty<CGFloat> {
|
|
179
|
+
.init(
|
|
180
|
+
caLayerKeypath: #keyPath(CALayer.shadowOpacity),
|
|
181
|
+
defaultValue: 0,
|
|
182
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
static var shadowColor: LayerProperty<CGColor> {
|
|
186
|
+
.init(
|
|
187
|
+
caLayerKeypath: #keyPath(CALayer.shadowColor),
|
|
188
|
+
defaultValue: .rgb(0, 0, 0),
|
|
189
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
static var shadowRadius: LayerProperty<CGFloat> {
|
|
193
|
+
.init(
|
|
194
|
+
caLayerKeypath: #keyPath(CALayer.shadowRadius),
|
|
195
|
+
defaultValue: 3.0,
|
|
196
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
static var shadowOffset: LayerProperty<CGSize> {
|
|
200
|
+
.init(
|
|
201
|
+
caLayerKeypath: #keyPath(CALayer.shadowOffset),
|
|
202
|
+
defaultValue: CGSize(width: 0, height: -3.0),
|
|
203
|
+
customizableProperty: nil /* currently unsupported */ )
|
|
204
|
+
}
|
|
162
205
|
}
|
|
163
206
|
|
|
164
207
|
// MARK: CAShapeLayer properties
|
|
@@ -182,7 +225,7 @@ extension LayerProperty {
|
|
|
182
225
|
.init(
|
|
183
226
|
caLayerKeypath: #keyPath(CAShapeLayer.lineWidth),
|
|
184
227
|
defaultValue: 1,
|
|
185
|
-
customizableProperty:
|
|
228
|
+
customizableProperty: .floatValue(.strokeWidth))
|
|
186
229
|
}
|
|
187
230
|
|
|
188
231
|
static var lineDashPhase: LayerProperty<CGFloat> {
|
|
@@ -221,14 +264,14 @@ extension LayerProperty {
|
|
|
221
264
|
.init(
|
|
222
265
|
caLayerKeypath: #keyPath(CAGradientLayer.colors),
|
|
223
266
|
defaultValue: nil,
|
|
224
|
-
customizableProperty:
|
|
267
|
+
customizableProperty: .gradientColors)
|
|
225
268
|
}
|
|
226
269
|
|
|
227
270
|
static var locations: LayerProperty<[CGFloat]> {
|
|
228
271
|
.init(
|
|
229
272
|
caLayerKeypath: #keyPath(CAGradientLayer.locations),
|
|
230
273
|
defaultValue: nil,
|
|
231
|
-
customizableProperty:
|
|
274
|
+
customizableProperty: .gradientLocations)
|
|
232
275
|
}
|
|
233
276
|
|
|
234
277
|
static var startPoint: LayerProperty<CGPoint> {
|
|
@@ -252,7 +295,7 @@ extension CustomizableProperty {
|
|
|
252
295
|
static var color: CustomizableProperty<CGColor> {
|
|
253
296
|
.init(
|
|
254
297
|
name: [.color],
|
|
255
|
-
conversion: { typeErasedValue in
|
|
298
|
+
conversion: { typeErasedValue, _ in
|
|
256
299
|
guard let color = typeErasedValue as? LottieColor else {
|
|
257
300
|
return nil
|
|
258
301
|
}
|
|
@@ -264,7 +307,7 @@ extension CustomizableProperty {
|
|
|
264
307
|
static var opacity: CustomizableProperty<CGFloat> {
|
|
265
308
|
.init(
|
|
266
309
|
name: [.opacity],
|
|
267
|
-
conversion: { typeErasedValue in
|
|
310
|
+
conversion: { typeErasedValue, _ in
|
|
268
311
|
guard let vector = typeErasedValue as? LottieVector1D else { return nil }
|
|
269
312
|
|
|
270
313
|
// Lottie animation files express opacity as a numerical percentage value
|
|
@@ -277,7 +320,7 @@ extension CustomizableProperty {
|
|
|
277
320
|
static var scaleX: CustomizableProperty<CGFloat> {
|
|
278
321
|
.init(
|
|
279
322
|
name: [.scale],
|
|
280
|
-
conversion: { typeErasedValue in
|
|
323
|
+
conversion: { typeErasedValue, _ in
|
|
281
324
|
guard let vector = typeErasedValue as? LottieVector3D else { return nil }
|
|
282
325
|
|
|
283
326
|
// Lottie animation files express scale as a numerical percentage value
|
|
@@ -290,7 +333,7 @@ extension CustomizableProperty {
|
|
|
290
333
|
static var scaleY: CustomizableProperty<CGFloat> {
|
|
291
334
|
.init(
|
|
292
335
|
name: [.scale],
|
|
293
|
-
conversion: { typeErasedValue in
|
|
336
|
+
conversion: { typeErasedValue, _ in
|
|
294
337
|
guard let vector = typeErasedValue as? LottieVector3D else { return nil }
|
|
295
338
|
|
|
296
339
|
// Lottie animation files express scale as a numerical percentage value
|
|
@@ -303,7 +346,7 @@ extension CustomizableProperty {
|
|
|
303
346
|
static var rotation: CustomizableProperty<CGFloat> {
|
|
304
347
|
.init(
|
|
305
348
|
name: [.rotation],
|
|
306
|
-
conversion: { typeErasedValue in
|
|
349
|
+
conversion: { typeErasedValue, _ in
|
|
307
350
|
guard let vector = typeErasedValue as? LottieVector1D else { return nil }
|
|
308
351
|
|
|
309
352
|
// Lottie animation files express rotation in degrees
|
|
@@ -316,6 +359,36 @@ extension CustomizableProperty {
|
|
|
316
359
|
static var position: CustomizableProperty<CGPoint> {
|
|
317
360
|
.init(
|
|
318
361
|
name: [.position],
|
|
319
|
-
conversion: {
|
|
362
|
+
conversion: { typeErasedValue, _ in
|
|
363
|
+
guard let vector = typeErasedValue as? LottieVector3D else { return nil }
|
|
364
|
+
return vector.pointValue
|
|
365
|
+
})
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
static var gradientColors: CustomizableProperty<[CGColor]> {
|
|
369
|
+
.init(
|
|
370
|
+
name: [.gradientColors],
|
|
371
|
+
conversion: { _, typeErasedValueProvider in
|
|
372
|
+
guard let gradientValueProvider = typeErasedValueProvider as? GradientValueProvider else { return nil }
|
|
373
|
+
return gradientValueProvider.colors.map { $0.cgColorValue }
|
|
374
|
+
})
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
static var gradientLocations: CustomizableProperty<[CGFloat]> {
|
|
378
|
+
.init(
|
|
379
|
+
name: [.gradientColors],
|
|
380
|
+
conversion: { _, typeErasedValueProvider in
|
|
381
|
+
guard let gradientValueProvider = typeErasedValueProvider as? GradientValueProvider else { return nil }
|
|
382
|
+
return gradientValueProvider.locations.map { CGFloat($0) }
|
|
383
|
+
})
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
static func floatValue(_ name: PropertyName...) -> CustomizableProperty<CGFloat> {
|
|
387
|
+
.init(
|
|
388
|
+
name: name,
|
|
389
|
+
conversion: { typeErasedValue, _ in
|
|
390
|
+
guard let vector = typeErasedValue as? LottieVector1D else { return nil }
|
|
391
|
+
return vector.cgFloatValue
|
|
392
|
+
})
|
|
320
393
|
}
|
|
321
394
|
}
|