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.