<lambda>null1 package com.airbnb.lottie.sample.compose.examples
2
3 import androidx.compose.foundation.layout.Column
4 import androidx.compose.foundation.layout.padding
5 import androidx.compose.material.Text
6 import androidx.compose.material.TextButton
7 import androidx.compose.runtime.Composable
8 import androidx.compose.runtime.LaunchedEffect
9 import androidx.compose.runtime.getValue
10 import androidx.compose.runtime.mutableStateOf
11 import androidx.compose.runtime.remember
12 import androidx.compose.runtime.rememberUpdatedState
13 import androidx.compose.runtime.setValue
14 import androidx.compose.runtime.snapshotFlow
15 import androidx.compose.ui.Modifier
16 import androidx.compose.ui.unit.dp
17 import com.airbnb.lottie.compose.rememberLottieAnimatable
18 import com.airbnb.lottie.compose.LottieAnimation
19 import com.airbnb.lottie.compose.LottieCancellationBehavior
20 import com.airbnb.lottie.compose.LottieClipSpec
21 import com.airbnb.lottie.compose.LottieCompositionSpec
22 import com.airbnb.lottie.compose.LottieConstants
23 import com.airbnb.lottie.compose.rememberLottieComposition
24 import com.airbnb.lottie.sample.compose.R
25 import kotlinx.coroutines.flow.collectLatest
26
27 enum class TransitionSection {
28 Intro,
29 LoopMiddle,
30 Outro;
31
32 fun next(): TransitionSection = when (this) {
33 Intro -> LoopMiddle
34 LoopMiddle -> Outro
35 Outro -> Intro
36 }
37 }
38
39 @Composable
TransitionsExamplesPagenull40 fun TransitionsExamplesPage() {
41 var state by remember { mutableStateOf(TransitionSection.Intro) }
42
43 UsageExamplePageScaffold { padding ->
44 Column(
45 modifier = Modifier
46 .padding(padding)
47 ) {
48 Text(
49 "Single composition",
50 modifier = Modifier
51 .padding(8.dp)
52 )
53 SingleCompositionTransition(state)
54 Text(
55 "Multiple compositions",
56 modifier = Modifier
57 .padding(8.dp)
58 )
59 SplitCompositionTransition(state)
60 TextButton(
61 onClick = { state = state.next() }
62 ) {
63 Text("State: $state")
64 }
65 }
66
67 }
68 }
69
70 @Composable
SingleCompositionTransitionnull71 fun SingleCompositionTransition(section: TransitionSection) {
72 val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.bar))
73 val animatable = rememberLottieAnimatable()
74 val state by rememberUpdatedState(section)
75
76 LaunchedEffect(composition, animatable) {
77 composition ?: return@LaunchedEffect
78 snapshotFlow { state }.collectLatest { s ->
79 val clipSpec = when (s) {
80 TransitionSection.Intro -> LottieClipSpec.Progress(0f, 0.301f)
81 TransitionSection.LoopMiddle -> LottieClipSpec.Progress(0.301f, 2f / 3f)
82 TransitionSection.Outro -> LottieClipSpec.Progress(2f / 3f, 1f)
83 }
84 do {
85 animatable.animate(
86 composition,
87 clipSpec = clipSpec,
88 cancellationBehavior = LottieCancellationBehavior.OnIterationFinish,
89 )
90 } while (s == TransitionSection.LoopMiddle)
91 }
92 }
93 LottieAnimation(composition, { animatable.progress })
94 }
95
96 @Composable
SplitCompositionTransitionnull97 fun SplitCompositionTransition(section: TransitionSection) {
98 val introComposition = rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.bar_1))
99 val loopMiddleComposition = rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.bar_2))
100 val outroComposition = rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.bar_3))
101 val animatable = rememberLottieAnimatable()
102
103 LaunchedEffect(section) {
104 val composition = when (section) {
105 TransitionSection.Intro -> introComposition
106 TransitionSection.LoopMiddle -> loopMiddleComposition
107 TransitionSection.Outro -> outroComposition
108 }.await()
109 animatable.animate(
110 composition,
111 iterations = if (section == TransitionSection.LoopMiddle) LottieConstants.IterateForever else 1,
112 cancellationBehavior = LottieCancellationBehavior.OnIterationFinish,
113 )
114 }
115
116 LottieAnimation(animatable.composition, { animatable.progress })
117 }