Categories
React

Framer Motion — Dynamic Variants and Animation Controls

Spread the love

With the Framer Motion library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with Framer Motion.

Dynamic Variants

We can animate each element differently with dynamic variants.

For example, we can write:

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

const variants = {
  visible: (i) => ({
    opacity: 1,
    transition: {
      delay: i * 0.3
    }
  }),
  hidden: { opacity: 0 }
};

const items = [
  {
    text: "foo",
    id: 1
  },
  {
    text: "bar",
    id: 2
  },
  {
    text: "baz",
    id: 3
  }
];

export default function App() {
  return (
    <div className="App">
      <motion.ul>
        {items.map(({ text, id }, i) => (
          <motion.li
            key={id}
            initial="hidden"
            custom={i}
            animate="visible"
            variants={variants}
          >
            {text}
          </motion.li>
        ))}
      </motion.ul>
    </div>
  );
}

to animate the li elements in App .

We set the delay of each item differently with the transition.delay property.

i is what we passed into the custom prop, and that’s what we get in the function.

variants has animation styles for different stages.

initial has the property name of the initial styles before animation.

And the animate prop has the property name of the final styles that are applied after the animation.

Component Animation Controls

We can control when animations start or stop.

To do this, we use the useAnimation hook to create the controls object, which lets us control when animation starts and ends.

Starting an Animation

We can use the controls.start method to start an animation.

For example, we can write:

import React, { useEffect } from "react";
import { motion, useAnimation } from "framer-motion";

export default function App() {
  const controls = useAnimation();

  useEffect(() => {
    const timer = setTimeout(() => {
      controls.start({
        x: "100%",
        backgroundColor: "green",
        transition: { duration: 3 }
      });
    }, 2000);
    return () => {
      clearTimeout(timer);
    };
  }, []);

  return (
    <motion.div
      animate={controls}
      style={{ backgroundColor: "yellow", width: 100, height: 100 }}
    />
  );
}

We call control.start with the styles applied after animation with the object.

It’s called within the setTimeout callback so that the animation is delayed.

We can also call controls.start with the variant name.

For example, we can write:

import React, { useEffect } from "react";
import { motion, useAnimation } from "framer-motion";

const variants = {
  visible: (i) => ({
    opacity: 1,
    transition: {
      delay: i * 0.3
    }
  }),
  hidden: { opacity: 0 }
};

export default function App() {
  const controls = useAnimation();

  useEffect(() => {
    const timer = setTimeout(() => {
      controls.start("hidden");
    }, 2000);
    return () => {
      clearTimeout(timer);
    };
  }, []);

  return (
    <motion.div
      animate={controls}
      variants={variants}
      style={{ backgroundColor: "yellow", width: 100, height: 100 }}
    />
  );
}

We set the variants to an object with styles so that we can pass in a property name into the control.start method.

Then we see the div goes from being displayed to being hidden.

Conclusion

We can apply styles dynamically with Framer Motion.

Also, we can control when our animation starts.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

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