Animations with Framer Motion
Framer Motion is a production-ready animation and gesture library. It allows the user to easily create simple and complex animations. It also offers more advanced listeners and extends the basic set of React event listeners.
At the point of this post being written, Framer Motion v3.10.2 requires React v16.8 or greater.
Installation
npm install framer-motion
Getting started
Once installed, we can add motion to our components by
import { motion } from "framer-motion"
We can then animate for instance a box with scale and rotation
1.box {
2 background: rgb(86, 134, 245);
3 width: 200px;
4 height: 200px;
5}
1<motion.div
2 className="box"
3 animate={{ scale: 0.9, rotate: 20 }}>
4</motion.div>Variants
If we want to animate from one state to another, we can do so by adding the initial prop
1<motion.div
2 className="box"
3 initial={{ opacity: 0 }}
4 animate={{ scale: 0.9, rotate: 20, opacity: 1 }}
5/>
We can also use the variants prop to define multiple states
1const boxVariants = {
2 visible: {
3 opacity: 1,
4 scale: 0.9,
5 rotate: 20,
6 },
7 hidden: { opacity: 0 },
8};
9
10<motion.div
11 className="box"
12 initial="hidden"
13 animate="visible"
14 variants={boxVariants}
15/>
In this case, we animate from the state hidden to visible. The state name can be anything as long it matches the content in initial and animate props.
Transitions
To customize the transition we can either add transition prop to motion.div or to the variable boxVariants state e.g.
1const boxVariants = {
2 visible: {
3 opacity: 1,
4 scale: 0.9,
5 rotate: 20,
6 transition: {
7 duration: 2,
8 },
9 },
10 hidden: { opacity: 0 },
11};
12
13<motion.div
14 className="box"
15 initial="hidden"
16 animate="visible"
17 variants={boxVariants}>
18</motion.div>
Any components that use boxVariants will have the same transition. If you don't want to share the transition between components, use transition as a prop instead.
To repeat the animation we can just add the repeat props inside the transition e.g. repeat: 10 or repeat: Infinite. By default, the animation will loop from start to finish, so if we want to have an Yo-yo effect instead we can set the repeatType to reverse. Here is an example
1<motion.div
2 className="box"
3 initial={{ opacity: 0 }}
4 animate={{ scale: 0.9, rotate: 20, opacity: 1 }}
5 transition={{ repeat: 2, repeatType: 'reverse', duration: 2 }}
6/>
Gestures
We can add gestures such as hover or tap with whileHover or whileTap
1const boxVariants = {
2 end: {
3 opacity: 1,
4 scale: 0.9,
5 rotate: 20,
6 },
7 start: {
8 opacity: 0,
9 background: 'rgb(86, 134, 245)',
10 },
11 hover: {
12 background: '#eee',
13 cursor: 'pointer',
14 },
15};
16
17<motion.div
18 className="box"
19 initial="start"
20 animate="end"
21 variants={boxVariants}
22 whileHover="hover"
23 whileTap="hover"
24/>
Keyframes
We can also add keyframes to create more complex animations
1<motion.div
2 className="box"
3 animate={{
4 scale: [0.9, 1.1, 0.8, 1.1, 0.9],
5 rotate: [20, -20, 270, -120, 0],
6 transition: {
7 duration: 2,
8 repeat: Infinity
9 ,},
10 }}
11/>
And there is so much more to learn about Framer Motion! Check out their docs if you are interested in learning more.
Thanks for reading! Any feedbacks are welcome and appreciated 🙏
Back to blog