How to animate in React using framer motion

Framer Motion is a React animation library offering intuitive motion components, physics-based animations, and gesture support. Its component-based approach and declarative syntax provide advantages over CSS animations, enabling dynamic, engaging user interfaces for developers of all skill levels.

GraphQL has a role beyond API Query Language- being the backbone of application Integration
background Coditation

How to animate in React using framer motion

In this blog we will be demonstrating about an animation library for React called Framer Motion. If you are completely new to animations in CSS, refer to the blog how to animate in CSS.

What is FramerMotion?

Framer Motion is a powerful animation and gesture library for React that helps developers create beautiful and engaging user interfaces. Whether you're a seasoned developer or just getting started with animation, Framer Motion provides a simple and intuitive way to add animations and interactions to your web projects. It uses a prop-based approach to create animations using motion components. Think of the motion component as a plain HTML or SVG element, supercharged with animation capabilities.

How to install it?

Run the below command to install it in your project:


npm install framer-motion

How to use it?

Once you install it, you can now use it in your react app by importing it like below:


import { motion } from "framer-motion"

Now that we have understood how to set up Framer motion in our project, let us create a simple sliding box animation using it, and right away you will see how easy it is to do that using this library.

In your App component write the below code.

App.js


import { motion } from 'framer-motion';
function App() {
  return (
    <div className='App'>
      <h1>Framer Motion Example</h1>
      <motion.div className='box' animate={{ x: 500 }} />
    </div>
  );
}

export default App;

That’s it! We have our animation ready! All we did was

  1. Replaced ‘div’ with ‘motion.div’
  2. Passed it a prop called ‘animate’

The only CSS I used here was the basic layout and giving width and height to the box.

index.css


* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
.App {
  width: 600px;
  margin: 0 auto;
  text-align: center;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
}

Now let's see what exactly we did here.

As I mentioned earlier, Framer Motion uses motion components. Think of it as “HTML tags with animation superpower” if you will. Each HTML tag will have a corresponding motion tag. Example, <motion.div />, <motion.svg />, etc.

These motion components now allow us to pass some extra props to them like animate, transition, and some more.

In the above example, we used <motion.div> and passed x: 500 as a value to animate prop. This is why our box shifted rightwards by 500px.

Framer uses “spring” as the default animation. It provides a cool effect of bouncing back to the final state which seems more natural and physics-friendly. But you can of course change these default animations and some more properties using transition prop.

For example,


<motion.div
        className='box'
        animate={{ x: 500 }}
        transition={{ ease: easeOut, duration: 2, repeat: Infinity }}
      />

Here, we have changed the animation to ‘easeOut’, increased the duration of the animation to 2 seconds, and made it run infinite times.

Why it's better than normal CSS?

Framer Motion provides a more powerful and flexible way to animate components compared to traditional CSS animations. Some of the key benefits of using Framer Motion include:

  1. Declarative syntax: Framer Motion uses a declarative syntax for defining animations, which makes it easier to understand and maintain. This is in contrast to the imperative approach used in CSS animations, which can make the code more difficult to understand.
  2. Component-based: Framer Motion animations are defined as components, which makes it easy to reuse and compose animations. This is in contrast to CSS animations, which are defined in a separate stylesheet and can be harder to reuse.
  3. Physics-based animations: Framer Motion includes a set of animation functions that are based on physics principles, such as spring, which makes it easy to create realistic and natural-feeling animations.
  4. Interaction support: Framer Motion provides a set of gesture functions that can be used to create complex interactions, such as drag-and-drop, swipe, and pinch-to-zoom.
  5. Animation controls: Framer Motion provides a set of controls for controlling animations, such as play, pause, and reverse, which can be useful for creating more advanced animations.

Keyframes

You can also create keyframes for creating different animations at different points in time. This can be done by simply providing an array of values instead of a single value for any property.


import { motion } from 'framer-motion';
function App() {
  return (
    <div className='App'>
      <h1>Framer Motion Example</h1>
      <motion.div
        className='box'
        initial={{ x: 0, borderRadius: '0%' }}
        animate={{
          x: [0, 250, 500],
          borderRadius: ['0%', '50%', '0%'],
        }}
        transition={{ duration: 3, repeat: Infinity }}
      />
    </div>
  );
}
export default App;

In the above example, we provided an array of values for x and borderRadius properties. So, the animation will go through each value in the sequence.

By default, each keyframe will be spaced evenly throughout the animation. You can override this by setting the times option via transition.

times is an array of the same length as the keyframes array, with numbers between 0 and 1 defining where in the animation each keyframe should be hit.


<motion.div
        className='box'
        initial={{ x: 0, borderRadius: '0%' }}
        animate={{
          x: [0, 250, 500],
          borderRadius: ['0%', '50%', '0%'],
        }}
        transition={{ duration: 3, repeat: Infinity, times: [0, 0.8, 1] }}
      />

Here, we have given times: [0, 0.8, 1] which means 0%, 80%, and 100% of our total animation duration i.e. 0s, 2.4s, and 3s.

Gestures

In Framer Motion, gestures are a way to add touch and mouse interactions to elements on a webpage. They allow users to interact with elements in a more natural and intuitive way. Framer motion currently has support for hover, tap, pan, and drag gesture detection.

For example, you can create a draggable element by adding the drag prop to the element and defining the x and y constraints of the draggable area.


<motion.div
        drag
        dragConstraints={{ left: 0, right: 100, top: 0, bottom: 0 }}
        style={{ width: 100, height: 100, background: 'blue' }}
      />

In the above example, we added the drag prop to our motion component, which allowed it to be dragged on the screen. Further, we also added some constraints to the extent where our component should be draggable. Here, we can drag the box only up to 100px on the right side. If we drag it any more, it will come back to the 100px position. Also, note how the box very naturally slides to its final position. This is because of the default spring animation type. So cool, right?

Let us see one more example of the hover gesture.


<motion.div whileHover={{ scale: 1.1 }} className='box' />

Here, we are scaling our box if we hover over it. It will also go back smoothly to its initial state once we stop hovering on it.

Conclusion

Overall, Framer Motion is an excellent tool for creating dynamic and engaging animations and interactions on the web. It's easy to use and highly customizable, making it a great choice for developers of all skill levels. I hope that you've found this blog helpful and informative and that you're now inspired to incorporate Framer Motion into your own projects. We encourage you to continue learning and experimenting with this library to create even more amazing animations and interactions.

Hi, I am Omkar Jadhav. I am a frontend developer with a passion for problem-solving and creating responsive and user-friendly web interfaces that deliver exceptional user experiences.

Want to receive update about our upcoming podcast?

Thanks for joining our newsletter.
Oops! Something went wrong.