Instagram-like particles animation using Jetpack Compose

In this article we will develop an Instagram-like emoji reactions animation using Jetpack Compose. Let’s see final result and see how it can be achieved.
My Jetpack Compose implementation:

Instagram implmenation:

This animation can be splitted in 2 parts. First one is animation of particular emoji (fire emoji in this case) and second is motion animation from bottom to top of all emojis at the same time.
Emoji animation:
- Quick fade in when emoji appears on the screen
- No animation (floating phase)
- Fade out + small change of scale when emoji disappears from the screen

As we want to start animation immediately after emoji composable added to composition our choice is transition API. Transition is a generic mechanism that allows to transition between multiple states. In this case we need to transition alpha from 0f to 1f to 0f at the end.
To use transition we need to use MutableTransitionState class, with defining initial state (0f) and target state (0f)
For animating alpha from 0f to 1f to 0f we can use keyframes mechanism. It’s. basically about defining state of transition at particular time.
That means that at START_OF_ANIMATION or 0ms we want our alpha to be equal to 0f. After 10% of animation time we want alpha == 1f, and then we want to fade out emoji similar way, starting from 80% of animation time.
Let’s do this for scale and see what we got:

Yup. Nothing shown. This is happening because we have our initial and end state of transition is equal to 0f. And framework thinks as target state equal to current state i will not transition anything as my job is done. A workaround i find to this is just to transition between 0.1f and 0f through all keyframes.
And voila! After this small change all working as expected:

All right, that was cool. With only 44! lines of code we created this beautiful and pretty complex animation.
Now it’s time to add more emojis and layout them on the screen. I counted 22 emojis on instagram reactions and it seems like emoji size depending on height. The closer emoji to bottom of the container the bigger. And also when animating, the closer emoji to bottom of the container the later it fading out from the screen.

This means that we need to parameterize Particle composable with scale and duration. And also for each Particle we need to define it’s place in container. For this we will create a custom view group. Fortunately in Jetpack Compose it’s super easy, but first, we need to calculate each emoji parameters.
In this code for each emoji we are generating its place on screen randomly (verticalFraction and horizontalFraction, all between 0f and 1f). And then fill out rest of the params depending on verticalFraction. InitialScale — interpolating with min and max scale using verticalFraction, same for duration of animation.
Next step would be to layout all this emojis depending on their vertical and horizontal fractions on the screen.

Works like a charm! Each time emojis appear on screen they have different coordinates, scale and duration. So basically this layout knows nothing about each emoji animating. It just layout’s all of them and when each particle emoji layouted, it starts animation.
Last step would be to add slide in motion to all of emojis. For this we can use a library mechanism called AnimatedVisibility. Don’t forget that we also need to stretch our emojis layout a bit during animation to make it seem like top emojis moving faster that bottom.
And after playing a bit with parameters i got this:

This is the final result. Hope you enjoyed the reading. If you are interested in Jetpack Compose animations visit this documentation. All source code is available on GitHub.
Cheers!