5 Cool Animations in React with Framer Motion
Tags: react, javascript, css, animation
Published: 2023-10-25 07:25:30

Animations are a powerful tool to enhance user experience, and when it comes to creating animations in React, Framer Motion is a popular library of choice. 
In this blog post, we'll explore 5 cool animations you can create in React using Framer Motion.

> Check out this [post on my blog] (https://salehmubashar.com/blog/5-cool-animations-in-react-with-framer-motion) 

---

Framer Motion is a versatile animation library for React, known for its simplicity and powerful animations. If you're looking for an alternative, you can explore React Spring, which I've covered in [my article here](https://salehmubashar.com/blog/animations-with-react-spring).

Now, let's dive into five cool animations you can create in React using Framer Motion!

##1. Button Tap Animation

This is a really simple yet fun effect to add to your buttons. It adds a fun touch to your buttons by scaling them when tapped. To add this, we can make use of the `whileTap` property. We can scale the button up or down within this property:

```react
import { motion } from "framer-motion";

function App() {
  return (
    <motion.button
      whileTap={{ scale: 0.85 }}
    >
      Click me!
    </motion.button>
  );
}

export default App;
```
The demo is provided below:

{% codesandbox j535s5 %}

##2. Text Typing Animation

Text typing animations, created with Framer Motion, add a playful touch to engage users, useful for loading messages and chat simulations.
To achieve this effect, we will take a sentence we want to display and convert it into an array of words. Next, we will map this array out and add an animation and transition on the opacity, as well as a delay that creates the typing effect.

```react
import "./styles.css";
import { motion } from "framer-motion";

function App() {
  const text = "Framer Motion is a really cool tool".split(" ");

  return (
    <div className="App">
      {text.map((el, i) => (
        <motion.span
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{
            duration: 0.25,
            delay: i / 10
          }}
          key={i}
        >
          {el}{" "}
        </motion.span>
      ))}
    </div>
  );
}

export default App;
```
The demo is provided below:

{% codesandbox 7ydrk3 %}


##3. Stagger Animations
Stagger animations, as demonstrated in dropdowns and navigation menus, involve animating elements in a sequential manner, each appearing one after the other, with a subtle delay distinguishing their appearances. You can create much more complex effects using this method as opposed to the ones mentioned above.

In this example, we will animate in some menu items when a menu button is clicked. We will use the `stagger` function alongside `motion` and `useAnimate`. Learn more about useAnimate [here](https://www.framer.com/motion/use-animate/).

```react
import { useAnimate, stagger, motion } from "framer-motion";
```

Start by creating an array that holds the list of items to be displayed in the menu. To achieve this effect, the list items are initially mapped within a `<ul>` element. When the button is clicked, the `<ul>` is first made visible. Then, the list items will animate in a staggered fashion one by one.

We will utilize the `useAnimate` hook to generate the animations for both the `<ul>` and `<li>` elements. These animations will be triggered by a change in state, which can be toggled using the button.

```react
import "./styles.css";
import { useState, useEffect } from "react";
import { useAnimate, stagger, motion } from "framer-motion";

export default function App() {
  const [open, setOpen] = useState(false);
  const [scope, animate] = useAnimate();
  const items = ["Item 1", "Item 2", "Item 3", "Item 4"];

  // the stagger effect
  const staggerList = stagger(0.1, { startDelay: 0.25 });

  // create the animations that will be applied
  // whenever the open state is toggled

  useEffect(() => {
    animate(
      "ul",
      {
        width: open ? 150 : 0,
        height: open ? 200 : 0,
        opacity: open ? 1 : 0
      },
      {
        type: "spring",
        bounce: 0,
        duration: 0.4
      }
    );
    animate(
      "li",
      open
        ? { opacity: 1, scale: 1, x: 0 }
        : { opacity: 0, scale: 0.3, x: -50 },
      {
        duration: 0.2,
        delay: open ? staggerList : 0
      }
    );
  }, [open]);

  return (
    <div className="App" ref={scope}>
      <motion.button onClick={() => setOpen(!open)} whileTap={{ scale: 0.95 }}>
        Menu
      </motion.button>
      <ul>
        {items.map((item, index) => (
          <motion.li key={index}>{item}</motion.li>
        ))}
      </ul>
    </div>
  );
}
```
The demo is provided below:

{% codesandbox v9qzn9 %}

##4. Count Animation
This effect is commonly used for displaying numbers and statistics and is often used in countdown timers. 

To implement this effect, we'll utilize `MotionValues` to monitor the state and velocity of the values, and we'll employ the `animate` function to specify the animation duration.

```react
import { motion, useMotionValue, animate } from "framer-motion";
```
We will pass it an initial state or value which will be 0. Then we will count up to 50. Keep in mind that you need to round the count to make sure no decimal points are shown. For this, `useTransform` will be used.

```react
import "./styles.css";
import { motion, useMotionValue, useTransform, animate } from "framer-motion";
import { useEffect } from "react";

export default function App() {
  const count = useMotionValue(0);
  const rounded = useTransform(count, Math.round);

  useEffect(() => {
    const animation = animate(count, 50, { duration: 2 });

    return animation.stop;
  }, []);

  return <motion.h1>{rounded}</motion.h1>;
}
```

In the code above, `animation.stop` is being used to stop the animation when the component is unmounted. This ensures that the animation is terminated, and any resources associated with the animation are released.

{% codesandbox np4qz5 %}

##5. Scroll Reveal Animations

Scroll reveal animations are a great way to make websites engaging and appealing to users. For instance, you can create effects like fading an element in or smoothly sliding it into view as it becomes visible on the screen.
To create this effect, we can use the `whileInView` and `viewport` props. Here's an example of how to use these props to achieve a scroll reveal effect:

```react
<motion.div
  initial="hidden"
  whileInView="visible"
  viewport={{ once: true }}
/>
```
We can add animations and effects within the `initial` and `whileInView` props. Variants can also be used for this purpose. In the example below, we are going to slide in some elements when they come into view:

```react
import React from "react";
import { motion } from "framer-motion";

function Card({ text, index }) {
  return (
    <motion.div
      className="card"
      initial={{
        opacity: 0,
        // if odd index card,slide from right instead of left
        x: index % 2 === 0 ? 50 : -50
      }}
      whileInView={{
        opacity: 1,
        x: 0, // Slide in to its original position
        transition: {
          duration: 1 // Animation duration
        }
      }}
      viewport={{ once: true }}
    >
      <p className="card-text">{text}</p>
    </motion.div>
  );
}

export default Card;
```

You can set `viewport={{ once: true }}` to false if you want the effect to occur every time the element is scrolled into or out of view.

{% codesandbox 3lvdm5 %}

---

Thanks for reading!
Check out this [post on my blog too](https://salehmubashar.com/blog/5-cool-animations-in-react-with-framer-motion)!