How to implement Confetti animation
We are currently focused on implementing animation for better User Experience. One of the animations that we implemented lately is Confetti.
There were some learnings while writing animation of Confetti. I will explain how to do it in this article.
Confetti animation prototype
Our designer provided the prototype as below using Anima which exports her sketch and automatically generates code.
We found out that we cannot simply auto-generated code from the Anima app. So we decided to create animation by ourselves.
There were two steps to create animation capturing real confetti movement which is 1) Confetti is thrown and 2) Confetti is falling down.
Both speeds are different. When we throw Confetti, they reach to the top quickly and they will fall down slowly.
The speeds of each step should vary as below.
1) Confetti is thrown (Fade-in animation)
2) Confetti is falling down (Fade-out animation)
Use cubic-bezer
Normally adding eitherlinear
or ease
in transition-timing-function
is sufficient for simple animations. When it comes to our Confetti animation, we know that we have to add customized cubic-bezier.
There is a cool website where you can create your desirable cubic-bezier.
As there are two different steps in our Confetti animation, I tried to implement both cases in one cubic-bezier
value as below.
Here is a piece of code. I used avalue cubic-bezier(.17,.5,.9,.02)
which I got from the above website.
@keyframes confetti-fade-in-and-out {
15% {
opacity: 0;
margin-top: 0;
}
35% {
opacity: 1;
margin-top: -50px;
}
55% {
opacity: 1;
margin-top: -50px;
}
100% {
opacity: 0;
margin-top: 0;
}
}
@mixin confetti-animation() {
animation: confetti-fade-in-and-out 3.2s cubic-bezier(.17,.5,.9,.02) ;
position: absolute;
opacity: 0;
}
This code generates the following animation.
As you can see, linear-in for fade-in animation and ease-out for fade-out animation are not visible and it’s still far from the prototype.
We learned that we cannot pack two timing/speed in one cubic-bezier.
So we decided to split it into two.
Use two keyframes
In order to have different timing and speed for Confetti movement, we created two keyframes. I wrapped Confetti img
with div
and pass keyframes to each of the elements.
<div className=’confetti-wrapper’>
<img src=’./img/Confetti.svg’ className=’confetti’ />
</div>
For fade-in animation, we used cubic-bezier(0,0.88,0.51,1)
We got this value from the prototype that our designer created in Anima.
@keyframes confetti-fade-in {
15% {
opacity: 0;
margin-top: 10px;
}
100% {
opacity: 1;
margin-top: -50px;
}
}
@mixin confetti-fade-in() {
animation: confetti-fade-in 3.2s cubic-bezier(0,0.88,0.51,1);
position: absolute;
opacity: 0;
}
For fade-out animation, we used cubic-bezier(0.84,0,1,1)
@keyframes confetti-fade-out {
0% {
opacity: 1;
margin-top: -50px;
}
100% {
opacity: 0;
margin-top: 10px;
}
}
@mixin confetti-fade-out() {
animation: confetti-fade-out 3.2s cubic-bezier(0.84,0,1,1);
position: absolute;
opacity: 0;
}
At first, we added delay
for fade-out animation, however, it didn’t work.
In the end, each fade-in and fade-out animation works perfectly without adding any delay
and using the same animation duration.
Add two keyframes to animation function
I was content with the result above, my colleague suggested me to add two keyframes in animation function.
Here is the code.
@keyframes confetti-fade-in {
15% {
opacity: 0;
margin-top: 0;
}
100% {
opacity: 1;
margin-top: -50px;
}
}
@keyframes confetti-fade-out {
0% {
opacity: 1;
margin-top: -50px;
}
100% {
opacity: 0;
margin-top: 0;
}
}
@mixin confetti-fade-in-and-out () {
animation: confetti-fade-in 1.6s cubic-bezier(0,0.88,0.51,1), confetti-fade-out 1.6s cubic-bezier(.84,0,1,1) 1.6s;
position: absolute;
opacity: 0;
}
First confetti-fade-in 1.6s cubic-bezier(0,0.88,0.51,1)
will be called. As 1.6s
delay is added in the last, confetti-fade-out 1.6s cubic-bezier(0.84,0,1,1)
will be called after fade-in animation.
Using this solution, we don’t have to add <div>
wrapper to have two keyframes. Simple and concise!
Summary
Let me summarise what we learned along the way.
- Making use of
cubic-bezier
to create customized animation - It’s possible to add two
keyframes
into one animation function to have different timing and speed of the animation
I hope this article helps you to unlock your limitation to create your desirable animations!
If you are curious about how we make use of animation for better UX, my colleague UX designer wrote about it in the following article.