Framer Motion is a popular animation library for React that helps create smooth and interactive animations. It offers easy-to-use components and APIs to implement animations such as page transitions, hover effects, and scroll-based animations. By using Framer Motion, you can enhance the user experience of your React application by adding smooth page transitions between different routes or views.
1. Setting up Framer Motion
Before you can start using Framer Motion, you need to install it in your React project. If you don’t have it installed yet, run:
npm install framer-motion
or, if using yarn:
yarn add framer-motion
2. Creating Basic Page Transitions with Framer Motion
To create page transitions, you can wrap your page components with motion.div
, which is a special type of div
that allows you to apply animations. For page transitions, you’ll also need to integrate Framer Motion
with React Router to animate route changes.
Example using React Router and Framer Motion:
First, let’s set up React Router:
npm install react-router-dom
Then, configure the routing and animations.
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import { motion } from 'framer-motion';
// Home Page
const Home = () => (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 1 }}
>
<h1>Home Page</h1>
<p>Welcome to the homepage!</p>
<Link to="/about">Go to About</Link>
</motion.div>
);
// About Page
const About = () => (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 1 }}
>
<h1>About Page</h1>
<p>Learn more about us!</p>
<Link to="/">Go to Home</Link>
</motion.div>
);
// App Component
function App() {
return (
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
);
}
export default App;
Explanation:
motion.div
:motion.div
is a special type of div provided by Framer Motion that allows animations to be applied directly to the element.initial
,animate
,exit
: These props are used to define the animation states.initial
is the starting state,animate
is the final state, andexit
is the state when the component is unmounted.transition
: This defines how the animation should occur, such as the duration and easing.React Router
: We use React Router to switch between pages and Framer Motion to animate the page transitions.
3. Handling Page Transitions with AnimatePresence
When transitioning between pages, you may want to animate elements when they are removed from the DOM. AnimatePresence
from Framer Motion is used to enable animations for components as they exit or are removed from the DOM.
Example with AnimatePresence
:
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import { motion, AnimatePresence } from 'framer-motion';
const Home = () => (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 1 }}
>
<h1>Home Page</h1>
<p>Welcome to the homepage!</p>
<Link to="/about">Go to About</Link>
</motion.div>
);
const About = () => (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 1 }}
>
<h1>About Page</h1>
<p>Learn more about us!</p>
<Link to="/">Go to Home</Link>
</motion.div>
);
function App() {
return (
<Router>
<AnimatePresence exitBeforeEnter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Switch>
</AnimatePresence>
</Router>
);
}
export default App;
Explanation:
AnimatePresence
: This component ensures that exit animations are triggered when a component is unmounted. Without it, the exit animations wouldn’t work properly when switching between routes.exitBeforeEnter
: This prop ensures that the exit animation completes before the new page starts animating in, creating a smoother transition.
4. Animating Specific Elements on a Page
You can animate individual elements within a page (e.g., buttons, images) in addition to animating the entire page transition.
const About = () => (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 1 }}
>
<h1>About Page</h1>
<motion.button
initial={{ x: -200 }}
animate={{ x: 0 }}
transition={{ duration: 0.5 }}
>
Learn More
</motion.button>
</motion.div>
);
In this example:
- Button Animation: We are animating the button’s position (
x
axis) when the page is rendered, making it slide in from the left. motion.button
: Just likemotion.div
, you can usemotion
with any HTML element (e.g.,motion.button
,motion.img
).
5. Adding Advanced Transitions (e.g., Staggered Animations)
For more complex animations, like staggered transitions for multiple elements on a page, you can use Framer Motion’s staggerChildren
to create a delay between the animations of child elements.
const Page = () => (
<motion.div
initial="hidden"
animate="visible"
exit="hidden"
variants={{
hidden: { opacity: 0 },
visible: { opacity: 1, transition: { staggerChildren: 0.3 } },
}}
>
<motion.h1 variants={{ hidden: { opacity: 0 }, visible: { opacity: 1 } }}>
Welcome to My Page
</motion.h1>
<motion.p variants={{ hidden: { opacity: 0 }, visible: { opacity: 1 } }}>
This is an example of a staggered animation.
</motion.p>
</motion.div>
);
In this example:
staggerChildren
: ThestaggerChildren
property introduces a delay between the animations of child elements (such as the heading and paragraph).variants
: Variants are reusable animation states. Thehidden
andvisible
states define how the elements should animate in or out.