blob: d6e5505ba85b6908b3d5a29d736b326f8d452072 [file] [log] [blame]
package com.airbnb.lottie.compose
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import com.airbnb.lottie.LottieComposition
/**
* Returns a [LottieAnimationState] representing the progress of an animation.
*
* This is the declarative version of [rememberLottieAnimatable] and [LottieAnimation].
*
* @param composition The composition to render. This should be retrieved with [rememberLottieComposition].
* @param isPlaying Whether or not the animation is currently playing. Note that the internal
* animation may end due to reaching the target iterations count. If that happens,
* the animation may stop even if this is still true. You can observe the returned
* [LottieAnimationState.isPlaying] to determine whether the underlying animation
* is still playing.
* @param restartOnPlay If isPlaying switches from false to true, restartOnPlay determines whether
* the progress and iteration gets reset.
* @param clipSpec A [LottieClipSpec] that specifies the bound the animation playback
* should be clipped to.
* @param speed The speed the animation should play at. Numbers larger than one will speed it up.
* Numbers between 0 and 1 will slow it down. Numbers less than 0 will play it backwards.
* @param iterations The number of times the animation should repeat before stopping. It must be
* a positive number. [LottieConstants.IterateForever] can be used to repeat forever.
*/
@Composable
fun animateLottieCompositionAsState(
composition: LottieComposition?,
isPlaying: Boolean = true,
restartOnPlay: Boolean = true,
clipSpec: LottieClipSpec? = null,
speed: Float = 1f,
iterations: Int = 1,
): LottieAnimationState {
require(iterations > 0) { "Iterations must be a positive number ($iterations)." }
require(speed.isFinite()) { "Speed must be a finite number. It is $speed." }
val animatable = rememberLottieAnimatable()
var wasPlaying by remember { mutableStateOf(isPlaying) }
LaunchedEffect(
composition,
isPlaying,
clipSpec,
speed,
iterations,
) {
if (isPlaying && !wasPlaying && restartOnPlay) {
animatable.resetToBeginning()
}
wasPlaying = isPlaying
if (!isPlaying) return@LaunchedEffect
animatable.animate(
composition,
iterations = iterations,
speed = speed,
clipSpec = clipSpec,
initialProgress = animatable.progress,
continueFromPreviousAnimate = false,
)
}
return animatable
}