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.
Sequencing
The controls.start method returns a promise so we can use it to sequence animations.
For example, we can write:
import React, { useEffect } from "react";
import { motion, useAnimation } from "framer-motion";
export default function App() {
const controls = useAnimation();
const sequence = async () => {
await controls.start({ x: 0 });
return await controls.start({ opacity: 1 });
};
useEffect(() => {
sequence();
}, []);
return (
<motion.div
animate={controls}
style={{ backgroundColor: "red", width: 100, height: 100 }}
/>
);
}
We have the sequence function that calls controls.start with different styles.
So this is what we’ll see when we load our component.
Dynamic Start
We can call controls.start dynamically.
For example, we can write:
import React, { useEffect } from "react";
import { motion, useAnimation } from "framer-motion";
export default function App() {
const controls = useAnimation();
useEffect(() => {
controls.start((i) => ({
opacity: 0,
x: 100,
transition: { delay: i * 0.3 }
}));
}, []);
return (
<ul>
<motion.li custom={0} animate={controls}>
foo
</motion.li>
<motion.li custom={1} animate={controls}>
bar
</motion.li>
<motion.li custom={2} animate={controls}>
baz
</motion.li>
</ul>
);
}
We pass in a callback with the i parameter, which is the value that we passed into the custom prop.
And we pass into the animate prop to set the controls to control the animation.
Layout Animations
We can animate layouts with Framer Motion
For example, we can write:
App.js
import React, { useState } from "react";
import { motion } from "framer-motion";
import "./styles.css";
const spring = {
type: "spring",
stiffness: 700,
damping: 30
};
export default function App() {
const [isOn, setIsOn] = useState(false);
const toggleSwitch = () => setIsOn(!isOn);
return (
<div className="switch" data-isOn={isOn} onClick={toggleSwitch}>
<motion.div className="handle" layout transition={spring} />
</div>
);
}
styles.css
html,
body {
min-height: 100vh;
padding: 0;
margin: 0;
}
* {
box-sizing: border-box;
}
.App {
font-family: sans-serif;
text-align: center;
}
.switch {
width: 160px;
height: 100px;
background-color: green;
display: flex;
justify-content: flex-start;
border-radius: 50px;
padding: 10px;
cursor: pointer;
}
.switch[data-isOn="true"] {
justify-content: flex-end;
}
.handle {
width: 80px;
height: 80px;
background-color: white;
border-radius: 40px;
}
We add the spring animation effect and pass that into the transition prop.
The onClick prop has the function to control the isOn state.
The layout prop lets us animate the layout of the div.
We add the styles to style our div into a switch.
justify-content set to flex-start has the switch bottom on the left. and flex-end puts the switch button to the right.
Conclusion
We can control our animation progress with Framer Motion.
And we can apply animations for layouts.