Advanced page transitions with Framer Motion in React allow for smooth, interactive, and highly customizable transitions when navigating between pages or changing components. Framer Motion is a popular animation library that makes creating sophisticated animations and transitions in React applications easy.
Here’s how to implement advanced page transitions using Framer Motion.
1. Install Framer Motion
Before we begin, make sure you have Framer Motion installed in your React project. You can install it via npm or yarn.
npm install framer-motion
or
yarn add framer-motion
2. Basic Setup for Page Transitions
The idea is to apply animations when transitioning between different pages. We can do this using the motion.div
component provided by Framer Motion, along with React Router (for page routing). You can create transition effects on the page level or component level.
npm install react-router-dom
Once React Router is installed, let’s set up a basic React Router setup for page transitions.
3. React Router Setup for Navigation
In the following example, we will use React Router to navigate between different pages and apply Framer Motion transitions.
Example of App.js
with React Router and Framer Motion:
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { motion } from 'framer-motion';
import HomePage from './HomePage';
import AboutPage from './AboutPage';
import ContactPage from './ContactPage';
const App = () => {
return (
<Router>
<Switch>
<Route exact path="/">
<PageTransition>
<HomePage />
</PageTransition>
</Route>
<Route path="/about">
<PageTransition>
<AboutPage />
</PageTransition>
</Route>
<Route path="/contact">
<PageTransition>
<ContactPage />
</PageTransition>
</Route>
</Switch>
</Router>
);
};
const PageTransition = ({ children }) => {
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
{children}
</motion.div>
);
};
export default App;
Explanation:
- React Router is used to handle different routes like
/
,/about
, and/contact
. - Framer Motion’s
motion.div
component is wrapped around the children (i.e., the page content), which applies animation during page transitions. - The
initial
,animate
, andexit
properties control the page fade-in/fade-out effect, providing smooth transitions as the page enters and leaves.
4. Advanced Transition Techniques
4.1 Slide Transition between Pages
If you want to have a slide-in effect (i.e., pages slide in from the right or left), you can modify the motion.div
properties.
const PageTransition = ({ children }) => {
return (
<motion.div
initial={{ x: "100%" }}
animate={{ x: 0 }}
exit={{ x: "-100%" }}
transition={{ type: "spring", stiffness: 300 }}
>
{children}
</motion.div>
);
};
Explanation:
- The
x
values represent horizontal movement.100%
means the page is initially off-screen to the right, and0
means it is in its normal position. - The
exit
property moves the page off-screen to the left (-100%
), creating a smooth exit animation. - The
spring
transition type gives a bouncy effect for the transition.
4.2 Scaling Transition
To create a scaling effect, where the page starts small and grows into full view, you can use the scale
property.
const PageTransition = ({ children }) => {
return (
<motion.div
initial={{ scale: 0.8 }}
animate={{ scale: 1 }}
exit={{ scale: 0.8 }}
transition={{ duration: 0.5 }}
>
{children}
</motion.div>
);
};
Explanation:
- The
scale
property is used to animate the scaling of the page. The page starts at 80% size (scale: 0.8
), then grows to its normal size (scale: 1
) when entering, and shrinks back to 80% when exiting.
4.3 Page Fade with Slide-in Content
In more complex transitions, you can animate the page fade along with individual elements inside the page sliding in from different directions. Here’s an example that combines a fade transition with content slide-ins:
const PageTransition = ({ children }) => {
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<motion.div
initial={{ x: "-100%" }}
animate={{ x: 0 }}
exit={{ x: "100%" }}
transition={{ type: "spring", stiffness: 300 }}
>
{children}
</motion.div>
</motion.div>
);
};
Explanation:
- The outer
motion.div
controls the page fade-in/fade-out. - The inner
motion.div
controls the content slide-in from the left (x: "-100%"
) and slide-out to the right (x: "100%"
).
4.4 Page Transitions with Nested Animations
You can also combine multiple animations inside each page. For example, you could animate the header, main content, and footer separately when navigating to a new page.
const PageTransition = ({ children }) => {
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<motion.header
initial={{ y: -50 }}
animate={{ y: 0 }}
exit={{ y: -50 }}
transition={{ duration: 0.5 }}
>
Header Content
</motion.header>
<motion.main
initial={{ x: "-100%" }}
animate={{ x: 0 }}
exit={{ x: "100%" }}
transition={{ type: "spring", stiffness: 300 }}
>
{children}
</motion.main>
<motion.footer
initial={{ y: 50 }}
animate={{ y: 0 }}
exit={{ y: 50 }}
transition={{ duration: 0.5 }}
>
Footer Content
</motion.footer>
</motion.div>
);
};
Explanation:
- The
header
,main
, andfooter
are each animated individually. The header animates in from the top (y: -50
), the content slides in from the left (x: "-100%"
), and the footer comes in from the bottom (y: 50
). - Each part of the page has its own animation settings, providing a more intricate page transition effect.
5. Combining Page Transitions with React Router AnimatePresence
Framer Motion provides an AnimatePresence component to enable animations when components are removed from the React tree (i.e., when navigating away from a page). Without AnimatePresence, the animation might not work when leaving a page.
import { AnimatePresence } from 'framer-motion';
const App = () => {
return (
<Router>
<AnimatePresence exitBeforeEnter>
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/about" component={AboutPage} />
<Route path="/contact" component={ContactPage} />
</Switch>
</AnimatePresence>
</Router>
);
};
Explanation:
AnimatePresence
wraps around routes to ensure smooth exit animations when a component is unmounted (e.g., when navigating away from a page).