DEV Community

Cover image for 5 Cool Animations in React with Framer Motion
Saleh Mubashar
Saleh Mubashar

Posted on • Updated on • Originally published at salehmubashar.com

5 Cool Animations in React with Framer Motion

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


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.

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:

import { motion } from "framer-motion";

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

export default App;
Enter fullscreen mode Exit fullscreen mode

The demo is provided below:

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.

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;
Enter fullscreen mode Exit fullscreen mode

The demo is provided below:

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.

import { useAnimate, stagger, motion } from "framer-motion";
Enter fullscreen mode Exit fullscreen mode

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.

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

The demo is provided below:

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.

import { motion, useMotionValue, animate } from "framer-motion";
Enter fullscreen mode Exit fullscreen mode

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.

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>;
}
Enter fullscreen mode Exit fullscreen mode

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.

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:

<motion.div
  initial="hidden"
  whileInView="visible"
  viewport={{ once: true }}
/>
Enter fullscreen mode Exit fullscreen mode

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:

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;
Enter fullscreen mode Exit fullscreen mode

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.


Thanks for reading!
Check out this post on my blog too!

Top comments (2)

Collapse
 
random_ti profile image
Random

Really handy Article! Thanks for sharing

Collapse
 
salehmubashar profile image
Saleh Mubashar

thanks!