Skip to content

Instantly share code, notes, and snippets.

@kropp
Created April 13, 2023 15:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kropp/f119e0f1341d129bc88957a5fc3d90da to your computer and use it in GitHub Desktop.
Save kropp/f119e0f1341d129bc88957a5fc3d90da to your computer and use it in GitHub Desktop.
import androidx.compose.foundation.Canvas
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.withFrameNanos
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.graphics.nativeCanvas
import org.jetbrains.skia.skottie.Animation
@Composable
fun LottieAnimation(
animation: Animation,
modifier: Modifier = Modifier,
loop: Boolean = true,
scale: Float = 1f,
) {
var frameTimeInSeconds by remember(animation) { mutableStateOf(0f) }
Canvas(modifier) {
withTransform({ scale(scale, scale, Offset.Zero) }) {
drawIntoCanvas {
animation.seekFrameTime(frameTimeInSeconds).render(it.nativeCanvas)
}
}
}
LaunchedEffect(animation) {
var lastFrameNanos = Long.MIN_VALUE
while (true) {
val animationEnded = withFrameNanos {
if (lastFrameNanos == Long.MIN_VALUE) lastFrameNanos = it
val nextFrameTimeInSeconds = (it - lastFrameNanos).toFloat() / 1_000_000_000L
frameTimeInSeconds = if (nextFrameTimeInSeconds >= animation.duration) {
lastFrameNanos = Long.MIN_VALUE
animation.duration
} else nextFrameTimeInSeconds
return@withFrameNanos frameTimeInSeconds == animation.duration && !loop
}
if (animationEnded) break
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment