Page Transitions with Framer Motion

Loading

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, and exit 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 like motion.div, you can use motion 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: The staggerChildren property introduces a delay between the animations of child elements (such as the heading and paragraph).
  • variants: Variants are reusable animation states. The hidden and visible states define how the elements should animate in or out.

Leave a Reply

Your email address will not be published. Required fields are marked *