How to use the Motion animation library with Astro

by Tomas Bankauskas

Motion is an animation library for JavaScript and React that offers a seamless way to create smooth and engaging animations.

With its hybrid engine, Motion combines hardware-accelerated DOM animations with support for animating various properties, including CSS, SVG, and Three.js objects. The library is highly flexible, featuring an intuitive API and rich functionality.

#TL;DR

To explore the Motion animation library, we will set up and customize Astro’s basic template, add the Motion library to the project, and create animation for a few site elements.

We will add a few sections (hero, features, and cta) to the index.astro page with placeholder content and Motion animations for these sections.

#Explore the example site and repo

Preview the deployed site and reference the repository for the code via the following links:

You can also follow the steps below to create this example from scratch on your local machine. Or use the deploy to Netlify button to deploy the example site to your Netlify account.

Deploy to Netlify

#Prerequisites

To get started, you’ll need Node.js v18 or higher. And to deploy your project to Netlify, you’ll need a Netlify account.

#Getting started with Astro

Let’s get started by installing the Astro Starter Kit: Basics template. Run the following command to create a new Astro project:

Terminal window
npm create astro@latest -- --template basics

#Adjust the Astro template

After setting up the template, remove the <Welcome /> component from the index.astro page, and then delete the Welcome.astro file in the components directory.

Add the hero, features, and cta sections to the index.astro page:

src/pages/index.astro (hero)
<section class="scrolling-section hero">
<h2>Animate Your UI with a Motion Library</h2>
<p>
Effortless animations, smooth transitions, and powerful interactions—all with an intuitive API designed for
developers of all skill levels. Elevate your web experience with high-performance motion.
</p>
<div class="btn-group">
<a class="btn-primary" href="https://developers.netlify.com/guides/">Learn more →</a>
</div>
</section>
src/pages/index.astro (features)
<section class="scrolling-section features">
<h2>Powerful Features, Seamless Animations</h2>
<p>
Motion.dev gives you the tools to create fluid, high-performance animations with ease. From simple transitions to
complex interactions, unlock the full potential of motion in your web projects.
</p>
<div class="card-grid">
<div class="card">
<h3>Simple & Declarative</h3>
<p>
With an intuitive API, Motion.dev makes animations easy to implement. Define motion properties directly in your
components without worrying about complex animation logic.
</p>
</div>
<div class="card">
<h3>Gesture & Scroll Animations</h3>
<p>
Enhance interactivity with built-in support for gestures, scroll-based animations, and dynamic effects. Create
immersive experiences that respond to user input.
</p>
</div>
<div class="card">
<h3>Performance Optimized</h3>
<p>
Built for speed, Motion.dev leverages hardware acceleration and optimized rendering techniques to keep
animations smooth and efficient, even in complex appdivcations.
</p>
</div>
<div class="card">
<h3>Flexible & Customizable</h3>
<p>
Tailor animations to fit your design needs with a highly flexible system. Adjust easing, duration, and
keyframes, or create custom animations that match your brand's style.
</p>
</div>
</div>
</section>
src/pages/index.astro (cta)
<section class="scrolling-section cta">
<h2>Ready to Animate? Let's Get Started!</h2>
<p>
Integrate the Motion library into your Astro project and create stunning, high-performance animations with ease.
Start building today!
</p>
<div class="btn-group">
<a class="btn-primary" href="https://developers.netlify.com/guides/">Start Animating →</a>
</div>
</section>

Note

All sections have the .scrolling-section CSS selector, which we will use later to target and animate these sections on the page.

You can copy CSS from the example repository or write it yourself. To try different Motion library functions, we need one-column (hero, cta) and two-column (features) layouts for CSS styling.

#Install Motion animation library

Once you have the template ready and set up in your local environment, install the Motion animation library via the NPM package.

Terminal window
npm install motion

#Add Motion animation library

To import the Motion library in index.astro (src/pages/index.astro) page, use <script> tag:

src/pages/index.astro
<script>
import {} from "motion";
</script>

The Motion library provides a variety of functions to create animations. In this guide, we use the following functions:

  • animate: This is the core function for applying animations to elements, allowing you to change properties like opacity, position, and more.
  • stagger: Creates a delay between the animations of multiple elements, so they animate in sequence instead of all at once.
  • inView: Triggers animations when an element comes into view as you scroll the page.

To use the animation functions, you need to import them into your JavaScript object.

src/pages/index.astro
<script>
import { animate, stagger, inView } from "motion";
</script>

#Animate the UI

The goal is to animate the hero, features, and cta sections on the index.astro page when it loads and as the user begins to scroll.

A simple fade-in animation will be applied to all sections, making them appear gradually as the user scrolls. As for the features section, which has the grid of cards, we will use the stagger function to animate each card with a slight delay, adding a more dynamic and natural effect.

To select elements for animation, we use the .scrolling-section and .card CSS selectors, which are already present in the example markup:

import { animate, stagger, inView } from "motion";
inView(
".scrolling-section",
(element) => {
animate(element, { opacity: [0, 1], y: [50, 0] }, { ease: [0.39, 0.24, 0.3, 1], duration: 1 });
const cards = element.querySelectorAll(".card");
if (cards.length > 0) {
animate(cards, { opacity: [0, 1], y: [25, 0] }, { type: "spring", delay: stagger(0.25, { startDelay: 0.25 }) });
}
},
{ amount: 0.25 }
);

Let’s break it down step by step to understand what this JavaScript code is doing.

#inView

inView(".scrolling-section", (element) => { ... }, { amount: 0.25 });
  • The inView function detects when elements matching the selector .scrolling-section appear in the viewport.
  • When at least 25% { amount: 0.25 } of the element is visible, the callback function is triggered.

#animate

animate(element, { opacity: [0, 1], y: [50, 0] }, { ease: [0.39, 0.24, 0.3, 1], duration: 1 });
  • Animates the selected element with the .scrolling-section CSS selector by fading it in from opacity 0 to 1 and moving it upward from y: 50px to y: 0px.
  • A custom cubic bezier easing (ease: [0.39, 0.24, 0.3, 1]) for smooth motion.
  • The animation lasts 1 second (duration: 1).

#Animate .card elements

const cards = element.querySelectorAll(".card");
if (cards.length > 0) {
animate(cards, { opacity: [0, 1], y: [25, 0] }, { type: "spring", delay: stagger(0.25, { startDelay: 0.25 }) });
}
  • If .card elements exist inside .scrolling-section each one is animated
  • Fading in (opacity 0 to 1).
  • Moving upward from y: 25px to y: 0px.
  • Using a spring animation (type: "spring") for a more natural bounce effect.
  • Each .card appears one after another (stagger(0.25)) with a 0.25s start delay { startDelay: 0.25 }.

#Conclusion

This guide walked you through setting up an Astro project, adding structured sections, and applying Motion animations. Integrating the Motion animation library with your web project allows you to create smooth, high-performance animations with minimal effort.