lottie-ios 3.4.0 → 3.4.3
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 +10 -7
- package/.github/workflows/stale_issues.yml +17 -0
- package/.swiftpm/xcode/package.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcodeproj/project.pbxproj +33 -21
- package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (macOS).xcscheme +2 -2
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +5 -6
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +114 -1
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +30 -0
- package/Package.swift +1 -1
- package/README.md +5 -6
- package/Rakefile +52 -17
- package/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift +7 -2
- package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +192 -67
- package/Sources/Private/CoreAnimation/Animations/CombinedShapeAnimation.swift +28 -0
- package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +31 -4
- package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +98 -43
- package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +19 -19
- package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +34 -7
- package/Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift +25 -14
- package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +61 -32
- package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +6 -2
- package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +29 -11
- package/Sources/Private/CoreAnimation/Extensions/KeyframeGroup+exactlyOneKeyframe.swift +2 -2
- package/Sources/Private/CoreAnimation/Extensions/Keyframes+combinedIfPossible.swift +116 -23
- package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +9 -0
- package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +2 -1
- package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +48 -12
- package/Sources/Private/CoreAnimation/Layers/GradientRenderLayer.swift +10 -3
- package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +5 -0
- package/Sources/Private/CoreAnimation/Layers/MaskCompositionLayer.swift +1 -1
- package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +2 -2
- package/Sources/Private/CoreAnimation/Layers/RepeaterLayer.swift +85 -0
- package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +94 -38
- package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +131 -46
- package/Sources/Private/CoreAnimation/Layers/TextLayer.swift +16 -2
- package/Sources/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.swift +1 -1
- package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +0 -2
- package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +2 -2
- package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +1 -2
- package/Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift +30 -1
- package/Sources/Private/MainThread/LayerContainers/Utility/InvertedMatteLayer.swift +1 -0
- package/Sources/Private/MainThread/LayerContainers/Utility/LayerTransformNode.swift +0 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Extensions/ItemsExtension.swift +5 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +4 -7
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +5 -0
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientStrokeRenderer.swift +1 -2
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/RectNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/StarNode.swift +3 -3
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +3 -0
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +28 -1
- package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +1 -1
- package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeRenderLayer.swift +0 -1
- package/Sources/Private/Model/Animation.swift +4 -4
- package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +25 -0
- package/Sources/Private/Model/ShapeItems/Ellipse.swift +0 -1
- package/Sources/Private/Model/ShapeItems/Fill.swift +1 -1
- package/Sources/Private/Model/ShapeItems/GradientFill.swift +14 -1
- package/Sources/Private/Model/ShapeItems/GradientStroke.swift +0 -1
- package/Sources/Private/Model/ShapeItems/Group.swift +6 -1
- package/Sources/Private/Model/ShapeItems/Merge.swift +0 -1
- package/Sources/Private/Model/ShapeItems/Rectangle.swift +0 -1
- package/Sources/Private/Model/ShapeItems/Repeater.swift +0 -1
- package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +0 -1
- package/Sources/Private/Model/ShapeItems/Star.swift +0 -1
- package/Sources/Private/Model/ShapeItems/Stroke.swift +0 -1
- package/Sources/Private/Model/ShapeItems/Trim.swift +0 -1
- package/Sources/Private/Model/Text/TextAnimator.swift +0 -1
- package/Sources/Private/Utility/Debugging/LayerDebugging.swift +1 -2
- package/Sources/Private/Utility/Extensions/MathKit.swift +1 -2
- package/Sources/Private/Utility/Extensions/StringExtensions.swift +0 -1
- package/Sources/Private/Utility/Interpolatable/InterpolatableExtensions.swift +0 -1
- package/Sources/Private/{MainThread/NodeRenderSystem/NodeProperties/ValueProviders → Utility/Interpolatable}/KeyframeInterpolator.swift +1 -4
- package/Sources/Private/Utility/Primitives/BezierPath.swift +1 -2
- package/Sources/Private/Utility/Primitives/CurveVertex.swift +2 -4
- package/Sources/Public/Animation/AnimationPublic.swift +2 -4
- package/Sources/Public/Animation/AnimationView.swift +29 -7
- package/Sources/Public/Animation/AnimationViewInitializers.swift +13 -11
- package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +0 -2
- package/Sources/Public/FontProvider/AnimationFontProvider.swift +1 -1
- package/Sources/Public/Logging/LottieLogger.swift +15 -2
- package/Sources/Public/TextProvider/AnimationTextProvider.swift +1 -1
- package/Sources/Public/iOS/AnimatedButton.swift +10 -4
- package/Sources/Public/iOS/AnimatedControl.swift +3 -5
- package/Sources/Public/iOS/AnimatedSwitch.swift +9 -6
- package/Sources/Public/iOS/BundleImageProvider.swift +2 -3
- package/Sources/Public/iOS/FilepathImageProvider.swift +1 -2
- package/Sources/Public/macOS/BundleImageProvider.macOS.swift +1 -2
- package/Sources/Public/macOS/FilepathImageProvider.macOS.swift +1 -3
- package/Tests/AnimationKeypathTests.swift +10 -1
- package/Tests/AutomaticEngineTests.swift +1 -0
- package/Tests/ParsingTests.swift +2 -1
- package/Tests/PerformanceTests.swift +28 -29
- package/Tests/SnapshotConfiguration.swift +19 -0
- package/Tests/SnapshotTests.swift +4 -0
- package/Tests/Utils/HardcodedTextProvider.swift +27 -0
- package/lottie-ios.podspec +2 -2
- package/package.json +1 -1
- package/script/test-carthage/CarthageTest/AppDelegate.swift +6 -7
- package/script/test-carthage/CarthageTest/ViewController.swift +1 -1
- package/script/test-carthage/CarthageTest-macOS/AppDelegate.swift +7 -0
- package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/AppIcon.appiconset/Contents.json +58 -0
- package/script/test-carthage/CarthageTest-macOS/Assets.xcassets/Contents.json +6 -0
- package/script/test-carthage/CarthageTest-macOS/Base.lproj/Main.storyboard +717 -0
- package/script/test-carthage/CarthageTest-macOS/CarthageTest_macOS.entitlements +10 -0
- package/script/test-carthage/CarthageTest-macOS/ViewController.swift +15 -0
- package/script/test-carthage/CarthageTest.xcodeproj/project.pbxproj +159 -5
- package/script/test-carthage/CarthageTest.xcodeproj/project.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/script/test-carthage/CarthageTest.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +19 -0
- package/Lottie.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +0 -23
- package/Mintfile +0 -3
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~-7Vi1RszY1XYnR2CCkEwIpKG8NwwA9zsZEz_WD7Dv6kKh4RC7N7ob8NIRVHGUJKp7eXxlpeI_gzD87Pcs_2u0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~-SKV2drO-SFlrlh-wrzECDMkUSr-aF1lV9h-5onOy94zSTsD-oI45s0-KpOK45L-kq3hRY7v9vm-xmh00_eheg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~-_CU_vuaiFfObSeDFfmp7GuB20ThMSAL-P_RUMowiQLbdu-y0bU9upIm3q8g6XmXUG5hP6J1az0Ma5Hi_rhhRg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~03aPYP6VHJjZj5DlphGarj0xdw43qu09Onx5SReZoPvg9zh5uL212E-KWfGct9jf6JG0JFV2tdbBi7X_8bH9aw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~1Z82GPBBPc1VLvn4O7V5glb6lgyXteNlDREUzV_TPymM4ra4UkBMklzV90lEqoYRCDuRVzaQHaDYbmYp3-8CFw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~1mFDCboXpUu9pSHAiVGr1O_QgqEEtvJp_LUhickxLZo0Z5pj3fvadn1l2MzEOd4bFsVBZifUvcyPa7dzlMWF-A== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~2_L9PUjv2JDKu1n8bDLb4XLB-yex6ZVjDDMwfuKAr7teDw-SKgLgkW6H-m_gjWChIVdB4vW6yvHP7XJxvXtRNA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -1
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~4krT4ZMzDOu34msFUq0Xod142kw4pAeSWX4JSxlsjOI0Wanu3343qeespgFi61MTWq1DdH9XXspVKqGlGm_fyw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~5_aJsdP-e3dRTAUnH-y1U2plaCuUi1vyHriaZuNK0xFe8wGl9Qft6uLCX2Qt6CRBKJQluEe9o0uRWw1eb42FHQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~8b0bSqV7eND54zvHvu1v2Htpm7yn-BOEFw5d3mITJrXWNykJ5BTR9WbrD80JEctNcT-rDqO2xfrQk1tFWeY6Sw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~9u8KAGpgtSm-mQ12Py8RZUbYbDlBhM3w1I2MQO53K2CSn6IePp7g65DBcdXTYMfG1bgoJ-6x30fjnGe-2UYsDQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Bw7uMs4wqB9ahfEqGii2FkQ9pvZmG6HGe2hmbAT2wyM5hpn8Xh5dELysMcEz6hEsqmn6HdRdLOLZhC_fNaXzgA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~BwUq2xXQYuE8ya6HT6lfNsdtEjz5AKGf8GvLY6VBxQyIY1vgj_Gov-3NeM69OS66BQRDK0PG9H4Oyg0R48E4vg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~EkDVUR6dcnzxV_lYjkrJ5QGMVTCvb_upAoBF6DBu61sQkGvZN3fSRTsJ1XfJIZO-JUzdNoVA3D_CcvokL0gnQg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~FUkcLSJ8RAuPenM4HFG1R-sN5-cDBGcTxgR2jaVCna7xV0ZTyBHriB1Nn59mariNlJDiCoBtMUQEmauGxWtfBA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~FqsuZe4RVLOOVUYLTL-GTIohZ8TdSfxx7m2KJtLYFPGOdE4XorTX7Oc7kXbhghPRppXT3jW-slI37M34YNEvLQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~G4F_NtyTj3i46fmKm0NorHAeq8tYWWYf6uv5yC1DwzdpWVoYbOPufmFNvdEbxZt4AMdV0gKx3HI46EAXNOQVFg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~GxetzGUNDgaBBXcTmLK6p9JBDX3I3QPshshbui1IaEWvJbQko-E36tCKwaJYHbleAWz9FqkAM_Tqx3YOmSVkVg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~H1Wjd5kKWDW4t3SDodxiHV72V8WT0xwPubw5cJTNLkPRLgaILFPh-dpy8EOUNgy1KzrDujFsm9EcTsbuqtMPLA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~JpI5MH4zCgebUHFpXVn4zjtsGtMNnO7BQZWfNARAB5UWa9gqz6YXHR3uLCJ_AvJ3lh53BUVkavsx9TY2FMmxbA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~JujNYkJtcux0Ni4QnR64zu4Wz_zYjyKvYaYZm5ypxTLPSzF3_jNE_NO4sdbDamF8wEqWoky1uf4ZE0JT3L607A== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~KJSEA6DKnb2_FRPSqKZGh41eo-C8x448J9kEBrH012bUrZfOSDvrgmIrU0Vz7Ri3gaS9aKKmSaVMvXsHSlTJVA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~MStOwu3jBlJtcRnxrseVOuhI4kCj--ggFPG7sqrq5w1hjrI3bVyD-bm1Jwyx0noY3wT1rHDEvaGWnV2qsGjGwg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~McsJ8kFVf3IjhgXIRdw8Xx-EXgbV071bmlj2BBnk52xrWl3sEeiIyxwUsF7mIWvMRWfcFfu4VGHYyqfk2BeHXw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~NHt9fVe4kDdbxnglKcEwXaRK-WsYEOaD23Kbl8SJPRMYHr_Z6SJd_HmG3BROHHR_M6TgSmucONpDJdTj5tjuFw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Nfo2iwCPcfAcOBIVyoUAK0-PIfr5qYxIKZt-uaSaTBdrTNxAuJ1ItmeDPZ3VdJJmxD_c22No7x482bdd3_yYtw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~S2Qlu11xBhEd5aGSzWsnw1TR8u8PiOF93GO0j5bfNoAFCVzxKOwhRFoIXba2EpQnLQqFdIKyhWN3l70A4GPHmg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~W7a7M37RO9jgck2zeR0471Pm7e8K0Kqj5tXEouDjvqKZXSrWxMaWD28oqkKKYAiU4608R4S9mM11KyphljdMSw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~XUo1oyPCrlL7CA74wG-OzQ06VOWJYWvHGFHU7keZN1SKaIXjHX5qi_kBzjG_rBCi89-S8GVmCy7S3PHSjG8SbQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Xh0VmDvFNMELHu08-vrs54pegVyUwwDRxx_nXkwyD0NjnYozyqcGAKAr_QWHmw6F8XyuWg51M9KGpJJIFzzGuw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Xve-wMBp_lxVUgD9qH5GwieGP9cAWtm0xULZvdGjBRUMvaevmpCB5gnbMBuIXAO6a1c9v6WUq0jNVX7ut5HvOw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~ZU1XkZFgnEE22CXEF-pOlcj5f10x-KM1Vw9d4IOLu-NiTZcz7koYPixhdrB1PJr8J-h9NpJmfqEastfxamA1jQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~_YkNYEHTsbbtFILJpzH3HenH0t4ShI25dIMdve541CF5bl-jPF3X3F7tq-t5dvP0TEkATsOJdLQdBp1xv4Q-ag== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~boy6mpn2jkwm60jjgQ0TG25UqRdN46LzmgTVCrpy6nBOgkLCGkGHcbceiwjU1itS_vj3-iQX0ZnrWOQrPyfHNA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~bwzpVZ9hAqGDHhXs2FRA82dfGfLmc7-m0uQhZDDfHHO7hQ17M_Np341BZX4WDLhYYS4cdUgaDodlNpdfpG3nXw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~cBxe-9PpAGFdAsYkmdN3lJVqEliLcRYlyoAov0aPZfJGwUr_cOm3XpjO7nmf_2eLf8UAx-rycjnJzw07xLrNCA== +0 -1
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~dirWk6W4Pav1oyciuflfJlRu0iuxbYOmrpQapOJ0mV9C1SQ-jvDRv_7h753Cy18-SwULARUdWsyUy3yNNvxF7w== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~ebwZVjSEHroc9jtIm4jd_h_YAqEBcOkAZ4HPNJT8pLCldjRcTq-obQLakxXOhfuoOBlYBoZLuO-Y0lskeZRYKw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~gfcRcmRIr0h09d0jiZsA7nUeQv2XtapxuYEXZy1Z9um0tTJQvz-O5ef5f7zhLenLvjnDtDtlY_aY4Hvpce6e1Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~hgOgiVCyv2R0W-f0qKw5xYPeUwj8_ccCM9vKH_7vAQcCO9t8BwR1APGRBv20AONmp-PYMXmtgsBlQkNBRBpdQA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~hrhCl-YRAAr8ByNB_LCgEBsVNHMp92gTIUknetpUHMjcXl4Hpn_uY-h6C45oga0ZALnfGCo6iKTmiPLa4Qvnpg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~n2yoR7JsyL4DSUwmjnpE4Iq9Qi_eeZrmpPU8cdehDFKfESK7nwxXxfrSMQbk0BQ2lgGPadoRcd1-qr1xVz97jA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~nMCcZm8WvPogyO_nuJ926Q3Q2dqVMN2LdjEL1Kq2wJ_RG-rH-e_6v41l1xZbCsQTa3XykQdEiXNc0HtAvT6IRA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~oc3C7xkUt-OWDL6rrsxs-seS4Fu1bqBWAAXCHalgShaGg9MUrOiRbHT2DcAnhyQFKx6x5FRbvjmYoQWrQiXJZA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~p-ihj7SEgkDXpMu9hvKE_wiX9cvtwyXrdIn964BfedXHKGpC6o7mMPxEyC0kRPVi_EZs_MRV5bAPEpl5h5we0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~qlhO_D9oE8uSKH-mZqyRF9pp4Zv1Tv0dIYcqrH4hb1VWlIxcdxmg2j0M8496cQeFXC5bn_JMXdBlD-d6cnFF8w== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~tjpiyIxJR_boTdUNrtFDuKIZoY84fI4lA1oMJbq9e2ZmYKIK5FeRN2O8cV_yMOYJGr4lbv03kTmT70mCjUc2_Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~wULeoj18eEKJWAKx1uFQVwS48cUGFcYPRJQj1Ro5XNJsWCwppGSCdIPhwifD6Z2f_j3zfI2SmC2Gg81sBXXW7g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~zrEihMys4NVV5rx6FmuzEGO2TjloI3OiC7yzIhvqYoRo43ibb2F-Km6Jf4NX-ac62pOLBYZRcjQTvYMpn75_oA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~-7Vi1RszY1XYnR2CCkEwIpKG8NwwA9zsZEz_WD7Dv6kKh4RC7N7ob8NIRVHGUJKp7eXxlpeI_gzD87Pcs_2u0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~-SKV2drO-SFlrlh-wrzECDMkUSr-aF1lV9h-5onOy94zSTsD-oI45s0-KpOK45L-kq3hRY7v9vm-xmh00_eheg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~-_CU_vuaiFfObSeDFfmp7GuB20ThMSAL-P_RUMowiQLbdu-y0bU9upIm3q8g6XmXUG5hP6J1az0Ma5Hi_rhhRg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~03aPYP6VHJjZj5DlphGarj0xdw43qu09Onx5SReZoPvg9zh5uL212E-KWfGct9jf6JG0JFV2tdbBi7X_8bH9aw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~1Z82GPBBPc1VLvn4O7V5glb6lgyXteNlDREUzV_TPymM4ra4UkBMklzV90lEqoYRCDuRVzaQHaDYbmYp3-8CFw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~1mFDCboXpUu9pSHAiVGr1O_QgqEEtvJp_LUhickxLZo0Z5pj3fvadn1l2MzEOd4bFsVBZifUvcyPa7dzlMWF-A== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~2_L9PUjv2JDKu1n8bDLb4XLB-yex6ZVjDDMwfuKAr7teDw-SKgLgkW6H-m_gjWChIVdB4vW6yvHP7XJxvXtRNA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~4krT4ZMzDOu34msFUq0Xod142kw4pAeSWX4JSxlsjOI0Wanu3343qeespgFi61MTWq1DdH9XXspVKqGlGm_fyw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~5_aJsdP-e3dRTAUnH-y1U2plaCuUi1vyHriaZuNK0xFe8wGl9Qft6uLCX2Qt6CRBKJQluEe9o0uRWw1eb42FHQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~8b0bSqV7eND54zvHvu1v2Htpm7yn-BOEFw5d3mITJrXWNykJ5BTR9WbrD80JEctNcT-rDqO2xfrQk1tFWeY6Sw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~9u8KAGpgtSm-mQ12Py8RZUbYbDlBhM3w1I2MQO53K2CSn6IePp7g65DBcdXTYMfG1bgoJ-6x30fjnGe-2UYsDQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Bw7uMs4wqB9ahfEqGii2FkQ9pvZmG6HGe2hmbAT2wyM5hpn8Xh5dELysMcEz6hEsqmn6HdRdLOLZhC_fNaXzgA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~BwUq2xXQYuE8ya6HT6lfNsdtEjz5AKGf8GvLY6VBxQyIY1vgj_Gov-3NeM69OS66BQRDK0PG9H4Oyg0R48E4vg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~EkDVUR6dcnzxV_lYjkrJ5QGMVTCvb_upAoBF6DBu61sQkGvZN3fSRTsJ1XfJIZO-JUzdNoVA3D_CcvokL0gnQg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~FUkcLSJ8RAuPenM4HFG1R-sN5-cDBGcTxgR2jaVCna7xV0ZTyBHriB1Nn59mariNlJDiCoBtMUQEmauGxWtfBA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~FqsuZe4RVLOOVUYLTL-GTIohZ8TdSfxx7m2KJtLYFPGOdE4XorTX7Oc7kXbhghPRppXT3jW-slI37M34YNEvLQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~G4F_NtyTj3i46fmKm0NorHAeq8tYWWYf6uv5yC1DwzdpWVoYbOPufmFNvdEbxZt4AMdV0gKx3HI46EAXNOQVFg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~GxetzGUNDgaBBXcTmLK6p9JBDX3I3QPshshbui1IaEWvJbQko-E36tCKwaJYHbleAWz9FqkAM_Tqx3YOmSVkVg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~H1Wjd5kKWDW4t3SDodxiHV72V8WT0xwPubw5cJTNLkPRLgaILFPh-dpy8EOUNgy1KzrDujFsm9EcTsbuqtMPLA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~JpI5MH4zCgebUHFpXVn4zjtsGtMNnO7BQZWfNARAB5UWa9gqz6YXHR3uLCJ_AvJ3lh53BUVkavsx9TY2FMmxbA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~JujNYkJtcux0Ni4QnR64zu4Wz_zYjyKvYaYZm5ypxTLPSzF3_jNE_NO4sdbDamF8wEqWoky1uf4ZE0JT3L607A== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~KJSEA6DKnb2_FRPSqKZGh41eo-C8x448J9kEBrH012bUrZfOSDvrgmIrU0Vz7Ri3gaS9aKKmSaVMvXsHSlTJVA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~MStOwu3jBlJtcRnxrseVOuhI4kCj--ggFPG7sqrq5w1hjrI3bVyD-bm1Jwyx0noY3wT1rHDEvaGWnV2qsGjGwg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~McsJ8kFVf3IjhgXIRdw8Xx-EXgbV071bmlj2BBnk52xrWl3sEeiIyxwUsF7mIWvMRWfcFfu4VGHYyqfk2BeHXw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~NHt9fVe4kDdbxnglKcEwXaRK-WsYEOaD23Kbl8SJPRMYHr_Z6SJd_HmG3BROHHR_M6TgSmucONpDJdTj5tjuFw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Nfo2iwCPcfAcOBIVyoUAK0-PIfr5qYxIKZt-uaSaTBdrTNxAuJ1ItmeDPZ3VdJJmxD_c22No7x482bdd3_yYtw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~S2Qlu11xBhEd5aGSzWsnw1TR8u8PiOF93GO0j5bfNoAFCVzxKOwhRFoIXba2EpQnLQqFdIKyhWN3l70A4GPHmg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~W7a7M37RO9jgck2zeR0471Pm7e8K0Kqj5tXEouDjvqKZXSrWxMaWD28oqkKKYAiU4608R4S9mM11KyphljdMSw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~XUo1oyPCrlL7CA74wG-OzQ06VOWJYWvHGFHU7keZN1SKaIXjHX5qi_kBzjG_rBCi89-S8GVmCy7S3PHSjG8SbQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Xh0VmDvFNMELHu08-vrs54pegVyUwwDRxx_nXkwyD0NjnYozyqcGAKAr_QWHmw6F8XyuWg51M9KGpJJIFzzGuw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Xve-wMBp_lxVUgD9qH5GwieGP9cAWtm0xULZvdGjBRUMvaevmpCB5gnbMBuIXAO6a1c9v6WUq0jNVX7ut5HvOw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~ZU1XkZFgnEE22CXEF-pOlcj5f10x-KM1Vw9d4IOLu-NiTZcz7koYPixhdrB1PJr8J-h9NpJmfqEastfxamA1jQ== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~_YkNYEHTsbbtFILJpzH3HenH0t4ShI25dIMdve541CF5bl-jPF3X3F7tq-t5dvP0TEkATsOJdLQdBp1xv4Q-ag== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~boy6mpn2jkwm60jjgQ0TG25UqRdN46LzmgTVCrpy6nBOgkLCGkGHcbceiwjU1itS_vj3-iQX0ZnrWOQrPyfHNA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~bwzpVZ9hAqGDHhXs2FRA82dfGfLmc7-m0uQhZDDfHHO7hQ17M_Np341BZX4WDLhYYS4cdUgaDodlNpdfpG3nXw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~cBxe-9PpAGFdAsYkmdN3lJVqEliLcRYlyoAov0aPZfJGwUr_cOm3XpjO7nmf_2eLf8UAx-rycjnJzw07xLrNCA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~dirWk6W4Pav1oyciuflfJlRu0iuxbYOmrpQapOJ0mV9C1SQ-jvDRv_7h753Cy18-SwULARUdWsyUy3yNNvxF7w== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~ebwZVjSEHroc9jtIm4jd_h_YAqEBcOkAZ4HPNJT8pLCldjRcTq-obQLakxXOhfuoOBlYBoZLuO-Y0lskeZRYKw== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~gfcRcmRIr0h09d0jiZsA7nUeQv2XtapxuYEXZy1Z9um0tTJQvz-O5ef5f7zhLenLvjnDtDtlY_aY4Hvpce6e1Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~hgOgiVCyv2R0W-f0qKw5xYPeUwj8_ccCM9vKH_7vAQcCO9t8BwR1APGRBv20AONmp-PYMXmtgsBlQkNBRBpdQA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~hrhCl-YRAAr8ByNB_LCgEBsVNHMp92gTIUknetpUHMjcXl4Hpn_uY-h6C45oga0ZALnfGCo6iKTmiPLa4Qvnpg== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~n2yoR7JsyL4DSUwmjnpE4Iq9Qi_eeZrmpPU8cdehDFKfESK7nwxXxfrSMQbk0BQ2lgGPadoRcd1-qr1xVz97jA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~nMCcZm8WvPogyO_nuJ926Q3Q2dqVMN2LdjEL1Kq2wJ_RG-rH-e_6v41l1xZbCsQTa3XykQdEiXNc0HtAvT6IRA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~oc3C7xkUt-OWDL6rrsxs-seS4Fu1bqBWAAXCHalgShaGg9MUrOiRbHT2DcAnhyQFKx6x5FRbvjmYoQWrQiXJZA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~p-ihj7SEgkDXpMu9hvKE_wiX9cvtwyXrdIn964BfedXHKGpC6o7mMPxEyC0kRPVi_EZs_MRV5bAPEpl5h5we0g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~qlhO_D9oE8uSKH-mZqyRF9pp4Zv1Tv0dIYcqrH4hb1VWlIxcdxmg2j0M8496cQeFXC5bn_JMXdBlD-d6cnFF8w== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~tjpiyIxJR_boTdUNrtFDuKIZoY84fI4lA1oMJbq9e2ZmYKIK5FeRN2O8cV_yMOYJGr4lbv03kTmT70mCjUc2_Q== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~wULeoj18eEKJWAKx1uFQVwS48cUGFcYPRJQj1Ro5XNJsWCwppGSCdIPhwifD6Z2f_j3zfI2SmC2Gg81sBXXW7g== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~zrEihMys4NVV5rx6FmuzEGO2TjloI3OiC7yzIhvqYoRo43ibb2F-Km6Jf4NX-ac62pOLBYZRcjQTvYMpn75_oA== +0 -0
- package/Tests/Artifacts/LottieTests.xcresult/Info.plist +0 -29
- package/Tests/Samples/9squares_AlBoardman.json +0 -1
- package/Tests/Samples/Boat_Loader.json +0 -1
- package/Tests/Samples/HamburgerArrow.json +0 -1
- package/Tests/Samples/IconTransitions.json +0 -1
- package/Tests/Samples/Images/dog.png +0 -0
- package/Tests/Samples/Issues/issue_1403.json +0 -1
- package/Tests/Samples/Issues/issue_1407.json +0 -1
- package/Tests/Samples/Issues/issue_1488.json +0 -1
- package/Tests/Samples/Issues/issue_1505.json +0 -1
- package/Tests/Samples/Issues/issue_1628.json +0 -1
- package/Tests/Samples/Issues/pr_1536.json +0 -1
- package/Tests/Samples/Issues/pr_1563.json +0 -8439
- package/Tests/Samples/Issues/pr_1592.json +0 -5527
- package/Tests/Samples/Issues/pr_1599.json +0 -738
- package/Tests/Samples/Issues/pr_1604_1.json +0 -1
- package/Tests/Samples/Issues/pr_1604_2.json +0 -1
- package/Tests/Samples/LottieFiles/LICENSE.md +0 -14
- package/Tests/Samples/LottieFiles/bounce_strokes.json +0 -1
- package/Tests/Samples/LottieFiles/cactus.json +0 -1
- package/Tests/Samples/LottieFiles/dog_car_ride.json +0 -1
- package/Tests/Samples/LottieFiles/draft_icon.json +0 -1
- package/Tests/Samples/LottieFiles/gradient_1.json +0 -1
- package/Tests/Samples/LottieFiles/gradient_2.json +0 -1
- package/Tests/Samples/LottieFiles/gradient_pill.json +0 -1
- package/Tests/Samples/LottieFiles/gradient_shapes.json +0 -1
- package/Tests/Samples/LottieFiles/gradient_square.json +0 -1
- package/Tests/Samples/LottieFiles/growth.json +0 -1
- package/Tests/Samples/LottieFiles/infinity_loader.json +0 -1
- package/Tests/Samples/LottieFiles/loading_dots_1.json +0 -1
- package/Tests/Samples/LottieFiles/loading_dots_2.json +0 -1
- package/Tests/Samples/LottieFiles/loading_dots_3.json +0 -1
- package/Tests/Samples/LottieFiles/loading_gradient_strokes.json +0 -1
- package/Tests/Samples/LottieFiles/settings_slider.json +0 -1
- package/Tests/Samples/LottieFiles/shop.json +0 -1
- package/Tests/Samples/LottieFiles/step_loader.json +0 -1
- package/Tests/Samples/LottieLogo1.json +0 -1
- package/Tests/Samples/LottieLogo1_masked.json +0 -1
- package/Tests/Samples/LottieLogo2.json +0 -1
- package/Tests/Samples/MotionCorpse_Jrcanest.json +0 -1
- package/Tests/Samples/Nonanimating/BasicLayers.json +0 -1
- package/Tests/Samples/Nonanimating/DisableNodesTest.json +0 -1
- package/Tests/Samples/Nonanimating/FirstText.json +0 -1
- package/Tests/Samples/Nonanimating/GeometryTransformTest.json +0 -1
- package/Tests/Samples/Nonanimating/Text_AnimatedProperties.json +0 -1
- package/Tests/Samples/Nonanimating/Text_Glyph.json +0 -1
- package/Tests/Samples/Nonanimating/Text_NoAnimation.json +0 -1
- package/Tests/Samples/Nonanimating/Text_NoGlyph.json +0 -1
- package/Tests/Samples/Nonanimating/Zoom.json +0 -1
- package/Tests/Samples/Nonanimating/_dog.json +0 -1
- package/Tests/Samples/Nonanimating/base64Test.json +0 -1
- package/Tests/Samples/Nonanimating/blend_mode_test.json +0 -1
- package/Tests/Samples/Nonanimating/keypathTest.json +0 -1
- package/Tests/Samples/Nonanimating/verifyLineHeight.json +0 -1
- package/Tests/Samples/PinJump.json +0 -1
- package/Tests/Samples/Private/BrokenLottieFiles/growth_man.json +0 -874
- package/Tests/Samples/Private/BrokenLottieFiles/rocket.json +0 -1
- package/Tests/Samples/Private/China_EmptyState_Itinerary.json +0 -1
- package/Tests/Samples/Private/LoaderHourglass.json +0 -12070
- package/Tests/Samples/Private/README.md +0 -7
- package/Tests/Samples/Private/Urgency/alarm_animated.json +0 -1
- package/Tests/Samples/Private/Urgency/diamond_animated.json +0 -1
- package/Tests/Samples/Private/Urgency/eye_animated.json +0 -1
- package/Tests/Samples/Private/Urgency/light_bulb_animated.json +0 -1
- package/Tests/Samples/Private/Urgency/light_bulb_static.json +0 -1
- package/Tests/Samples/Private/Urgency/piggy_bank_static.json +0 -1
- package/Tests/Samples/Private/Urgency/price_tag_legacy.json +0 -1
- package/Tests/Samples/Private/Urgency/rausch_alarm.json +0 -1
- package/Tests/Samples/Private/Urgency/rausch_alert.json +0 -1
- package/Tests/Samples/Private/Urgency/rausch_clock.json +0 -1
- package/Tests/Samples/Private/Urgency/rausch_diamond.json +0 -1
- package/Tests/Samples/Private/Urgency/rausch_money.json +0 -1
- package/Tests/Samples/Private/Urgency/rausch_piggy_bank.json +0 -1
- package/Tests/Samples/Private/Urgency/rausch_tag.json +0 -1
- package/Tests/Samples/Private/Urgency/red_envelope_animated.json +0 -1
- package/Tests/Samples/Private/Urgency/tag_animated.json +0 -1
- package/Tests/Samples/Private/Urgency/trophy_animated.json +0 -1
- package/Tests/Samples/Private/Urgency/wings_key_animated.json +0 -1
- package/Tests/Samples/Private/_flexible.json +0 -1
- package/Tests/Samples/Private/aircover.json +0 -1
- package/Tests/Samples/Private/belo_spin_rausch.json +0 -1
- package/Tests/Samples/Private/celebration.json +0 -2821
- package/Tests/Samples/Private/checkbox.json +0 -1
- package/Tests/Samples/Private/checkbox_small.json +0 -1
- package/Tests/Samples/Private/getting_your_trip_ready.json +0 -3540
- package/Tests/Samples/Private/gradient_afternoon.json +0 -1
- package/Tests/Samples/Private/gradient_brand.json +0 -1
- package/Tests/Samples/Private/gradient_evening.json +0 -1
- package/Tests/Samples/Private/gradient_morning.json +0 -1
- package/Tests/Samples/Private/issue_1467.json +0 -1
- package/Tests/Samples/Private/loading_dots.json +0 -1
- package/Tests/Samples/Private/loading_dots_small.json +0 -1
- package/Tests/Samples/Private/payment_loader.json +0 -1
- package/Tests/Samples/Private/radio_button.json +0 -1
- package/Tests/Samples/Private/selfie_intro.json +0 -1
- package/Tests/Samples/Private/stepper_add.json +0 -1
- package/Tests/Samples/Private/stepper_subtract.json +0 -1
- package/Tests/Samples/Private/switch.json +0 -1
- package/Tests/Samples/Private/thumb.json +0 -1
- package/Tests/Samples/Private/toggle_no.json +0 -1
- package/Tests/Samples/Private/toggle_yes.json +0 -1
- package/Tests/Samples/Private/user_error_black_and_white.json +0 -1
- package/Tests/Samples/Private/user_error_cut_off.json +0 -1
- package/Tests/Samples/Switch.json +0 -1
- package/Tests/Samples/Switch_States.json +0 -1
- package/Tests/Samples/TwitterHeart.json +0 -1
- package/Tests/Samples/TwitterHeartButton.json +0 -1
- package/Tests/Samples/TypeFace/A.json +0 -1
- package/Tests/Samples/TypeFace/Apostrophe.json +0 -1
- package/Tests/Samples/TypeFace/B.json +0 -1
- package/Tests/Samples/TypeFace/BlinkingCursor.json +0 -1
- package/Tests/Samples/TypeFace/C.json +0 -1
- package/Tests/Samples/TypeFace/Colon.json +0 -1
- package/Tests/Samples/TypeFace/Comma.json +0 -1
- package/Tests/Samples/TypeFace/D.json +0 -1
- package/Tests/Samples/TypeFace/E.json +0 -1
- package/Tests/Samples/TypeFace/F.json +0 -1
- package/Tests/Samples/TypeFace/G.json +0 -1
- package/Tests/Samples/TypeFace/H.json +0 -1
- package/Tests/Samples/TypeFace/I.json +0 -1
- package/Tests/Samples/TypeFace/J.json +0 -1
- package/Tests/Samples/TypeFace/K.json +0 -1
- package/Tests/Samples/TypeFace/L.json +0 -1
- package/Tests/Samples/TypeFace/M.json +0 -1
- package/Tests/Samples/TypeFace/N.json +0 -1
- package/Tests/Samples/TypeFace/O.json +0 -1
- package/Tests/Samples/TypeFace/P.json +0 -1
- package/Tests/Samples/TypeFace/Q.json +0 -1
- package/Tests/Samples/TypeFace/R.json +0 -1
- package/Tests/Samples/TypeFace/S.json +0 -1
- package/Tests/Samples/TypeFace/T.json +0 -1
- package/Tests/Samples/TypeFace/U.json +0 -1
- package/Tests/Samples/TypeFace/V.json +0 -1
- package/Tests/Samples/TypeFace/W.json +0 -1
- package/Tests/Samples/TypeFace/X.json +0 -1
- package/Tests/Samples/TypeFace/Y.json +0 -1
- package/Tests/Samples/TypeFace/Z.json +0 -1
- package/Tests/Samples/Watermelon.json +0 -1
- package/Tests/Samples/setValueTest.json +0 -1
- package/Tests/Samples/timeremap.json +0 -1
- package/Tests/Samples/vcTransition1.json +0 -1
- package/Tests/Samples/vcTransition2.json +0 -1
- package/script/lint/airbnb.swiftformat +0 -68
- package/script/lint/swiftlint.yml +0 -38
- package/script/test-carthage/Carthage/Build/.lottie-ios.version +0 -19
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/Info.plist +0 -46
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/BCSymbolMaps/BF971162-BE99-3507-B5B3-11947DC6B176.bcsymbolmap +0 -14778
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Headers/Lottie-Swift.h +0 -673
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Info.plist +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Lottie +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/Lottie.framework/Modules/module.modulemap +0 -4
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/dSYMs/Lottie.framework.dSYM/Contents/Info.plist +0 -20
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64/dSYMs/Lottie.framework.dSYM/Contents/Resources/DWARF/Lottie +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Headers/Lottie-Swift.h +0 -1352
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Info.plist +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Lottie +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/arm64.swiftsourceinfo +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/Project/x86_64.swiftsourceinfo +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64-apple-ios-simulator.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/arm64.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64-apple-ios-simulator.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64.swiftdoc +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/Lottie.swiftmodule/x86_64.swiftmodule +0 -0
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/Modules/module.modulemap +0 -4
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/Lottie.framework/_CodeSignature/CodeResources +0 -256
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/dSYMs/Lottie.framework.dSYM/Contents/Info.plist +0 -20
- package/script/test-carthage/Carthage/Build/Lottie.xcframework/ios-arm64_x86_64-simulator/dSYMs/Lottie.framework.dSYM/Contents/Resources/DWARF/Lottie +0 -0
- package/script/test-carthage/Carthage/Checkouts/lottie-ios/Lottie.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/script/test-carthage/Carthage/Checkouts/lottie-ios/Lottie.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +0 -37
- package/script/test-carthage/Carthage/Checkouts/lottie-ios/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
|
@@ -17,6 +17,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
|
|
|
17
17
|
init(
|
|
18
18
|
animation: Animation,
|
|
19
19
|
imageProvider: AnimationImageProvider,
|
|
20
|
+
textProvider: AnimationTextProvider,
|
|
20
21
|
fontProvider: AnimationFontProvider,
|
|
21
22
|
compatibilityTrackerMode: CompatibilityTracker.Mode,
|
|
22
23
|
logger: LottieLogger)
|
|
@@ -24,6 +25,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
|
|
|
24
25
|
{
|
|
25
26
|
self.animation = animation
|
|
26
27
|
self.imageProvider = imageProvider
|
|
28
|
+
self.textProvider = textProvider
|
|
27
29
|
self.fontProvider = fontProvider
|
|
28
30
|
self.logger = logger
|
|
29
31
|
compatibilityTracker = CompatibilityTracker(mode: compatibilityTrackerMode, logger: logger)
|
|
@@ -44,6 +46,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
|
|
|
44
46
|
animation = typedLayer.animation
|
|
45
47
|
currentAnimationConfiguration = typedLayer.currentAnimationConfiguration
|
|
46
48
|
imageProvider = typedLayer.imageProvider
|
|
49
|
+
textProvider = typedLayer.textProvider
|
|
47
50
|
fontProvider = typedLayer.fontProvider
|
|
48
51
|
didSetUpAnimation = typedLayer.didSetUpAnimation
|
|
49
52
|
compatibilityTracker = typedLayer.compatibilityTracker
|
|
@@ -92,6 +95,16 @@ final class CoreAnimationLayer: BaseAnimationLayer {
|
|
|
92
95
|
didSet { reloadImages() }
|
|
93
96
|
}
|
|
94
97
|
|
|
98
|
+
/// The `AnimationTextProvider` that `TextLayer`'s use to retrieve texts,
|
|
99
|
+
/// that they should use to render their text context
|
|
100
|
+
var textProvider: AnimationTextProvider {
|
|
101
|
+
didSet {
|
|
102
|
+
// We need to rebuild the current animation after updating the text provider,
|
|
103
|
+
// since this is used in `TextLayer.setupAnimations(context:)`
|
|
104
|
+
rebuildCurrentAnimation()
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
/// The `FontProvider` that `TextLayer`s use to retrieve the `CTFont`
|
|
96
109
|
/// that they should use to render their text content
|
|
97
110
|
var fontProvider: AnimationFontProvider {
|
|
@@ -203,6 +216,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
|
|
|
203
216
|
LayerContext(
|
|
204
217
|
animation: animation,
|
|
205
218
|
imageProvider: imageProvider,
|
|
219
|
+
textProvider: textProvider,
|
|
206
220
|
fontProvider: fontProvider,
|
|
207
221
|
compatibilityTracker: compatibilityTracker,
|
|
208
222
|
layerName: "root layer")
|
|
@@ -234,6 +248,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
|
|
|
234
248
|
compatibilityTracker: compatibilityTracker,
|
|
235
249
|
logger: logger,
|
|
236
250
|
currentKeypath: AnimationKeypath(keys: []),
|
|
251
|
+
textProvider: textProvider,
|
|
237
252
|
logHierarchyKeypaths: configuration.logHierarchyKeypaths)
|
|
238
253
|
|
|
239
254
|
// Perform a layout pass if necessary so all of the sublayers
|
|
@@ -264,6 +279,11 @@ final class CoreAnimationLayer: BaseAnimationLayer {
|
|
|
264
279
|
|
|
265
280
|
let timedProgressAnimation = animationProgressTracker.timed(with: context, for: self)
|
|
266
281
|
timedProgressAnimation.delegate = currentAnimationConfiguration?.animationContext.closure
|
|
282
|
+
|
|
283
|
+
// Remove the progress animation once complete so we know when the animation
|
|
284
|
+
// has finished playing (if it doesn't loop infinitely)
|
|
285
|
+
timedProgressAnimation.isRemovedOnCompletion = true
|
|
286
|
+
|
|
267
287
|
add(timedProgressAnimation, forKey: #keyPath(animationProgress))
|
|
268
288
|
}
|
|
269
289
|
|
|
@@ -309,11 +329,18 @@ extension CoreAnimationLayer: RootAnimationLayer {
|
|
|
309
329
|
}
|
|
310
330
|
|
|
311
331
|
var isAnimationPlaying: Bool? {
|
|
312
|
-
switch playbackState {
|
|
332
|
+
switch pendingAnimationConfiguration?.playbackState {
|
|
313
333
|
case .playing:
|
|
314
334
|
return true
|
|
315
|
-
case
|
|
335
|
+
case .paused:
|
|
316
336
|
return false
|
|
337
|
+
case nil:
|
|
338
|
+
switch playbackState {
|
|
339
|
+
case .playing:
|
|
340
|
+
return animation(forKey: #keyPath(animationProgress)) != nil
|
|
341
|
+
case nil, .paused:
|
|
342
|
+
return false
|
|
343
|
+
}
|
|
317
344
|
}
|
|
318
345
|
}
|
|
319
346
|
|
|
@@ -378,15 +405,6 @@ extension CoreAnimationLayer: RootAnimationLayer {
|
|
|
378
405
|
(sublayers ?? []).filter { $0 is AnimationLayer }
|
|
379
406
|
}
|
|
380
407
|
|
|
381
|
-
var textProvider: AnimationTextProvider {
|
|
382
|
-
get { DictionaryTextProvider([:]) }
|
|
383
|
-
set {
|
|
384
|
-
logger.assertionFailure("""
|
|
385
|
-
The Core Animation rendering engine currently doesn't support `textProvider`s")
|
|
386
|
-
""")
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
408
|
func reloadImages() {
|
|
391
409
|
// When the image provider changes, we have to update all `ImageLayer`s
|
|
392
410
|
// so they can query the most up-to-date image from the new image provider.
|
|
@@ -23,7 +23,7 @@ extension KeyframeGroup {
|
|
|
23
23
|
fileID _: StaticString = #fileID,
|
|
24
24
|
line _: UInt = #line)
|
|
25
25
|
throws
|
|
26
|
-
->
|
|
26
|
+
-> T
|
|
27
27
|
{
|
|
28
28
|
try context.compatibilityAssert(
|
|
29
29
|
keyframes.count == 1,
|
|
@@ -32,6 +32,6 @@ extension KeyframeGroup {
|
|
|
32
32
|
for \(description) values (due to limitations of Core Animation `CAKeyframeAnimation`s).
|
|
33
33
|
""")
|
|
34
34
|
|
|
35
|
-
return keyframes[0]
|
|
35
|
+
return keyframes[0].value
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -4,34 +4,113 @@
|
|
|
4
4
|
// MARK: - Keyframes
|
|
5
5
|
|
|
6
6
|
enum Keyframes {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
|
|
8
|
+
// MARK: Internal
|
|
9
|
+
|
|
10
|
+
/// Combines the given keyframe groups of `Keyframe<T>`s into a single keyframe group of
|
|
11
|
+
/// of `Keyframe<[T]>`s if all of the `KeyframeGroup`s have the exact same animation timing
|
|
12
|
+
static func combinedIfPossible<T>(_ allGroups: [KeyframeGroup<T>]) -> KeyframeGroup<[T]>? {
|
|
13
|
+
combinedIfPossible(allGroups, makeCombinedResult: { index in
|
|
14
|
+
allGroups.map { $0.valueForCombinedKeyframes(at: index) }
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/// Combines the given keyframe groups of `Keyframe<T>`s into a single keyframe group of
|
|
19
|
+
/// of `Keyframe<[T]>`s if all of the `KeyframeGroup`s have the exact same animation timing
|
|
20
|
+
static func combinedIfPossible<T1, T2, CombinedResult>(
|
|
21
|
+
_ k1: KeyframeGroup<T1>,
|
|
22
|
+
_ k2: KeyframeGroup<T2>,
|
|
23
|
+
makeCombinedResult: (T1, T2) -> CombinedResult)
|
|
24
|
+
-> KeyframeGroup<CombinedResult>?
|
|
25
|
+
{
|
|
26
|
+
combinedIfPossible(
|
|
27
|
+
[k1, k2],
|
|
28
|
+
makeCombinedResult: { index in
|
|
29
|
+
makeCombinedResult(
|
|
30
|
+
k1.valueForCombinedKeyframes(at: index),
|
|
31
|
+
k2.valueForCombinedKeyframes(at: index))
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/// Combines the given keyframe groups of `Keyframe<T>`s into a single keyframe group of
|
|
36
|
+
/// of `Keyframe<[T]>`s if all of the `KeyframeGroup`s have the exact same animation timing
|
|
37
|
+
static func combinedIfPossible<T1, T2, T3, CombinedResult>(
|
|
38
|
+
_ k1: KeyframeGroup<T1>,
|
|
39
|
+
_ k2: KeyframeGroup<T2>,
|
|
40
|
+
_ k3: KeyframeGroup<T3>,
|
|
41
|
+
makeCombinedResult: (T1, T2, T3) -> CombinedResult)
|
|
42
|
+
-> KeyframeGroup<CombinedResult>?
|
|
43
|
+
{
|
|
44
|
+
combinedIfPossible(
|
|
45
|
+
[k1, k2, k3],
|
|
46
|
+
makeCombinedResult: { index in
|
|
47
|
+
makeCombinedResult(
|
|
48
|
+
k1.valueForCombinedKeyframes(at: index),
|
|
49
|
+
k2.valueForCombinedKeyframes(at: index),
|
|
50
|
+
k3.valueForCombinedKeyframes(at: index))
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// Combines the given keyframe groups of `Keyframe<T>`s into a single keyframe group of
|
|
55
|
+
/// of `Keyframe<[T]>`s if all of the `KeyframeGroup`s have the exact same animation timing
|
|
56
|
+
static func combinedIfPossible<T1, T2, T3, T4, T5, T6, T7, CombinedResult>(
|
|
57
|
+
_ k1: KeyframeGroup<T1>,
|
|
58
|
+
_ k2: KeyframeGroup<T2>,
|
|
59
|
+
_ k3: KeyframeGroup<T3>,
|
|
60
|
+
_ k4: KeyframeGroup<T4>,
|
|
61
|
+
_ k5: KeyframeGroup<T5>,
|
|
62
|
+
_ k6: KeyframeGroup<T6>,
|
|
63
|
+
_ k7: KeyframeGroup<T7>,
|
|
64
|
+
makeCombinedResult: (T1, T2, T3, T4, T5, T6, T7) -> CombinedResult)
|
|
65
|
+
-> KeyframeGroup<CombinedResult>?
|
|
66
|
+
{
|
|
67
|
+
combinedIfPossible(
|
|
68
|
+
[k1, k2, k3, k4, k5, k6, k7],
|
|
69
|
+
makeCombinedResult: { index in
|
|
70
|
+
makeCombinedResult(
|
|
71
|
+
k1.valueForCombinedKeyframes(at: index),
|
|
72
|
+
k2.valueForCombinedKeyframes(at: index),
|
|
73
|
+
k3.valueForCombinedKeyframes(at: index),
|
|
74
|
+
k4.valueForCombinedKeyframes(at: index),
|
|
75
|
+
k5.valueForCombinedKeyframes(at: index),
|
|
76
|
+
k6.valueForCombinedKeyframes(at: index),
|
|
77
|
+
k7.valueForCombinedKeyframes(at: index))
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// MARK: Private
|
|
82
|
+
|
|
83
|
+
/// Combines the given `[KeyframeGroup]` of `Keyframe<T>`s into a single `KeyframeGroup`
|
|
84
|
+
/// of `Keyframe<CombinedResult>`s if all of the `KeyframeGroup`s have the exact same animation timing
|
|
85
|
+
private static func combinedIfPossible<CombinedResult>(
|
|
86
|
+
_ allGroups: [AnyKeyframeGroup],
|
|
87
|
+
makeCombinedResult: (_ index: Int) -> CombinedResult)
|
|
88
|
+
-> KeyframeGroup<CombinedResult>?
|
|
89
|
+
{
|
|
90
|
+
let untypedGroups = allGroups.map { $0.untyped }
|
|
91
|
+
|
|
92
|
+
// Animations with no timing information (e.g. with just a single keyframe)
|
|
93
|
+
// can be trivially combined with any other set of keyframes, so we don't need
|
|
94
|
+
// to check those.
|
|
95
|
+
let animatingKeyframes = untypedGroups.filter { $0.keyframes.count > 1 }
|
|
96
|
+
|
|
11
97
|
guard
|
|
12
|
-
!
|
|
13
|
-
|
|
98
|
+
!allGroups.isEmpty,
|
|
99
|
+
animatingKeyframes.allSatisfy({ $0.hasSameTimingParameters(as: animatingKeyframes[0]) })
|
|
14
100
|
else { return nil }
|
|
15
101
|
|
|
16
|
-
var combinedKeyframes = ContiguousArray<Keyframe<
|
|
102
|
+
var combinedKeyframes = ContiguousArray<Keyframe<CombinedResult>>()
|
|
103
|
+
let baseKeyframes = (animatingKeyframes.first ?? untypedGroups[0]).keyframes
|
|
17
104
|
|
|
18
|
-
for index in
|
|
19
|
-
let baseKeyframe =
|
|
20
|
-
let
|
|
21
|
-
combinedKeyframes.append(baseKeyframe.withValue(
|
|
105
|
+
for index in baseKeyframes.indices {
|
|
106
|
+
let baseKeyframe = baseKeyframes[index]
|
|
107
|
+
let combinedValue = makeCombinedResult(index)
|
|
108
|
+
combinedKeyframes.append(baseKeyframe.withValue(combinedValue))
|
|
22
109
|
}
|
|
23
110
|
|
|
24
111
|
return KeyframeGroup(keyframes: combinedKeyframes)
|
|
25
112
|
}
|
|
26
113
|
|
|
27
|
-
/// Combines the given `[KeyframeGroup?]` of `Keyframe<T>`s
|
|
28
|
-
/// into a single `KeyframeGroup` of `Keyframe<[T]>`s
|
|
29
|
-
/// if all of the `KeyframeGroup`s have the exact same animation timing
|
|
30
|
-
static func combinedIfPossible<T>(_ groups: [KeyframeGroup<T>?]) -> KeyframeGroup<[T]>? {
|
|
31
|
-
let nonOptionalGroups = groups.compactMap { $0 }
|
|
32
|
-
guard nonOptionalGroups.count == groups.count else { return nil }
|
|
33
|
-
return combinedIfPossible(nonOptionalGroups)
|
|
34
|
-
}
|
|
35
114
|
}
|
|
36
115
|
|
|
37
116
|
extension KeyframeGroup {
|
|
@@ -49,13 +128,27 @@ extension KeyframeGroup {
|
|
|
49
128
|
}
|
|
50
129
|
|
|
51
130
|
extension Keyframe {
|
|
52
|
-
/// Whether or not this keyframe has the same timing parameters as the given keyframe
|
|
53
|
-
|
|
131
|
+
/// Whether or not this keyframe has the same timing parameters as the given keyframe,
|
|
132
|
+
/// excluding `spatialInTangent` and `spatialOutTangent`.
|
|
133
|
+
fileprivate func hasSameTimingParameters<T>(as other: Keyframe<T>) -> Bool {
|
|
54
134
|
time == other.time
|
|
55
135
|
&& isHold == other.isHold
|
|
56
136
|
&& inTangent == other.inTangent
|
|
57
137
|
&& outTangent == other.outTangent
|
|
58
|
-
|
|
59
|
-
|
|
138
|
+
// We intentionally don't compare spatial in/out tangents,
|
|
139
|
+
// since those values are only used in very specific cases
|
|
140
|
+
// (animating the x/y position of a layer), which aren't ever
|
|
141
|
+
// combined in this way.
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
extension KeyframeGroup {
|
|
146
|
+
/// The value to use for a combined set of keyframes, for the given index
|
|
147
|
+
fileprivate func valueForCombinedKeyframes(at index: Int) -> T {
|
|
148
|
+
if keyframes.count == 1 {
|
|
149
|
+
return keyframes[0].value
|
|
150
|
+
} else {
|
|
151
|
+
return keyframes[index].value
|
|
152
|
+
}
|
|
60
153
|
}
|
|
61
154
|
}
|
|
@@ -41,6 +41,9 @@ struct LayerAnimationContext {
|
|
|
41
41
|
/// The AnimationKeypath represented by the current layer
|
|
42
42
|
var currentKeypath: AnimationKeypath
|
|
43
43
|
|
|
44
|
+
/// The `AnimationTextProvider`
|
|
45
|
+
var textProvider: AnimationTextProvider
|
|
46
|
+
|
|
44
47
|
/// Whether or not to log `AnimationKeypath`s for all of the animation's layers
|
|
45
48
|
/// - Used for `CoreAnimationLayer.logHierarchyKeypaths()`
|
|
46
49
|
var logHierarchyKeypaths: Bool
|
|
@@ -63,6 +66,12 @@ struct LayerAnimationContext {
|
|
|
63
66
|
animation.progressTime(forFrame: timeRemapping(frame), clamped: false)
|
|
64
67
|
}
|
|
65
68
|
|
|
69
|
+
/// The real-time `TimeInterval` for the given `AnimationFrameTime` within this layer,
|
|
70
|
+
/// accounting for the `timeRemapping` applied to this layer
|
|
71
|
+
func time(for frame: AnimationFrameTime) -> TimeInterval {
|
|
72
|
+
animation.time(forFrame: timeRemapping(frame))
|
|
73
|
+
}
|
|
74
|
+
|
|
66
75
|
/// Chains an additional `timeRemapping` closure onto this layer context
|
|
67
76
|
func withTimeRemapping(
|
|
68
77
|
_ additionalTimeRemapping: @escaping (AnimationFrameTime) -> AnimationFrameTime)
|
|
@@ -78,7 +78,8 @@ class BaseCompositionLayer: BaseAnimationLayer {
|
|
|
78
78
|
private func setupSublayers() {
|
|
79
79
|
if
|
|
80
80
|
renderLayerContents,
|
|
81
|
-
let masks = baseLayerModel.masks
|
|
81
|
+
let masks = baseLayerModel.masks?.filter({ $0.mode != .none }),
|
|
82
|
+
!masks.isEmpty
|
|
82
83
|
{
|
|
83
84
|
mask = MaskCompositionLayer(masks: masks)
|
|
84
85
|
}
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
import QuartzCore
|
|
5
5
|
|
|
6
6
|
extension CALayer {
|
|
7
|
+
|
|
8
|
+
// MARK: Internal
|
|
9
|
+
|
|
7
10
|
/// Sets up an `AnimationLayer` / `CALayer` hierarchy in this layer,
|
|
8
11
|
/// using the given list of layers.
|
|
9
12
|
@nonobjc
|
|
@@ -48,7 +51,7 @@ extension CALayer {
|
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
// Create an `AnimationLayer` for each `LayerModel`
|
|
51
|
-
for (layerModel,
|
|
54
|
+
for (layerModel, mask) in try layersInZAxisOrder.pairedLayersAndMasks(context: context) {
|
|
52
55
|
guard let layer = try layerModel.makeAnimationLayer(context: context) else {
|
|
53
56
|
continue
|
|
54
57
|
}
|
|
@@ -64,14 +67,14 @@ extension CALayer {
|
|
|
64
67
|
|
|
65
68
|
// Create the `mask` layer for this layer, if it has a `MatteType`
|
|
66
69
|
if
|
|
67
|
-
let
|
|
68
|
-
let maskLayer = try
|
|
70
|
+
let mask = mask,
|
|
71
|
+
let maskLayer = try maskLayer(for: mask.model, type: mask.matteType, context: context)
|
|
69
72
|
{
|
|
70
73
|
let maskParentTransformLayer = makeParentTransformLayer(
|
|
71
|
-
childLayerModel:
|
|
74
|
+
childLayerModel: mask.model,
|
|
72
75
|
childLayer: maskLayer,
|
|
73
76
|
name: { parentLayerModel in
|
|
74
|
-
"\(
|
|
77
|
+
"\(mask.model.name) (mask of \(layerModel.name)) (parent, \(parentLayerModel.name))"
|
|
75
78
|
})
|
|
76
79
|
|
|
77
80
|
// Set up a parent container to host both the layer
|
|
@@ -96,6 +99,41 @@ extension CALayer {
|
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
101
|
|
|
102
|
+
// MARK: Fileprivate
|
|
103
|
+
|
|
104
|
+
/// Creates a mask `CALayer` from the given matte layer model, using the `MatteType`
|
|
105
|
+
/// from the layer that is being masked.
|
|
106
|
+
fileprivate func maskLayer(
|
|
107
|
+
for matteLayerModel: LayerModel,
|
|
108
|
+
type: MatteType,
|
|
109
|
+
context: LayerContext) throws
|
|
110
|
+
-> CALayer?
|
|
111
|
+
{
|
|
112
|
+
switch type {
|
|
113
|
+
case .add:
|
|
114
|
+
return try matteLayerModel.makeAnimationLayer(context: context)
|
|
115
|
+
|
|
116
|
+
case .invert:
|
|
117
|
+
guard let maskLayer = try matteLayerModel.makeAnimationLayer(context: context) else {
|
|
118
|
+
return nil
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// We can invert the mask layer by having a large solid black layer with the
|
|
122
|
+
// given mask layer subtracted out using the `xor` blend mode. When applied to the
|
|
123
|
+
// layer being masked, this creates an inverted mask where only areas _outside_
|
|
124
|
+
// of the mask layer are visible.
|
|
125
|
+
// https://developer.apple.com/documentation/coregraphics/cgblendmode/xor
|
|
126
|
+
let base = BaseAnimationLayer()
|
|
127
|
+
base.backgroundColor = .rgb(0, 0, 0)
|
|
128
|
+
base.addSublayer(maskLayer)
|
|
129
|
+
maskLayer.compositingFilter = "xor"
|
|
130
|
+
return base
|
|
131
|
+
|
|
132
|
+
case .none, .unknown:
|
|
133
|
+
return nil
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
99
137
|
}
|
|
100
138
|
|
|
101
139
|
extension Collection where Element == LayerModel {
|
|
@@ -103,8 +141,10 @@ extension Collection where Element == LayerModel {
|
|
|
103
141
|
/// a `LayerModel` to use as its mask, if applicable
|
|
104
142
|
/// based on the layer's `MatteType` configuration.
|
|
105
143
|
/// - Assumes the layers are sorted in z-axis order.
|
|
106
|
-
fileprivate func pairedLayersAndMasks(context: LayerContext) throws
|
|
107
|
-
|
|
144
|
+
fileprivate func pairedLayersAndMasks(context _: LayerContext) throws
|
|
145
|
+
-> [(layer: LayerModel, mask: (model: LayerModel, matteType: MatteType)?)]
|
|
146
|
+
{
|
|
147
|
+
var layersAndMasks = [(layer: LayerModel, mask: (model: LayerModel, matteType: MatteType)?)]()
|
|
108
148
|
var unprocessedLayers = reversed()
|
|
109
149
|
|
|
110
150
|
while let layer = unprocessedLayers.popLast() {
|
|
@@ -114,11 +154,7 @@ extension Collection where Element == LayerModel {
|
|
|
114
154
|
matteType != .none,
|
|
115
155
|
let maskLayer = unprocessedLayers.popLast()
|
|
116
156
|
{
|
|
117
|
-
|
|
118
|
-
matteType == .add,
|
|
119
|
-
"The Core Animation rendering engine currently only supports `MatteMode.add`.")
|
|
120
|
-
|
|
121
|
-
layersAndMasks.append((layer: layer, mask: maskLayer))
|
|
157
|
+
layersAndMasks.append((layer: layer, mask: (model: maskLayer, matteType: matteType)))
|
|
122
158
|
}
|
|
123
159
|
|
|
124
160
|
else {
|
|
@@ -59,7 +59,7 @@ final class GradientRenderLayer: CAGradientLayer {
|
|
|
59
59
|
/// - This specific value is arbitrary and can be increased if necessary.
|
|
60
60
|
/// Theoretically this should be "infinite", to match the behavior of
|
|
61
61
|
/// `CGContext.drawLinearGradient` with `[.drawsAfterEndLocation, .drawsBeforeStartLocation]`.
|
|
62
|
-
private let gradientPadding: CGFloat =
|
|
62
|
+
private let gradientPadding: CGFloat = 10_000
|
|
63
63
|
|
|
64
64
|
private func updateLayout() {
|
|
65
65
|
anchorPoint = .zero
|
|
@@ -70,9 +70,12 @@ final class GradientRenderLayer: CAGradientLayer {
|
|
|
70
70
|
width: gradientPadding + gradientReferenceBounds.width + gradientPadding,
|
|
71
71
|
height: gradientPadding + gradientReferenceBounds.height + gradientPadding)
|
|
72
72
|
|
|
73
|
+
// Align the center of this layer to be at the center point of its parent layer
|
|
74
|
+
let superlayerSize = superlayer?.frame.size ?? gradientReferenceBounds.size
|
|
75
|
+
|
|
73
76
|
transform = CATransform3DMakeTranslation(
|
|
74
|
-
-
|
|
75
|
-
-
|
|
77
|
+
(superlayerSize.width - bounds.width) / 2,
|
|
78
|
+
(superlayerSize.height - bounds.height) / 2,
|
|
76
79
|
0)
|
|
77
80
|
}
|
|
78
81
|
|
|
@@ -83,5 +86,9 @@ final class GradientRenderLayer: CAGradientLayer {
|
|
|
83
86
|
extension GradientRenderLayer: CustomLayoutLayer {
|
|
84
87
|
func layout(superlayerBounds: CGRect) {
|
|
85
88
|
gradientReferenceBounds = superlayerBounds
|
|
89
|
+
|
|
90
|
+
if let gradientMask = mask as? GradientRenderLayer {
|
|
91
|
+
gradientMask.layout(superlayerBounds: superlayerBounds)
|
|
92
|
+
}
|
|
86
93
|
}
|
|
87
94
|
}
|
|
@@ -9,6 +9,7 @@ import QuartzCore
|
|
|
9
9
|
struct LayerContext {
|
|
10
10
|
let animation: Animation
|
|
11
11
|
let imageProvider: AnimationImageProvider
|
|
12
|
+
let textProvider: AnimationTextProvider
|
|
12
13
|
let fontProvider: AnimationFontProvider
|
|
13
14
|
let compatibilityTracker: CompatibilityTracker
|
|
14
15
|
var layerName: String
|
|
@@ -27,6 +28,10 @@ extension LayerModel {
|
|
|
27
28
|
func makeAnimationLayer(context: LayerContext) throws -> BaseCompositionLayer? {
|
|
28
29
|
let context = context.forLayer(self)
|
|
29
30
|
|
|
31
|
+
if hidden {
|
|
32
|
+
return TransformLayer(layerModel: self)
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
switch (type, self) {
|
|
31
36
|
case (.precomp, let preCompLayerModel as PreCompLayerModel):
|
|
32
37
|
let preCompLayer = PreCompLayer(preCompLayer: preCompLayerModel)
|
|
@@ -68,12 +68,12 @@ final class PreCompLayer: BaseCompositionLayer {
|
|
|
68
68
|
try setupLayerAnimations(context: context)
|
|
69
69
|
|
|
70
70
|
// Precomp layers can adjust the local time of their child layers (relative to the
|
|
71
|
-
// animation's global time) via `timeRemapping` or a custom `startTime`
|
|
71
|
+
// animation's global time) via `timeRemapping` or a custom `startTime` / `timeStretch`
|
|
72
72
|
let contextForChildren = context.withTimeRemapping { [preCompLayer, timeRemappingInterpolator] layerLocalFrame in
|
|
73
73
|
if let timeRemappingInterpolator = timeRemappingInterpolator {
|
|
74
74
|
return timeRemappingInterpolator.value(frame: layerLocalFrame) as? AnimationFrameTime ?? layerLocalFrame
|
|
75
75
|
} else {
|
|
76
|
-
return layerLocalFrame + AnimationFrameTime(preCompLayer.startTime)
|
|
76
|
+
return (layerLocalFrame * AnimationFrameTime(preCompLayer.timeStretch)) + AnimationFrameTime(preCompLayer.startTime)
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Created by Cal Stephens on 8/1/22.
|
|
2
|
+
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
|
3
|
+
|
|
4
|
+
import QuartzCore
|
|
5
|
+
|
|
6
|
+
// MARK: - RepeaterLayer
|
|
7
|
+
|
|
8
|
+
/// A layer that renders a child layer at some offset using a `Repeater`
|
|
9
|
+
final class RepeaterLayer: BaseAnimationLayer {
|
|
10
|
+
|
|
11
|
+
// MARK: Lifecycle
|
|
12
|
+
|
|
13
|
+
init(repeater: Repeater, childLayer: CALayer, index: Int) {
|
|
14
|
+
repeaterTransform = RepeaterTransform(repeater: repeater, index: index)
|
|
15
|
+
super.init()
|
|
16
|
+
addSublayer(childLayer)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
required init?(coder _: NSCoder) {
|
|
20
|
+
fatalError("init(coder:) has not been implemented")
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// Called by CoreAnimation to create a shadow copy of this layer
|
|
24
|
+
/// More details: https://developer.apple.com/documentation/quartzcore/calayer/1410842-init
|
|
25
|
+
override init(layer: Any) {
|
|
26
|
+
guard let typedLayer = layer as? Self else {
|
|
27
|
+
fatalError("\(Self.self).init(layer:) incorrectly called with \(type(of: layer))")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
repeaterTransform = typedLayer.repeaterTransform
|
|
31
|
+
super.init(layer: typedLayer)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// MARK: Internal
|
|
35
|
+
|
|
36
|
+
override func setupAnimations(context: LayerAnimationContext) throws {
|
|
37
|
+
try super.setupAnimations(context: context)
|
|
38
|
+
try addTransformAnimations(for: repeaterTransform, context: context)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// MARK: Private
|
|
42
|
+
|
|
43
|
+
private let repeaterTransform: RepeaterTransform
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// MARK: - RepeaterTransform
|
|
48
|
+
|
|
49
|
+
/// A transform model created from a `Repeater`
|
|
50
|
+
private struct RepeaterTransform {
|
|
51
|
+
|
|
52
|
+
// MARK: Lifecycle
|
|
53
|
+
|
|
54
|
+
init(repeater: Repeater, index: Int) {
|
|
55
|
+
anchorPoint = repeater.anchorPoint
|
|
56
|
+
scale = repeater.scale
|
|
57
|
+
|
|
58
|
+
rotation = repeater.rotation.map { rotation in
|
|
59
|
+
Vector1D(rotation.value * Double(index))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
position = repeater.position.map { position in
|
|
63
|
+
Vector3D(
|
|
64
|
+
x: position.x * Double(index),
|
|
65
|
+
y: position.y * Double(index),
|
|
66
|
+
z: position.z * Double(index))
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// MARK: Internal
|
|
71
|
+
|
|
72
|
+
let anchorPoint: KeyframeGroup<Vector3D>
|
|
73
|
+
let position: KeyframeGroup<Vector3D>
|
|
74
|
+
let rotation: KeyframeGroup<Vector1D>
|
|
75
|
+
let scale: KeyframeGroup<Vector3D>
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// MARK: TransformModel
|
|
80
|
+
|
|
81
|
+
extension RepeaterTransform: TransformModel {
|
|
82
|
+
var _position: KeyframeGroup<Vector3D>? { position }
|
|
83
|
+
var _positionX: KeyframeGroup<Vector1D>? { nil }
|
|
84
|
+
var _positionY: KeyframeGroup<Vector1D>? { nil }
|
|
85
|
+
}
|