I have a Lottie animation that I want to start then when it gets to a certain frame I want to loop from frame X to frame Y.
The issue I am running up against is that I cant seem to figure out how to update the clipSpec
at runtime with LottieCompose
as clipSpec
cannot be reassigned.
I was able to do this no problem with normal XML layout based Lottie like this
loading_animation.addAnimatorUpdateListener {
if(initialLoad && loading_animation.frame == 15){
initialLoad = false
startTime = System.currentTimeMillis()
loading_animation.setMinAndMaxFrame(15,28)
}
if(!initialLoad && authenticated && System.currentTimeMillis() >= (startTime+1000)){
loading_animation.pauseAnimation()
startActivity()
}
}
here is my LottieCompose
code I have so far
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.sun_icon))
val animatable = rememberLottieAnimatable()
val progress by animateLottieCompositionAsState(composition, iterations = LottieConstants.IterateForever)
LottieAnimation(composition = composition, progress = progress, modifier = Modifier.wrapContentSize())
clipSpec
can be specified with animateLottieCompositionAsState
. You can update it just like any other state in Compose: create a state variable and update it with some action/side-effect.
Learn more about state in Compose documentation, including this youtube video, which explains the basic principles.
getFrameForProgress
returns a frame in Float
, I am not sure if it is safe to convert it to Int
and compare equals (is it guaranteed that every frame is rendered? on slow devices it might not be), so my comparison code looks not too nice.
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw. sun_icon))
var clipSpec by remember { mutableStateOf<LottieClipSpec?>(null)}
val progress by animateLottieCompositionAsState(
composition = composition,
clipSpec = clipSpec,
iterations = LottieConstants.IterateForever
)
LottieAnimation(
composition = composition,
progress = progress,
modifier = Modifier.wrapContentSize()
)
var initialLoad by remember { mutableStateOf(true) }
if (initialLoad && composition?.getFrameForProgress(progress)?.let { it >= 15f } == true) {
SideEffect {
initialLoad = false
clipSpec = LottieClipSpec.Frame(
min = 15,
max = 28
)
}
}