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

CSSApp.css
.box {
  background: rgb(86, 134, 245);
  width: 200px;
  height: 200px;
}

JSXApp.js
<motion.div
  className="box"
  animate={{ scale: 0.9, rotate: 20 }}>
</motion.div>

Variants

If we want to animate from one state to another, we can do so by adding the initial prop

JSXApp.js
<motion.div
  className="box"
  initial={{ opacity: 0 }}
  animate={{ scale: 0.9, rotate: 20, opacity: 1 }}
/>

We can also use the variants prop to define multiple states

JSXApp.js
const boxVariants = {
  visible: {
    opacity: 1,
    scale: 0.9,
    rotate: 20,
  },
  hidden: { opacity: 0 },
};

<motion.div
  className="box"
  initial="hidden"
  animate="visible"
  variants={boxVariants}
/>

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.

JSX
const boxVariants = {
  visible: {
    opacity: 1,
    scale: 0.9,
    rotate: 20,
    transition: {
      duration: 2,
    },
  },
  hidden: { opacity: 0 },
};

<motion.div
  className="box"
  initial="hidden"
  animate="visible"
  variants={boxVariants}>
</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

JSX
<motion.div
  className="box"
  initial={{ opacity: 0 }}
  animate={{ scale: 0.9, rotate: 20, opacity: 1 }}
  transition={{ repeat: 2, repeatType: 'reverse', duration: 2 }}
/>

Yo-yo effect

Gestures

We can add gestures such as hover or tap with whileHover or whileTap

JSX
const boxVariants = {
  end: {
    opacity: 1,
    scale: 0.9,
    rotate: 20,
  },
  start: {
    opacity: 0,
    background: 'rgb(86, 134, 245)',
  },
  hover: {
    background: '#eee',
    cursor: 'pointer',
  },
};

<motion.div
  className="box"
  initial="start"
  animate="end"
  variants={boxVariants}
  whileHover="hover"
  whileTap="hover"
/>

Keyframes

We can also add keyframes to create more complex animations

JSX
<motion.div
  className="box"
  animate={{
    scale: [0.9, 1.1, 0.8, 1.1, 0.9],
    rotate: [20, -20, 270, -120, 0],
    transition: {
      duration: 2,
      repeat: Infinity
    ,},
  }}
/>

And there are so much more to learn about Framer Motion! Check out their docs if you are interested on learning more.

Thanks for reading! Any feedback are welcome and appreciated 🙏

Back to blog
Discuss on Twitter ‱ Tweet about this post
  • Email
  • GitHub
  • Twitter
  • Codepen
  • LinkedIn
  • GitLab