DEV Community

Cover image for Introduction to Framer Motion
Jane Tracy 👩🏽‍💻
Jane Tracy 👩🏽‍💻

Posted on

Introduction to Framer Motion

Making cool animations with CSS is great but can be tricky when you want to create powerful ones. If you are not an expert in CSS this task can be more frustrating. With Framer motion, you don't need to be perfect in CSS, the hard work is already done for you. You just need to install the library, customize the values and create smooth animations.

What is Framer Motion

Framer Motion is an open-source React library to power production-ready animations. It will help you create fluid animations for the web across desktop and mobile. This makes creating complex animations easier, with its simple syntax. You can build gesture animation, variants, keyframes, drag, motion values, exit animations and more.

How to install Framer motion to your React project

  • For you to start using it, you have to install the library through the node package manager first.
npm install framer-motion
Enter fullscreen mode Exit fullscreen mode
  • Import it to your project
import { motion } from "framer-motion"
Enter fullscreen mode Exit fullscreen mode
  • To use it in your React components you have to use:

Motion Components

Motion components are the heart of framer motion. By including the props (properties) you can add gestures and animations to your components. Without incorporating it you can't animate anything at all. You can easily initiate it by including motion. before your div element.

  • Motion components accept props like animate and transition for basic animations. The props can include single or multiple objects that will have keys and values to induct motion.
  • let's start off by animating the title
import { motion } from "framer-motion"

<motion.h1
       animate={
         {fontSize: "3rem",
          x: 20, y: -10 
          }
       }>
        Welcome to Framer Motion
   </motion.h1>
Enter fullscreen mode Exit fullscreen mode

Before I start to explain the results, let's first understand the meaning of the positive and negative values in x and y.

  • To move to the right - Use a positive number
  • To move to the left - Use a negative number
  • To move upwards - Use a negative number
  • To move downwards - Use a positive number

This means our h1 will first increase it's the font size by 3 rem, move to the right by 20px and then move up by 10px. The default value uses a px unit but if you want to use rems, you have to state it as I did with font size.

Using Initial prop

Apart from animate prop you can use the initial prop that illustrates how the component will look like before the animate property is indicated. For example, we can say before the h1 is seen, it would be invisible and later on, it's seen on the browser.


<motion.h1
       initial = {{y: -300, opacity: 0}}
       animate={
         {opacity: 1,
          fontSize: "3rem",
          x: 20, y: -10 
          }
       }>
        Welcome to Framer Motion
   </motion.h1>
Enter fullscreen mode Exit fullscreen mode

The initial prop will make h1 be hidden first with an opacity 0, it will move from the top of the browser and settle on its original position. Then animate prop will be mounted as I explained in the previous section.

Transition prop

This prop determines how your animation will appear. You can control the delay, type and duration time for components. This creates a smooth transition and makes your animations more appealing to the eye.
Types of transition for framer motion

  • Tween- This is a linear or easing curve and given duration.
  • Spring- It is based on mass, damping and stiffness.
  • Inertia - It includes spring and friction combined scroll physics.
<motion.h1
        initial={{ y: -1000, opacity: 0 }}
        animate={{ opacity: 1, fontSize: "3rem", x: 20, y: 15 }}
        transition={{type:'spring', duration: .5, delay: .2 }}
      >
        Welcome to Framer motion
  </motion.h1>
Enter fullscreen mode Exit fullscreen mode

Here the h1 transition will be spring which is also the default type of transition for Framer Motion. The duration determines how long the animation will be. In this case, the title will animate for 0.5 seconds and it will be delayed too.

whileHover prop

In order to create hover animations, you have to use the whileHover prop. This determines how the components will be when a user hovers over it.

  • Example let create a simple button and create some hover animations
<motion.button
   whileHover={{
     scale: 1.02,
     color: '#231738'
    }}
   transition={{duration: .3}}
  className="Button">Click me
 </motion.button>
Enter fullscreen mode Exit fullscreen mode

In transition, you can also add yoyo key and give it a value of Infinity to make the hover animation last longer. Creates a heartbeat type of animation.

Variants

Variants are visual states that can be defined externally from a Frame and passed in via the variants property. This helps us to apply the dry code method. Where there is no repetition of properties in the components. You can create values for initial, animate, hover or press.

const titleVariants = {
 hidden:{
  y: -1000, 
  opacity: 0
 },
 visible:{
  opacity: 1, fontSize: "3rem", x: 20, y: 15,
  transition:{
    type: "spring", duration: 0.5, delay: 0.2
  }
 },
}

<motion.h1
   variants={titleVariants}
  initial= 'hidden'
  animate= 'visible'
>
  Welcome to Framer motion
 </motion.h1>
Enter fullscreen mode Exit fullscreen mode

By using variants it makes our code components cleaner and less confusing to others who will review our code later on.
The properties of the variants can be inherited to the other children. Hence variants with the same name will be triggered.
Let's continue with our example and include the button variants.

const textVariants = {
  hidden: {
    x: "-100vw",
    opacity: 0
  },
  visible: {
    opacity: 1,
    fontSize: "1.5rem",
    x: 0,
    y: 15,
    transition: {
      type: "spring",
      duration: 0.5
    }
  }
};

const titleVariants = {
 hidden:{
  y: -1000, 
  opacity: 0
 },
 visible:{
  opacity: 1, fontSize: "3rem", x: 20, y: 15,
  transition:{
    type: "spring", duration: 0.5, delay: 0.2
  }
 },
}

const buttonVariants = {
  hover: {
    scale: 1.1,
    backgroundColor: "#d62ba3",

    transition: {
      duration: 0.5,
      yoyo: Infinity
    }
  }
};

<motion.h1 
variants={titleVariants} 
initial="hidden" 
animate="visible">
   Welcome to Framer motion
</motion.h1>

<motion.p
 variants={textVariants}
>
The title will increase in size move to the right and downwards      </motion.p>

<motion.button
  variants={buttonVariants}
  whileHover="hover"
  className="Button"
>
   Click me
</motion.button>

Enter fullscreen mode Exit fullscreen mode

As you can see, the paragraph inherited the variants from the parent component, the h1. This makes it easier to write more complex animations to your components.

Animating Routes
  • First, add the Router tag in the index.js
import { BrowserRouter as Router } from 'react-router-dom';

<React.StrictMode>
    <Router>
      <App />
    </Router>
</React.StrictMode>
Enter fullscreen mode Exit fullscreen mode
  • import useLocation from react-router and save useLocation function in a variable. You can do this in the App.js file
import { Route, Switch, useLocation } from "react-router-dom";

const location = useLocation();
Enter fullscreen mode Exit fullscreen mode
  • wrap the switch with Animate presence
<AnimatePresence exitBeforeEnter>
 <Switch location={location} key={location.key}>
   <Route exact path="/" exact component={Home}/>
   <Route exact path="/about" exact component={About}/>
   <Route exact path="/recipe" exact component={Recipe}/>
   <Route exact path="/order-now" exact component={Order}/>
 </Switch>
</AnimatePresence>
Enter fullscreen mode Exit fullscreen mode
  • Add the exit prop to the pages. This determines how the page will animate when you exit it to another page.
const exitVariants = {
  hidden: { 
    opacity: 0, 
  },
  visible: { 
    opacity: 1, 
    transition: { duration: 1 }
  },
  exit: {
    x: "100vh",
    transition: { ease: 'ease' }
  }
};

//add the variants
<motion.div className="home container"
  variants={exitVariants}
  initial="hidden"
  animate="visible"
  exit="exit"
 >

Enter fullscreen mode Exit fullscreen mode

This means the page will exit from the right instead of the left side of the browser.
Add the exitVariants to the other pages in your projects and there you go. You have animated your routes successfully. 🎉

Resources

In conclusion

Framer motion is a great animation library for your next React project. It makes it easy to create complex animations without stressing out about having advanced skills in CSS animations. By creating simple props like animate, initial, hover or press, you make your website more fun to interact with. To best honest who doesn't love playing around with animations from sites they visit.
As long as you don't overuse the animations, your website will be more appealing to users.

relaxing girl gif

If you find this post useful, share it with your peers or beginners who are learning Framer Motion and might find the content useful to their journey. You can also buy me coffee. 🙂

Buy Me A Coffee

Top comments (3)

Collapse
 
thebinaryguy profile image
TheBinaryGuy

I believe 'yoyo' is deprecated:

  • Deprecated:
yoyo: Infinity
Enter fullscreen mode Exit fullscreen mode
  • New way:
repeat: Infinity,
repeatType: 'reverse'
Enter fullscreen mode Exit fullscreen mode
Collapse
 
igorbrands profile image
Igor Cantelmo

Yes, it is.

Collapse
 
whyps_ed4c1a3c61919efa6ed profile image
Whyps