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
|
@@ -55,8 +55,13 @@ final class ShapeItemLayer: BaseAnimationLayer {
|
|
|
55
55
|
/// A `ShapeItem` that should be rendered by this layer
|
|
56
56
|
let item: ShapeItem
|
|
57
57
|
|
|
58
|
-
/// The
|
|
59
|
-
|
|
58
|
+
/// The set of groups that this item descends from
|
|
59
|
+
/// - Due to the way `GroupLayer`s are setup, the original `ShapeItem`
|
|
60
|
+
/// hierarchy from the `ShapeLayer` data model may no longer exactly
|
|
61
|
+
/// match the hierarchy of `GroupLayer` / `ShapeItemLayer`s constructed
|
|
62
|
+
/// at runtime. Since animation keypaths need to match the original
|
|
63
|
+
/// structure of the `ShapeLayer` data model, we track that info here.
|
|
64
|
+
let groupPath: [String]
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
override func setupAnimations(context: LayerAnimationContext) throws {
|
|
@@ -69,27 +74,24 @@ final class ShapeItemLayer: BaseAnimationLayer {
|
|
|
69
74
|
try setupSolidFillAnimations(shapeLayer: shapeLayer, context: context)
|
|
70
75
|
|
|
71
76
|
case .gradientFill(let gradientLayers):
|
|
72
|
-
try setupGradientFillAnimations(
|
|
73
|
-
gradientLayer: gradientLayers.gradientLayer,
|
|
74
|
-
maskLayer: gradientLayers.maskLayer,
|
|
75
|
-
context: context)
|
|
77
|
+
try setupGradientFillAnimations(layers: gradientLayers, context: context)
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
if let gradientStrokeConfiguration = sublayerConfiguration.gradientStroke {
|
|
79
|
-
try setupGradientStrokeAnimations(
|
|
80
|
-
gradientLayer: gradientStrokeConfiguration.gradientLayer,
|
|
81
|
-
maskLayer: gradientStrokeConfiguration.maskLayer,
|
|
82
|
-
context: context)
|
|
81
|
+
try setupGradientStrokeAnimations(layers: gradientStrokeConfiguration, context: context)
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
// MARK: Private
|
|
87
86
|
|
|
88
87
|
private struct GradientLayers {
|
|
89
|
-
/// The `CALayer` that renders the
|
|
90
|
-
let
|
|
91
|
-
/// The `
|
|
92
|
-
|
|
88
|
+
/// The `CALayer` that renders the RGB components of the gradient
|
|
89
|
+
let gradientColorLayer: GradientRenderLayer
|
|
90
|
+
/// The `CALayer` that renders the alpha components of the gradient,
|
|
91
|
+
/// masking the `gradientColorLayer`
|
|
92
|
+
let gradientAlphaLayer: GradientRenderLayer?
|
|
93
|
+
/// The `CAShapeLayer` that clips the gradient layers to the expected shape
|
|
94
|
+
let shapeMaskLayer: CAShapeLayer
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
/// The configuration of this layer's `fill` sublayers
|
|
@@ -115,15 +117,15 @@ final class ShapeItemLayer: BaseAnimationLayer {
|
|
|
115
117
|
// we're rendering a gradient (a `CAGradientLayer` masked by a `CAShapeLayer`)
|
|
116
118
|
// or a solid shape (a simple `CAShapeLayer`).
|
|
117
119
|
let fillLayerConfiguration: FillLayerConfiguration
|
|
118
|
-
if otherItems.
|
|
119
|
-
fillLayerConfiguration = setupGradientFillLayerHierarchy()
|
|
120
|
+
if let gradientFill = otherItems.first(GradientFill.self) {
|
|
121
|
+
fillLayerConfiguration = setupGradientFillLayerHierarchy(for: gradientFill)
|
|
120
122
|
} else {
|
|
121
123
|
fillLayerConfiguration = setupSolidFillLayerHierarchy()
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
let gradientStrokeConfiguration: GradientLayers?
|
|
125
|
-
if otherItems.
|
|
126
|
-
gradientStrokeConfiguration = setupGradientStrokeLayerHierarchy()
|
|
127
|
+
if let gradientStroke = otherItems.first(GradientStroke.self) {
|
|
128
|
+
gradientStrokeConfiguration = setupGradientStrokeLayerHierarchy(for: gradientStroke)
|
|
127
129
|
} else {
|
|
128
130
|
gradientStrokeConfiguration = nil
|
|
129
131
|
}
|
|
@@ -144,18 +146,35 @@ final class ShapeItemLayer: BaseAnimationLayer {
|
|
|
144
146
|
return .solidFill(shapeLayer)
|
|
145
147
|
}
|
|
146
148
|
|
|
147
|
-
private func setupGradientFillLayerHierarchy(
|
|
149
|
+
private func setupGradientFillLayerHierarchy(
|
|
150
|
+
for gradientFill: GradientFill)
|
|
151
|
+
-> FillLayerConfiguration
|
|
152
|
+
{
|
|
148
153
|
let pathMask = CAShapeLayer()
|
|
149
154
|
pathMask.fillColor = .rgb(0, 0, 0)
|
|
150
155
|
mask = pathMask
|
|
151
156
|
|
|
152
|
-
let
|
|
153
|
-
addSublayer(
|
|
157
|
+
let rgbGradientLayer = GradientRenderLayer()
|
|
158
|
+
addSublayer(rgbGradientLayer)
|
|
154
159
|
|
|
155
|
-
|
|
160
|
+
let alphaGradientLayer: GradientRenderLayer?
|
|
161
|
+
if gradientFill.hasAlphaComponent {
|
|
162
|
+
alphaGradientLayer = GradientRenderLayer()
|
|
163
|
+
rgbGradientLayer.mask = alphaGradientLayer
|
|
164
|
+
} else {
|
|
165
|
+
alphaGradientLayer = nil
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return .gradientFill(GradientLayers(
|
|
169
|
+
gradientColorLayer: rgbGradientLayer,
|
|
170
|
+
gradientAlphaLayer: alphaGradientLayer,
|
|
171
|
+
shapeMaskLayer: pathMask))
|
|
156
172
|
}
|
|
157
173
|
|
|
158
|
-
private func setupGradientStrokeLayerHierarchy(
|
|
174
|
+
private func setupGradientStrokeLayerHierarchy(
|
|
175
|
+
for gradientStroke: GradientStroke)
|
|
176
|
+
-> GradientLayers
|
|
177
|
+
{
|
|
159
178
|
let container = BaseAnimationLayer()
|
|
160
179
|
|
|
161
180
|
let pathMask = CAShapeLayer()
|
|
@@ -163,11 +182,22 @@ final class ShapeItemLayer: BaseAnimationLayer {
|
|
|
163
182
|
pathMask.strokeColor = .rgb(0, 0, 0)
|
|
164
183
|
container.mask = pathMask
|
|
165
184
|
|
|
166
|
-
let
|
|
167
|
-
container.addSublayer(
|
|
185
|
+
let rgbGradientLayer = GradientRenderLayer()
|
|
186
|
+
container.addSublayer(rgbGradientLayer)
|
|
168
187
|
addSublayer(container)
|
|
169
188
|
|
|
170
|
-
|
|
189
|
+
let alphaGradientLayer: GradientRenderLayer?
|
|
190
|
+
if gradientStroke.hasAlphaComponent {
|
|
191
|
+
alphaGradientLayer = GradientRenderLayer()
|
|
192
|
+
rgbGradientLayer.mask = alphaGradientLayer
|
|
193
|
+
} else {
|
|
194
|
+
alphaGradientLayer = nil
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return GradientLayers(
|
|
198
|
+
gradientColorLayer: rgbGradientLayer,
|
|
199
|
+
gradientAlphaLayer: alphaGradientLayer,
|
|
200
|
+
shapeMaskLayer: pathMask)
|
|
171
201
|
}
|
|
172
202
|
|
|
173
203
|
private func setupSolidFillAnimations(
|
|
@@ -178,6 +208,13 @@ final class ShapeItemLayer: BaseAnimationLayer {
|
|
|
178
208
|
var trimPathMultiplier: PathMultiplier? = nil
|
|
179
209
|
if let (trim, context) = otherItems.first(Trim.self, context: context) {
|
|
180
210
|
trimPathMultiplier = try shapeLayer.addAnimations(for: trim, context: context)
|
|
211
|
+
|
|
212
|
+
try context.compatibilityAssert(
|
|
213
|
+
otherItems.first(Fill.self) == nil,
|
|
214
|
+
"""
|
|
215
|
+
The Core Animation rendering engine doesn't currently support applying
|
|
216
|
+
trims to filled shapes (only stroked shapes).
|
|
217
|
+
""")
|
|
181
218
|
}
|
|
182
219
|
|
|
183
220
|
try shapeLayer.addAnimations(for: shape.item, context: context.for(shape), pathMultiplier: trimPathMultiplier ?? 1)
|
|
@@ -192,34 +229,42 @@ final class ShapeItemLayer: BaseAnimationLayer {
|
|
|
192
229
|
}
|
|
193
230
|
|
|
194
231
|
private func setupGradientFillAnimations(
|
|
195
|
-
|
|
196
|
-
maskLayer: CAShapeLayer,
|
|
232
|
+
layers: GradientLayers,
|
|
197
233
|
context: LayerAnimationContext)
|
|
198
234
|
throws
|
|
199
235
|
{
|
|
200
|
-
try
|
|
236
|
+
try layers.shapeMaskLayer.addAnimations(
|
|
237
|
+
for: shape.item,
|
|
238
|
+
context: context.for(shape),
|
|
239
|
+
pathMultiplier: 1)
|
|
201
240
|
|
|
202
241
|
if let (gradientFill, context) = otherItems.first(GradientFill.self, context: context) {
|
|
203
|
-
|
|
242
|
+
layers.shapeMaskLayer.fillRule = gradientFill.fillRule.caFillRule
|
|
243
|
+
try layers.gradientColorLayer.addGradientAnimations(for: gradientFill, type: .rgb, context: context)
|
|
244
|
+
try layers.gradientAlphaLayer?.addGradientAnimations(for: gradientFill, type: .alpha, context: context)
|
|
204
245
|
}
|
|
205
246
|
}
|
|
206
247
|
|
|
207
248
|
private func setupGradientStrokeAnimations(
|
|
208
|
-
|
|
209
|
-
maskLayer: CAShapeLayer,
|
|
249
|
+
layers: GradientLayers,
|
|
210
250
|
context: LayerAnimationContext)
|
|
211
251
|
throws
|
|
212
252
|
{
|
|
213
253
|
var trimPathMultiplier: PathMultiplier? = nil
|
|
214
254
|
if let (trim, context) = otherItems.first(Trim.self, context: context) {
|
|
215
|
-
trimPathMultiplier = try
|
|
255
|
+
trimPathMultiplier = try layers.shapeMaskLayer.addAnimations(for: trim, context: context)
|
|
216
256
|
}
|
|
217
257
|
|
|
218
|
-
try
|
|
258
|
+
try layers.shapeMaskLayer.addAnimations(
|
|
259
|
+
for: shape.item,
|
|
260
|
+
context: context.for(shape),
|
|
261
|
+
pathMultiplier: trimPathMultiplier ?? 1)
|
|
219
262
|
|
|
220
263
|
if let (gradientStroke, context) = otherItems.first(GradientStroke.self, context: context) {
|
|
221
|
-
try
|
|
222
|
-
try
|
|
264
|
+
try layers.gradientColorLayer.addGradientAnimations(for: gradientStroke, type: .rgb, context: context)
|
|
265
|
+
try layers.gradientAlphaLayer?.addGradientAnimations(for: gradientStroke, type: .alpha, context: context)
|
|
266
|
+
|
|
267
|
+
try layers.shapeMaskLayer.addStrokeAnimations(for: gradientStroke, context: context)
|
|
223
268
|
}
|
|
224
269
|
}
|
|
225
270
|
|
|
@@ -241,6 +286,17 @@ extension Array where Element == ShapeItemLayer.Item {
|
|
|
241
286
|
|
|
242
287
|
return nil
|
|
243
288
|
}
|
|
289
|
+
|
|
290
|
+
/// The first `ShapeItem` in this array of the given type
|
|
291
|
+
func first<ItemType: ShapeItem>(_: ItemType.Type) -> ItemType? {
|
|
292
|
+
for item in self {
|
|
293
|
+
if let match = item.item as? ItemType {
|
|
294
|
+
return match
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return nil
|
|
299
|
+
}
|
|
244
300
|
}
|
|
245
301
|
|
|
246
302
|
extension LayerAnimationContext {
|
|
@@ -249,8 +305,8 @@ extension LayerAnimationContext {
|
|
|
249
305
|
func `for`(_ item: ShapeItemLayer.Item) -> LayerAnimationContext {
|
|
250
306
|
var context = self
|
|
251
307
|
|
|
252
|
-
|
|
253
|
-
context.currentKeypath.keys.append(
|
|
308
|
+
for parentGroupName in item.groupPath {
|
|
309
|
+
context.currentKeypath.keys.append(parentGroupName)
|
|
254
310
|
}
|
|
255
311
|
|
|
256
312
|
context.currentKeypath.keys.append(item.item.name)
|
|
@@ -13,7 +13,7 @@ final class ShapeLayer: BaseCompositionLayer {
|
|
|
13
13
|
init(shapeLayer: ShapeLayerModel, context: LayerContext) throws {
|
|
14
14
|
self.shapeLayer = shapeLayer
|
|
15
15
|
super.init(layerModel: shapeLayer)
|
|
16
|
-
try
|
|
16
|
+
try setUpGroups(context: context)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
required init?(coder _: NSCoder) {
|
|
@@ -35,6 +35,28 @@ final class ShapeLayer: BaseCompositionLayer {
|
|
|
35
35
|
|
|
36
36
|
private let shapeLayer: ShapeLayerModel
|
|
37
37
|
|
|
38
|
+
private func setUpGroups(context: LayerContext) throws {
|
|
39
|
+
// If the layer has a `Repeater`, the `Group`s are duplicated and offset
|
|
40
|
+
// based on the copy count of the repeater.
|
|
41
|
+
if let repeater = shapeLayer.items.first(where: { $0 is Repeater }) as? Repeater {
|
|
42
|
+
try setUpRepeater(repeater, context: context)
|
|
43
|
+
} else {
|
|
44
|
+
try setupGroups(from: shapeLayer.items, parentGroup: nil, parentGroupPath: [], context: context)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private func setUpRepeater(_ repeater: Repeater, context: LayerContext) throws {
|
|
49
|
+
let items = shapeLayer.items.filter { !($0 is Repeater) }
|
|
50
|
+
let copyCount = Int(try repeater.copies.exactlyOneKeyframe(context: context, description: "repeater copies").value)
|
|
51
|
+
|
|
52
|
+
for index in 0..<copyCount {
|
|
53
|
+
for groupLayer in try makeGroupLayers(from: items, parentGroup: nil, parentGroupPath: [], context: context) {
|
|
54
|
+
let repeatedLayer = RepeaterLayer(repeater: repeater, childLayer: groupLayer, index: index)
|
|
55
|
+
addSublayer(repeatedLayer)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
38
60
|
}
|
|
39
61
|
|
|
40
62
|
// MARK: - GroupLayer
|
|
@@ -44,9 +66,10 @@ final class GroupLayer: BaseAnimationLayer {
|
|
|
44
66
|
|
|
45
67
|
// MARK: Lifecycle
|
|
46
68
|
|
|
47
|
-
init(group: Group,
|
|
69
|
+
init(group: Group, items: [ShapeItemLayer.Item], groupPath: [String], context: LayerContext) throws {
|
|
48
70
|
self.group = group
|
|
49
|
-
self.
|
|
71
|
+
self.items = items
|
|
72
|
+
self.groupPath = groupPath
|
|
50
73
|
super.init()
|
|
51
74
|
try setupLayerHierarchy(context: context)
|
|
52
75
|
}
|
|
@@ -63,7 +86,8 @@ final class GroupLayer: BaseAnimationLayer {
|
|
|
63
86
|
}
|
|
64
87
|
|
|
65
88
|
group = typedLayer.group
|
|
66
|
-
|
|
89
|
+
items = typedLayer.items
|
|
90
|
+
groupPath = typedLayer.groupPath
|
|
67
91
|
super.init(layer: typedLayer)
|
|
68
92
|
}
|
|
69
93
|
|
|
@@ -82,46 +106,62 @@ final class GroupLayer: BaseAnimationLayer {
|
|
|
82
106
|
|
|
83
107
|
private let group: Group
|
|
84
108
|
|
|
85
|
-
/// `
|
|
86
|
-
///
|
|
87
|
-
private let
|
|
109
|
+
/// `ShapeItemLayer.Item`s rendered by this `Group`
|
|
110
|
+
/// - In the original `ShapeLayer` data model, these items could have originated from a different group
|
|
111
|
+
private let items: [ShapeItemLayer.Item]
|
|
112
|
+
|
|
113
|
+
/// The keypath that represents this group, with respect to the parent `ShapeLayer`
|
|
114
|
+
/// - Due to the way `GroupLayer`s are setup, the original `ShapeItem`
|
|
115
|
+
/// hierarchy from the `ShapeLayer` data model may no longer exactly
|
|
116
|
+
/// match the hierarchy of `GroupLayer` / `ShapeItemLayer`s constructed
|
|
117
|
+
/// at runtime. Since animation keypaths need to match the original
|
|
118
|
+
/// structure of the `ShapeLayer` data model, we track that info here.
|
|
119
|
+
private let groupPath: [String]
|
|
88
120
|
|
|
89
|
-
/// `ShapeItem`s (other than nested `Group`s) that are
|
|
90
|
-
private lazy var nonGroupItems =
|
|
91
|
-
.filter { !($0 is Group) }
|
|
92
|
-
.map { ShapeItemLayer.Item(item: $0, parentGroup: group) }
|
|
93
|
-
+ inheritedItems
|
|
121
|
+
/// `ShapeItem`s (other than nested `Group`s) that are rendered by this layer
|
|
122
|
+
private lazy var nonGroupItems = items.filter { !($0.item is Group) }
|
|
94
123
|
|
|
95
124
|
private func setupLayerHierarchy(context: LayerContext) throws {
|
|
96
125
|
// Groups can contain other groups, so we may have to continue
|
|
97
126
|
// recursively creating more `GroupLayer`s
|
|
98
|
-
try setupGroups(from: group.items, parentGroup: group, context: context)
|
|
127
|
+
try setupGroups(from: group.items, parentGroup: group, parentGroupPath: groupPath, context: context)
|
|
99
128
|
|
|
100
129
|
// Create `ShapeItemLayer`s for each subgroup of shapes that should be rendered as a single unit
|
|
101
130
|
// - These groups are listed from front-to-back, so we have to add the sublayers in reverse order
|
|
102
131
|
for shapeRenderGroup in nonGroupItems.shapeRenderGroups.reversed() {
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
// because combining multiple paths into a single `CGPath` (instead of rendering them in separate layers)
|
|
109
|
-
// allows `CAShapeLayerFillRule.evenOdd` to be applied if the paths overlap. We just can't do this
|
|
110
|
-
// in all cases, due to limitations of Core Animation.
|
|
132
|
+
// When there are multiple path-drawing items, they're supposed to be rendered
|
|
133
|
+
// in a single `CAShapeLayer` (instead of rendering them in separate layers) so
|
|
134
|
+
// `CAShapeLayerFillRule.evenOdd` can be applied correctly if the paths overlap.
|
|
135
|
+
// Since a `CAShapeLayer` only supports animating a single `CGPath` from a single `KeyframeGroup<BezierPath>`,
|
|
136
|
+
// this requires combining all of the path-drawing items into a single set of keyframes.
|
|
111
137
|
if
|
|
112
138
|
shapeRenderGroup.pathItems.count > 1,
|
|
113
|
-
|
|
114
|
-
|
|
139
|
+
// We currently only support this codepath for `Shape` items that directly contain bezier path keyframes.
|
|
140
|
+
// We could also support this for other path types like rectangles, ellipses, and polygons with more work.
|
|
141
|
+
shapeRenderGroup.pathItems.allSatisfy({ $0.item is Shape }),
|
|
115
142
|
// `Trim`s are currently only applied correctly using individual `ShapeItemLayer`s,
|
|
116
143
|
// because each path has to be trimmed separately.
|
|
117
144
|
!shapeRenderGroup.otherItems.contains(where: { $0.item is Trim })
|
|
118
145
|
{
|
|
119
|
-
let
|
|
120
|
-
|
|
121
|
-
|
|
146
|
+
let allPathKeyframes = shapeRenderGroup.pathItems.compactMap { ($0.item as? Shape)?.path }
|
|
147
|
+
let combinedShape: CombinedShapeItem
|
|
148
|
+
|
|
149
|
+
// If all of the path-drawing `ShapeItem`s have keyframes with the same timing information,
|
|
150
|
+
// we can combine the `[KeyframeGroup<BezierPath>]` (which have to animate in separate layers)
|
|
151
|
+
// into a single `KeyframeGroup<[BezierPath]>`, which can be combined into a single CGPath animation.
|
|
152
|
+
if let combinedShapeKeyframes = Keyframes.combinedIfPossible(allPathKeyframes) {
|
|
153
|
+
combinedShape = CombinedShapeItem(shapes: combinedShapeKeyframes, name: group.name)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Otherwise, in order for the path fills to be rendered correctly, we have to manually
|
|
157
|
+
// interpolate the path for each shape at each frame ahead of time so we can combine them
|
|
158
|
+
// into a single set of bezier path keyframes.
|
|
159
|
+
else {
|
|
160
|
+
combinedShape = .manuallyInterpolating(shapes: allPathKeyframes, name: group.name, context: context)
|
|
161
|
+
}
|
|
122
162
|
|
|
123
163
|
let sublayer = try ShapeItemLayer(
|
|
124
|
-
shape: ShapeItemLayer.Item(item: combinedShape,
|
|
164
|
+
shape: ShapeItemLayer.Item(item: combinedShape, groupPath: shapeRenderGroup.pathItems[0].groupPath),
|
|
125
165
|
otherItems: shapeRenderGroup.otherItems,
|
|
126
166
|
context: context)
|
|
127
167
|
|
|
@@ -129,7 +169,8 @@ final class GroupLayer: BaseAnimationLayer {
|
|
|
129
169
|
}
|
|
130
170
|
|
|
131
171
|
// Otherwise, if each `ShapeItem` that draws a `GGPath` animates independently,
|
|
132
|
-
// we have to create a separate `ShapeItemLayer` for each one.
|
|
172
|
+
// we have to create a separate `ShapeItemLayer` for each one. This may render
|
|
173
|
+
// incorrectly if there are multiple paths that overlap with each other.
|
|
133
174
|
else {
|
|
134
175
|
for pathDrawingItem in shapeRenderGroup.pathItems {
|
|
135
176
|
let sublayer = try ShapeItemLayer(
|
|
@@ -149,34 +190,78 @@ extension CALayer {
|
|
|
149
190
|
/// Sets up `GroupLayer`s for each `Group` in the given list of `ShapeItem`s
|
|
150
191
|
/// - Each `Group` item becomes its own `GroupLayer` sublayer.
|
|
151
192
|
/// - Other `ShapeItem` are applied to all sublayers
|
|
152
|
-
fileprivate func setupGroups(
|
|
153
|
-
|
|
193
|
+
fileprivate func setupGroups(
|
|
194
|
+
from items: [ShapeItem],
|
|
195
|
+
parentGroup: Group?,
|
|
196
|
+
parentGroupPath: [String],
|
|
197
|
+
context: LayerContext) throws
|
|
198
|
+
{
|
|
199
|
+
let groupLayers = try makeGroupLayers(
|
|
200
|
+
from: items,
|
|
201
|
+
parentGroup: parentGroup,
|
|
202
|
+
parentGroupPath: parentGroupPath,
|
|
203
|
+
context: context)
|
|
204
|
+
|
|
205
|
+
for groupLayer in groupLayers {
|
|
206
|
+
addSublayer(groupLayer)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/// Creates a `GroupLayer` for each `Group` in the given list of `ShapeItem`s
|
|
211
|
+
/// - Each `Group` item becomes its own `GroupLayer` sublayer.
|
|
212
|
+
/// - Other `ShapeItem` are applied to all sublayers
|
|
213
|
+
fileprivate func makeGroupLayers(
|
|
214
|
+
from items: [ShapeItem],
|
|
215
|
+
parentGroup: Group?,
|
|
216
|
+
parentGroupPath: [String],
|
|
217
|
+
context: LayerContext) throws
|
|
218
|
+
-> [GroupLayer]
|
|
219
|
+
{
|
|
220
|
+
var (groupItems, otherItems) = items
|
|
221
|
+
.filter { !$0.hidden }
|
|
222
|
+
.grouped(by: { $0 is Group })
|
|
223
|
+
|
|
224
|
+
// If this shape doesn't have any groups but just has top-level shape items,
|
|
225
|
+
// we can create a placeholder group with those items. (Otherwise the shape items
|
|
226
|
+
// would be silently ignored, since we expect all shape layers to have a top-level group).
|
|
227
|
+
if groupItems.isEmpty, parentGroup == nil {
|
|
228
|
+
groupItems = [Group(items: otherItems, name: "")]
|
|
229
|
+
otherItems = []
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// `ShapeItem`s either draw a path, or modify how a path is rendered.
|
|
233
|
+
// - If this group doesn't have any items that draw a path, then its
|
|
234
|
+
// items are applied to all of this group's children.
|
|
235
|
+
let inheritedItemsForChildGroups: [ShapeItemLayer.Item]
|
|
236
|
+
if !otherItems.contains(where: { $0.drawsCGPath }) {
|
|
237
|
+
inheritedItemsForChildGroups = otherItems.map {
|
|
238
|
+
ShapeItemLayer.Item(item: $0, groupPath: parentGroupPath)
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
inheritedItemsForChildGroups = []
|
|
242
|
+
}
|
|
154
243
|
|
|
155
244
|
// Groups are listed from front to back,
|
|
156
245
|
// but `CALayer.sublayers` are listed from back to front.
|
|
157
246
|
let groupsInZAxisOrder = groupItems.reversed()
|
|
158
247
|
|
|
159
|
-
|
|
160
|
-
guard let group = group as? Group else {
|
|
248
|
+
return try groupsInZAxisOrder.compactMap { group in
|
|
249
|
+
guard let group = group as? Group else { return nil }
|
|
161
250
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
let inheritedItems: [ShapeItemLayer.Item]
|
|
166
|
-
if !otherItems.contains(where: { $0.drawsCGPath }) {
|
|
167
|
-
inheritedItems = otherItems.map {
|
|
168
|
-
ShapeItemLayer.Item(item: $0, parentGroup: parentGroup)
|
|
169
|
-
}
|
|
170
|
-
} else {
|
|
171
|
-
inheritedItems = []
|
|
251
|
+
var pathForChildren = parentGroupPath
|
|
252
|
+
if !group.name.isEmpty {
|
|
253
|
+
pathForChildren.append(group.name)
|
|
172
254
|
}
|
|
173
255
|
|
|
174
|
-
let
|
|
256
|
+
let childItems = group.items
|
|
257
|
+
.filter { !$0.hidden }
|
|
258
|
+
.map { ShapeItemLayer.Item(item: $0, groupPath: pathForChildren) }
|
|
259
|
+
|
|
260
|
+
return try GroupLayer(
|
|
175
261
|
group: group,
|
|
176
|
-
|
|
262
|
+
items: childItems + inheritedItemsForChildGroups,
|
|
263
|
+
groupPath: pathForChildren,
|
|
177
264
|
context: context)
|
|
178
|
-
|
|
179
|
-
addSublayer(groupLayer)
|
|
180
265
|
}
|
|
181
266
|
}
|
|
182
267
|
}
|
|
@@ -36,12 +36,27 @@ final class TextLayer: BaseCompositionLayer {
|
|
|
36
36
|
|
|
37
37
|
// MARK: Internal
|
|
38
38
|
|
|
39
|
+
override func setupAnimations(context: LayerAnimationContext) throws {
|
|
40
|
+
try super.setupAnimations(context: context)
|
|
41
|
+
let textAnimationContext = context.addingKeypathComponent(textLayerModel.name)
|
|
42
|
+
|
|
43
|
+
let sourceText = try textLayerModel.text.exactlyOneKeyframe(
|
|
44
|
+
context: textAnimationContext,
|
|
45
|
+
description: "text layer text")
|
|
46
|
+
|
|
47
|
+
renderLayer.text = context.textProvider.textFor(
|
|
48
|
+
keypathName: textAnimationContext.currentKeypath.fullPath,
|
|
49
|
+
sourceText: sourceText.text)
|
|
50
|
+
|
|
51
|
+
renderLayer.sizeToFit()
|
|
52
|
+
}
|
|
53
|
+
|
|
39
54
|
func configureRenderLayer(with context: LayerContext) throws {
|
|
40
55
|
// We can't use `CATextLayer`, because it doesn't support enough features we use.
|
|
41
56
|
// Instead, we use the same `CoreTextRenderLayer` (with a custom `draw` implementation)
|
|
42
57
|
// used by the Main Thread rendering engine. This means the Core Animation engine can't
|
|
43
58
|
// _animate_ text properties, but it can display static text without any issues.
|
|
44
|
-
let text = try textLayerModel.text.exactlyOneKeyframe(context: context, description: "text layer text")
|
|
59
|
+
let text = try textLayerModel.text.exactlyOneKeyframe(context: context, description: "text layer text")
|
|
45
60
|
|
|
46
61
|
// The Core Animation engine doesn't currently support `TextAnimator`s.
|
|
47
62
|
// - We could add support for animating the transform-related properties without much trouble.
|
|
@@ -54,7 +69,6 @@ final class TextLayer: BaseCompositionLayer {
|
|
|
54
69
|
""")
|
|
55
70
|
}
|
|
56
71
|
|
|
57
|
-
renderLayer.text = text.text
|
|
58
72
|
renderLayer.font = context.fontProvider.fontFor(family: text.fontFamily, size: CGFloat(text.fontSize))
|
|
59
73
|
|
|
60
74
|
renderLayer.alignment = text.justification.textAlignment
|
|
@@ -17,7 +17,7 @@ class CompositionLayer: CALayer, KeypathSearchable {
|
|
|
17
17
|
|
|
18
18
|
init(layer: LayerModel, size: CGSize) {
|
|
19
19
|
transformNode = LayerTransformNode(transform: layer.transform)
|
|
20
|
-
if let masks = layer.masks {
|
|
20
|
+
if let masks = layer.masks?.filter({ $0.mode != .none }), !masks.isEmpty {
|
|
21
21
|
maskLayer = MaskContainerLayer(masks: masks)
|
|
22
22
|
} else {
|
|
23
23
|
maskLayer = nil
|
|
@@ -109,7 +109,6 @@ private class MaskLayer: CALayer {
|
|
|
109
109
|
actions = [
|
|
110
110
|
"opacity" : NSNull(),
|
|
111
111
|
]
|
|
112
|
-
|
|
113
112
|
}
|
|
114
113
|
|
|
115
114
|
override init(layer: Any) {
|
|
@@ -152,7 +151,6 @@ private class MaskLayer: CALayer {
|
|
|
152
151
|
}
|
|
153
152
|
maskLayer.path = path
|
|
154
153
|
}
|
|
155
|
-
|
|
156
154
|
}
|
|
157
155
|
}
|
|
158
156
|
|
|
@@ -107,12 +107,12 @@ final class PreCompositionLayer: CompositionLayer {
|
|
|
107
107
|
} else {
|
|
108
108
|
localFrame = (frame - startFrame) / timeStretch
|
|
109
109
|
}
|
|
110
|
-
animationLayers.forEach(
|
|
110
|
+
animationLayers.forEach({ $0.displayWithFrame(frame: localFrame, forceUpdates: forceUpdates) })
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
override func updateRenderScale() {
|
|
114
114
|
super.updateRenderScale()
|
|
115
|
-
animationLayers.forEach(
|
|
115
|
+
animationLayers.forEach({ $0.renderScale = renderScale })
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// MARK: Fileprivate
|
|
@@ -93,7 +93,6 @@ final class MainThreadAnimationLayer: CALayer, RootAnimationLayer {
|
|
|
93
93
|
super.init(layer: layer)
|
|
94
94
|
|
|
95
95
|
currentFrame = typedLayer.currentFrame
|
|
96
|
-
|
|
97
96
|
}
|
|
98
97
|
|
|
99
98
|
required init?(coder _: NSCoder) {
|
|
@@ -195,7 +194,7 @@ final class MainThreadAnimationLayer: CALayer, RootAnimationLayer {
|
|
|
195
194
|
|
|
196
195
|
/// Forces the view to update its drawing.
|
|
197
196
|
func forceDisplayUpdate() {
|
|
198
|
-
animationLayers.forEach(
|
|
197
|
+
animationLayers.forEach({ $0.displayWithFrame(frame: currentFrame, forceUpdates: true) })
|
|
199
198
|
}
|
|
200
199
|
|
|
201
200
|
func logHierarchyKeypaths() {
|
|
@@ -151,6 +151,16 @@ final class CoreTextRenderLayer: CALayer {
|
|
|
151
151
|
strokeFrame = nil
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
// This fixes a vertical padding issue that arises when drawing some fonts.
|
|
155
|
+
// For some reason some fonts, such as Helvetica draw with and ascender that is greater than the one reported by CTFontGetAscender.
|
|
156
|
+
// I suspect this is actually an issue with the Attributed string, but cannot reproduce.
|
|
157
|
+
|
|
158
|
+
if let fillFrame = fillFrame {
|
|
159
|
+
ctx.adjustWithLineOrigins(in: fillFrame, with: font)
|
|
160
|
+
} else if let strokeFrame = strokeFrame {
|
|
161
|
+
ctx.adjustWithLineOrigins(in: strokeFrame, with: font)
|
|
162
|
+
}
|
|
163
|
+
|
|
154
164
|
if !strokeOnTop, let strokeFrame = strokeFrame {
|
|
155
165
|
CTFrameDraw(strokeFrame, ctx)
|
|
156
166
|
}
|
|
@@ -311,10 +321,29 @@ final class CoreTextRenderLayer: CALayer {
|
|
|
311
321
|
x: textAnchor.x.remap(fromLow: 0, fromHigh: drawingRect.size.width, toLow: 0, toHigh: 1),
|
|
312
322
|
y: textAnchor.y.remap(fromLow: 0, fromHigh: drawingRect.size.height, toLow: 0, toHigh: 1))
|
|
313
323
|
|
|
314
|
-
if fillFrameSetter != nil
|
|
324
|
+
if fillFrameSetter != nil, strokeFrameSetter != nil {
|
|
315
325
|
drawingRect.size.width += strokeWidth
|
|
316
326
|
drawingRect.size.height += strokeWidth
|
|
317
327
|
}
|
|
318
328
|
}
|
|
319
329
|
|
|
320
330
|
}
|
|
331
|
+
|
|
332
|
+
extension CGContext {
|
|
333
|
+
|
|
334
|
+
fileprivate func adjustWithLineOrigins(in frame: CTFrame, with font: CTFont?) {
|
|
335
|
+
guard let font = font else { return }
|
|
336
|
+
|
|
337
|
+
let count = CFArrayGetCount(CTFrameGetLines(frame))
|
|
338
|
+
|
|
339
|
+
guard count > 0 else { return }
|
|
340
|
+
|
|
341
|
+
var o = [CGPoint](repeating: .zero, count: 1)
|
|
342
|
+
CTFrameGetLineOrigins(frame, CFRange(location: count - 1, length: 1), &o)
|
|
343
|
+
|
|
344
|
+
let diff = CTFontGetDescent(font) - o[0].y
|
|
345
|
+
if diff > 0 {
|
|
346
|
+
translateBy(x: 0, y: diff)
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
@@ -16,7 +16,6 @@ final class LayerTransformProperties: NodePropertyMap, KeypathSearchable {
|
|
|
16
16
|
// MARK: Lifecycle
|
|
17
17
|
|
|
18
18
|
init(transform: Transform) {
|
|
19
|
-
|
|
20
19
|
anchor = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.anchorPoint.keyframes))
|
|
21
20
|
scale = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.scale.keyframes))
|
|
22
21
|
rotation = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.rotation.keyframes))
|