From 1e0db56e7d0d578234f2a7b104be7a041d33d9af Mon Sep 17 00:00:00 2001 From: Mohamed Darwish Date: Thu, 19 May 2022 19:18:52 +0200 Subject: [PATCH 1/2] Defer progress reads in LottieAnimation to draw phase --- .../airbnb/lottie/compose/LottieAnimation.kt | 56 +++++++++++++++---- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieAnimation.kt b/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieAnimation.kt index f22be003e7..fefea855c4 100644 --- a/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieAnimation.kt +++ b/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieAnimation.kt @@ -32,12 +32,12 @@ import kotlin.math.roundToInt * * @param composition The composition that will be rendered. To generate a [LottieComposition], you can use * [rememberLottieComposition]. - * @param progress The progress (between 0 and 1) that should be rendered. If you want to render a specific - * frame, you can use [LottieComposition.getFrameForProgress]. In most cases, you will want - * to use one of the overloaded LottieAnimation composables that drives the animation for you. - * The overloads that have isPlaying as a parameter instead of progress will drive the - * animation automatically. You may want to use this version if you want to drive the animation - * from your own Animatable or via events such as download progress or a gesture. + * @param progressProvider A provider for the progress (between 0 and 1) that should be rendered. If you want to render a + * specific frame, you can use [LottieComposition.getFrameForProgress]. In most cases, you will want + * to use one of the overloaded LottieAnimation composables that drives the animation for you. + * The overloads that have isPlaying as a parameter instead of progress will drive the + * animation automatically. You may want to use this version if you want to drive the animation + * from your own Animatable or via events such as download progress or a gesture. * @param outlineMasksAndMattes Enable this to debug slow animations by outlining masks and mattes. * The performance overhead of the masks and mattes will be proportional to the * surface area of all of the masks/mattes combined. @@ -69,7 +69,7 @@ import kotlin.math.roundToInt @Composable fun LottieAnimation( composition: LottieComposition?, - @FloatRange(from = 0.0, to = 1.0) progress: Float, + @FloatRange(from = 0.0, to = 1.0) progressProvider: () -> Float, modifier: Modifier = Modifier, outlineMasksAndMattes: Boolean = false, applyOpacityToLayers: Boolean = false, @@ -114,16 +114,52 @@ fun LottieAnimation( drawable.isApplyingOpacityToLayersEnabled = applyOpacityToLayers drawable.maintainOriginalImageBounds = maintainOriginalImageBounds drawable.clipToCompositionBounds = clipToCompositionBounds - drawable.progress = progress + drawable.progress = progressProvider() drawable.setBounds(0, 0, composition.bounds.width(), composition.bounds.height()) drawable.draw(canvas.nativeCanvas, matrix) } } } +/** + * This is like [LottieAnimation] except that it takes a raw progress parameter instead of taking a progress provider. + * + * @see LottieAnimation + */ +@Composable +fun LottieAnimation( + composition: LottieComposition?, + @FloatRange(from = 0.0, to = 1.0) progress: Float, + modifier: Modifier = Modifier, + outlineMasksAndMattes: Boolean = false, + applyOpacityToLayers: Boolean = false, + enableMergePaths: Boolean = false, + renderMode: RenderMode = RenderMode.AUTOMATIC, + maintainOriginalImageBounds: Boolean = false, + dynamicProperties: LottieDynamicProperties? = null, + alignment: Alignment = Alignment.Center, + contentScale: ContentScale = ContentScale.Fit, + clipToCompositionBounds: Boolean = true, +) { + LottieAnimation( + composition, + { progress }, + modifier, + outlineMasksAndMattes, + applyOpacityToLayers, + enableMergePaths, + renderMode, + maintainOriginalImageBounds, + dynamicProperties, + alignment, + contentScale, + clipToCompositionBounds, + ) +} + /** * This is like [LottieAnimation] except that it handles driving the animation via [animateLottieCompositionAsState] - * instead of taking a raw progress parameter. + * instead of taking a progress provider. * * @see LottieAnimation * @see animateLottieCompositionAsState @@ -157,7 +193,7 @@ fun LottieAnimation( ) LottieAnimation( composition, - progress, + { progress }, modifier, outlineMasksAndMattes, applyOpacityToLayers, From b128105164949691a97e9f8717be1f7f6d10a118 Mon Sep 17 00:00:00 2001 From: Mohamed Darwish Date: Thu, 19 May 2022 19:33:57 +0200 Subject: [PATCH 2/2] Update sample-compose and issue-repro-compose to use the new progressProvider --- .../lottie/issues/compose/ComposeIssueReproActivity.kt | 2 +- .../sample/compose/examples/AnimatableExamplesPage.kt | 10 +++++----- .../sample/compose/examples/BasicUsageExamplesPage.kt | 2 +- .../sample/compose/examples/TransitionsExamplesPage.kt | 4 ++-- .../lottie/sample/compose/examples/ViewPagerExample.kt | 2 +- .../airbnb/lottie/sample/compose/player/PlayerPage.kt | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/issue-repro-compose/src/main/java/com/airbnb/lottie/issues/compose/ComposeIssueReproActivity.kt b/issue-repro-compose/src/main/java/com/airbnb/lottie/issues/compose/ComposeIssueReproActivity.kt index 81acbedf6b..aeecf2fb7f 100755 --- a/issue-repro-compose/src/main/java/com/airbnb/lottie/issues/compose/ComposeIssueReproActivity.kt +++ b/issue-repro-compose/src/main/java/com/airbnb/lottie/issues/compose/ComposeIssueReproActivity.kt @@ -22,6 +22,6 @@ class ComposeIssueReproActivity : AppCompatActivity() { fun Content() { val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.heart)) val progress by animateLottieCompositionAsState(composition) - LottieAnimation(composition, progress) + LottieAnimation(composition, { progress }) } } diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/AnimatableExamplesPage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/AnimatableExamplesPage.kt index 562b837a6a..f52b15dd6f 100644 --- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/AnimatableExamplesPage.kt +++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/AnimatableExamplesPage.kt @@ -64,7 +64,7 @@ private fun Example1() { iterations = LottieConstants.IterateForever, ) } - LottieAnimation(anim.composition, anim.progress) + LottieAnimation(anim.composition, { anim.progress }) } @Composable @@ -84,7 +84,7 @@ private fun Example2() { } } Box { - LottieAnimation(anim.composition, anim.progress) + LottieAnimation(anim.composition, { anim.progress }) Slider( value = sliderGestureProgress ?: anim.progress, onValueChange = { sliderGestureProgress = it }, @@ -110,7 +110,7 @@ private fun Example3() { ) } Box { - LottieAnimation(composition, anim.progress) + LottieAnimation(composition, { anim.progress }) Slider( value = speed, onValueChange = { speed = it }, @@ -144,7 +144,7 @@ private fun Example4() { } LottieAnimation( composition, - animatable.progress, + { animatable.progress }, modifier = Modifier .clickable { nonce++ } ) @@ -162,7 +162,7 @@ private fun Example5() { } LottieAnimation( composition, - animatable.progress, + { animatable.progress }, modifier = Modifier .clickable { shouldPlay = !shouldPlay } ) diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/BasicUsageExamplesPage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/BasicUsageExamplesPage.kt index d592c18f22..f82e2ba965 100644 --- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/BasicUsageExamplesPage.kt +++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/BasicUsageExamplesPage.kt @@ -140,7 +140,7 @@ private fun Example6() { ) LottieAnimation( composition, - progress, + { progress }, ) } diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/TransitionsExamplesPage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/TransitionsExamplesPage.kt index e6eec4e355..0dbcd85d75 100644 --- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/TransitionsExamplesPage.kt +++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/TransitionsExamplesPage.kt @@ -90,7 +90,7 @@ fun SingleCompositionTransition(section: TransitionSection) { } while (s == TransitionSection.LoopMiddle) } } - LottieAnimation(composition, animatable.progress) + LottieAnimation(composition, { animatable.progress }) } @Composable @@ -113,5 +113,5 @@ fun SplitCompositionTransition(section: TransitionSection) { ) } - LottieAnimation(animatable.composition, animatable.progress) + LottieAnimation(animatable.composition, { animatable.progress }) } \ No newline at end of file diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/ViewPagerExample.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/ViewPagerExample.kt index 26a51469c2..79945beff0 100644 --- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/ViewPagerExample.kt +++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/examples/ViewPagerExample.kt @@ -60,7 +60,7 @@ private fun WalkthroughAnimation(pagerState: PagerState) { val progress by derivedStateOf { (pagerState.currentPage + pagerState.currentPageOffset) / (pagerState.pageCount - 1f) } LottieAnimation( composition, - progress, + { progress }, modifier = Modifier .fillMaxSize() ) diff --git a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/PlayerPage.kt b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/PlayerPage.kt index e050069d30..3a640f2723 100644 --- a/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/PlayerPage.kt +++ b/sample-compose/src/main/java/com/airbnb/lottie/sample/compose/player/PlayerPage.kt @@ -255,7 +255,7 @@ fun PlayerPageContent( ) { PlayerPageLottieAnimation( composition, - state.animatable.progress, + { state.animatable.progress }, modifier = Modifier // TODO: figure out how maxWidth can play nice with the aspectRatio modifier inside of LottieAnimation. .fillMaxWidth() @@ -291,12 +291,12 @@ fun PlayerPageContent( @Composable private fun PlayerPageLottieAnimation( composition: LottieComposition?, - progress: Float, + progressProvider: () -> Float, modifier: Modifier = Modifier, ) { LottieAnimation( composition, - progress, + progressProvider, modifier = modifier, ) }