Animations that feel alive using GSAP randomization
Animations can make web apps feel more fun and alive. In this tutorial, learn how to use GSAP, randomization, and the MotionPath plugin to make your animations feel more lively.
Animations are more fun — and more engaging — when they feel “alive”. Let’s build a hero section to learn how to take animations from stiff and robotic to something much more natural-feeling with just a few lines of code using GreenSock.
Rather watch along than read? No problem!
A video version of this tutorial is available on YouTube. Don’t forget to subscribe!
Set up the project with HTML and CSS
For our animation to work, we need four components:
- A cutout image to be in the foreground
- A container with a background image that will hold our animations
- A button to trigger new animations
- A template that contains the markup we want to animate on each button click
To get the starter code that contains the styles and markup used in this tutorial, clone the start
branch of the repo:
Start the dev server
To start the site in local dev mode, run the following command:
The server will start up the site running at http://localhost:5173
. Open it in your browser and you should see a hero banner extolling the virtues of donuts:
Animate an image whenever the button is clicked
First, let’s get a basic animation in place. We’ll be using GreenSock — also known as GSAP — because it’s extremely powerful, free, and compatible with any framework (or no framework at all).
To do that, we will:
- Get the template, container, and button using
document.querySelector
so we can work with them - Create a variable called
endY
that will tell the heart where it should be at the end of the animation - Add an event listener to the button for click events and prevent the default behavior
- Create a copy of the heart image
- Add the cloned heart inside the container
- Use GSAP to animate the heart using
.to()
, from its starting position at the bottom of the container to theendY
value, which is out of view at the top - At the end of the animation, remove the heart
Removing the heart at the end is important with an animation like this. Since someone can click the button an unlimited number of times, we need to make sure we’re not continuously increasing the number of DOM nodes on the page.
Save these changes, then click the button in your browser. The heart will animate in exactly the same way every time you click.
This is good, but we can make it better. Let’s add some randomness to make the animation feel less robotic.
Start the animation from a random position in the container
To make the animation feel a little more alive, we’ll have each heart generate from a random position along the bottom of the container. To do that, we’ll need to:
- Figure out the width of the container
- Set the width of the heart
- Get a random value between 0 and the width of the container, minus the width of the heart
GSAP provides a helpful set of utility classes, including a random
helper. We’ll use that to randomize the start position.
Add the following changes to src/main.ts
:
Save and click the button in your browser a few times. The hearts now show up at different sizes and from different positions.
By randomizing the starting position and size, the animation feels more fun and “alive”. But we can do better!
Add a “floating” effect to the animation path
To polish off the animation, we’ll bring in GSAP’s MotionPathPlugin, which will allow us to make the hearts “float” as they animate upward. Combined with some randomization, we can make the hearts look like they’re floating bubbles, drifting upward organically as we click.
To accomplish this, we need to:
- Import and register the MotionPathPlugin
- Create a
floatDirection
variables to hold-1
or1
, which we’ll use to determine if the heart should float left or right - A function called
getNextX()
to determine the distance each heart should drift (using thefloatDirection
to determine to which side it drifts) - Replace the
y
value ingsap.to()
withmotionPath
config.- The hearts should turn to match their path direction.
autoRotate: 90
sets the top of the image (default is right side) as the part that should face the path - Setting
curviness: 1.25
“softens” the float. Try setting it to0
to see the hearts follow a jagged path
- The hearts should turn to match their path direction.
- Finally, add an easing function to give the float a bit more dynamism.
Make the following changes to src/main.ts
to update the animation:
Save and click the button in your browser. You’ll see floaty animated hearts!
Give your animations a little more life with randomized values
Adding animation makes apps more engaging, more interactive, and more likely to be shared. And now that you know how to use randomization to make your animations feel a little more alive, you’re well on your way to building engaging, interactive, and shareable apps of your own!
Share what you build in the comments! Don’t forget to like and subscribe. If you want to learn more about animation, check out the recommended video. See you next time.