· 3 min read Posted by Gustavo Fão Valvassori

Compose Multiplatform + Lottie Animations

Lottie and Bodymovin provide amazing animations that you can now use in your Compose Multiplatform projects.
Kelly Sikkema - https://unsplash.com/photos/person-writing-on-white-paper-ia1p6fqftnQ
Credit: Kelly Sikkema - https://unsplash.com/photos/person-writing-on-white-paper-ia1p6fqftnQ

Animations are one key feature that provides a good user experience. Lottie, developed by Airbnb, is a great choice for adding amazing animations to your app.

Lottie implements a render engine for the Adobe After Effects animations using the Bodymovin plugin. Long story short, Bodymovin converts the After Effects animation into a JSON file that can be used by other sources (like Android, iOS, and Web apps).

Unfortunately, the Airbnb libraries do not support Compose Multiplatform. In an issue from Compose Android, they mention that their implementation is tied to the Android platform. Therefore, making it work with Kotlin Multiplatform is not in their scope.

To support this need, the community has developed a few libraries to support this use case. The most common are Kottie and Compottie.

This isn’t just theoretical. Touchlab is putting Compose Multiplatform (CMP) with Lottie into production with our clients. If you want to explore CMP in a greenfield project or integrate it into an existing app, Touchlab has the tools and expertise you need to be successful.

Start A Conversation Today!

Kottie

Kottie is the first alternative. It is maintained by Ismail Mohamed and is a wrapper for the Lottie libraries implemented by Airbnb. Its usage is quite simple. All you need to do is load your JSON file as a string and use the rememberKottieComposition compose method.

// Original Code: https://github.com/ismai117/kottie/blob/55ea950751e0f337e0a0e51be527f8f5ab73723f/sample/shared/src/commonMain/kotlin/App.kt
@Composable
fun App(
    modifier: Modifier = Modifier,
) {
    var animation by remember { mutableStateOf("") }

		// Load animation JSON
    LaunchedEffect(Unit){
        animation = Res.readBytes("files/animation.json").decodeToString()
    }

		// Create the animation composition
    val composition = rememberKottieComposition(
        spec = KottieCompositionSpec.File(animation)
    )

		// Optionally: Define the animation state so you can control the progress
    val animationState by animateKottieCompositionAsState(
        composition = composition,
        iterations = KottieConstants.IterateForever
    )

    MaterialTheme {
        Box(
            modifier = modifier
                .fillMaxSize()
                .background(Color.Red),
            contentAlignment = Alignment.Center
        ) {
						// Render your Lottie file
            KottieAnimation(
                composition = composition,
                progress = { animationState.progress },
                modifier = modifier
                    .fillMaxWidth()
            )

        }
    }
}

Compottie

The second option is developed by Alexander Zhirkevich. It started as a similar solution to Kottie where it used to wrap the the Lottie animation, but in the 2.0 version they are building their own renderer.

This new render works fully in Kotlin Multiplatform and is still experimental. With the shared render, you remove the complexity during installation and makes it work “natively” to Compose Multiplatform, without any bridges. Therefore, you may find issues as it’s still in development.

The usage is really simple. Just create the Compottie Composition that will hold your animation JSON instance. Then create a Compottie painter using the rememberLottiePainter and voilà.

// Original Code: https://github.com/alexzhirkevich/compottie/blob/standalone-main/example/shared/src/commonMain/kotlin/lottiefiles/LottieFilesScreen.kt
@Composable
private fun LottieCard(
    file : LottieFile,
    onClick : () -> Unit,
    modifier: Modifier = Modifier
) {
    val composition by rememberLottieComposition {
        LottieCompositionSpec.Url(file.lottieSource ?: file.jsonSource ?: "")
    }
    
    Image(
        modifier = Modifier.fillMaxSize(),
        painter = rememberLottiePainter(
            composition = composition,
            iterations = Compottie.IterateForever
        ),
        contentDescription = file.name
    )
}

Final Thoughts

The KMP community is growing fast and implementing amazing solutions for the problems we encounter. Lottie animations is one of them and it’s great to see it working with Compose Multiplatform.

The right library will very much depend on your context and needs, and both alternatives have great support and may be able to support your scenario.