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