• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.airbnb.lottie.sample.compose.examples
2 
3 import androidx.compose.foundation.background
4 import androidx.compose.foundation.clickable
5 import androidx.compose.foundation.layout.Box
6 import androidx.compose.foundation.layout.Column
7 import androidx.compose.foundation.layout.fillMaxWidth
8 import androidx.compose.foundation.layout.padding
9 import androidx.compose.foundation.layout.size
10 import androidx.compose.foundation.rememberScrollState
11 import androidx.compose.foundation.verticalScroll
12 import androidx.compose.material.Slider
13 import androidx.compose.runtime.Composable
14 import androidx.compose.runtime.LaunchedEffect
15 import androidx.compose.runtime.getValue
16 import androidx.compose.runtime.mutableStateOf
17 import androidx.compose.runtime.remember
18 import androidx.compose.runtime.setValue
19 import androidx.compose.ui.Alignment
20 import androidx.compose.ui.Modifier
21 import androidx.compose.ui.graphics.Color
22 import androidx.compose.ui.unit.dp
23 import com.airbnb.lottie.compose.rememberLottieAnimatable
24 import com.airbnb.lottie.compose.LottieAnimation
25 import com.airbnb.lottie.compose.LottieCompositionSpec
26 import com.airbnb.lottie.compose.LottieConstants
27 import com.airbnb.lottie.compose.rememberLottieComposition
28 import com.airbnb.lottie.sample.compose.R
29 
30 @Composable
AnimatableExamplesPagenull31 fun AnimatableExamplesPage() {
32     UsageExamplePageScaffold {
33         Column(
34             modifier = Modifier
35                 .fillMaxWidth()
36                 .verticalScroll(rememberScrollState())
37         ) {
38             ExampleCard("Example 1", "Repeat Forever") {
39                 Example1()
40             }
41             ExampleCard("Example 2", "Draggable Progress Slider") {
42                 Example2()
43             }
44             ExampleCard("Example 3", "Draggable Speed Slider") {
45                 Example3()
46             }
47             ExampleCard("Example 4", "Repeat once. Click to repeat again") {
48                 Example4()
49             }
50             ExampleCard("Example 5", "Click to toggle playback") {
51                 Example5()
52             }
53             ExampleCard("Example 6", "Reverse Animation on Repeat") {
54                 Example6()
55             }
56         }
57     }
58 }
59 
60 @Composable
Example1null61 private fun Example1() {
62     val anim = rememberLottieAnimatable()
63     val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.heart))
64     LaunchedEffect(composition) {
65         anim.animate(
66             composition,
67             iterations = LottieConstants.IterateForever,
68         )
69     }
70     LottieAnimation(anim.composition, { anim.progress })
71 }
72 
73 @Composable
Example2null74 private fun Example2() {
75     val anim = rememberLottieAnimatable()
76     val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.heart))
77     var sliderGestureProgress: Float? by remember { mutableStateOf(null) }
78     LaunchedEffect(composition, sliderGestureProgress) {
79         when (val p = sliderGestureProgress) {
80             null -> anim.animate(
81                 composition,
82                 iterations = LottieConstants.IterateForever,
83                 initialProgress = anim.progress,
84                 continueFromPreviousAnimate = false,
85             )
86             else -> anim.snapTo(progress = p)
87         }
88     }
89     Box {
90         LottieAnimation(anim.composition, { anim.progress })
91         Slider(
92             value = sliderGestureProgress ?: anim.progress,
93             onValueChange = { sliderGestureProgress = it },
94             onValueChangeFinished = { sliderGestureProgress = null },
95             modifier = Modifier
96                 .align(Alignment.BottomCenter)
97                 .padding(bottom = 8.dp)
98         )
99     }
100 }
101 
102 @Composable
Example3null103 private fun Example3() {
104     val anim = rememberLottieAnimatable()
105     val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.heart))
106     var speed by remember { mutableStateOf(1f) }
107     LaunchedEffect(composition, speed) {
108         anim.animate(
109             composition,
110             iterations = LottieConstants.IterateForever,
111             speed = speed,
112             initialProgress = anim.progress,
113         )
114     }
115     Box {
116         LottieAnimation(composition, { anim.progress })
117         Slider(
118             value = speed,
119             onValueChange = { speed = it },
120             valueRange = -3f..3f,
121             modifier = Modifier
122                 .align(Alignment.BottomCenter)
123                 .padding(bottom = 8.dp)
124         )
125         Box(
126             modifier = Modifier
127                 .align(Alignment.BottomCenter)
128                 .padding(bottom = 24.dp)
129                 .size(width = 1.dp, height = 16.dp)
130                 .background(Color.Black)
131         )
132     }
133 }
134 
135 @Composable
Example4null136 private fun Example4() {
137     var nonce by remember { mutableStateOf(1) }
138     val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.heart))
139     val animatable = rememberLottieAnimatable()
140 
141     LaunchedEffect(composition, nonce) {
142         composition ?: return@LaunchedEffect
143         animatable.animate(
144             composition,
145             continueFromPreviousAnimate = false,
146         )
147     }
148     LottieAnimation(
149         composition,
150         { animatable.progress },
151         modifier = Modifier
152             .clickable { nonce++ }
153     )
154 }
155 
156 @Composable
Example5null157 private fun Example5() {
158     var shouldPlay by remember { mutableStateOf(true) }
159     val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.heart))
160     val animatable = rememberLottieAnimatable()
161 
162     LaunchedEffect(composition, shouldPlay) {
163         if (composition == null || !shouldPlay) return@LaunchedEffect
164         animatable.animate(composition, iteration = LottieConstants.IterateForever)
165     }
166     LottieAnimation(
167         composition,
168         { animatable.progress },
169         modifier = Modifier
170             .clickable { shouldPlay = !shouldPlay }
171     )
172 }
173 
174 @Composable
Example6null175 private fun Example6() {
176     val anim = rememberLottieAnimatable()
177     val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.heart))
178     LaunchedEffect(composition) {
179         anim.animate(
180             composition,
181             iterations = LottieConstants.IterateForever,
182             reverseOnRepeat = true,
183         )
184     }
185     LottieAnimation(anim.composition, { anim.progress })
186 }
187 
188