Varaiants for Drag and Drop in Framer Motion
Tags: javascript, framermotion, react
Published: 2022-06-05 03:59:12

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.

## Variants
We can organize styles with variants.

They let us control animations throughout a component tree by switching to a single `animate` prop.

Sample:

```javascript
import React from "react";
import { motion } from "framer-motion";
const variants = {
  active: {
    backgroundColor: "#f00"
  },
  inactive: {
    backgroundColor: "#fff",
    transition: { duration: 2 }
  }
};
export default function App() {
  return (
    <>
      <motion.div
        style={{ width: 100, height: 100 }}
        variants={variants}
        animate="active"
      />
    </>
  );
}
```

We create the `variants` object with some styles we want to apply at various stages of animation.

Then we apply them by passing the `variants` object as the value of the variants prop.

Then we set `animate` to `'active'` to set the styles when the animation ends to the ones in the active property.

## Style
The `style` prop is like the `style` prop in React, but it’s enhanced to support motion values and `transform` values.

Sample:

```javascript
import React from "react";
import { motion, useMotionValue } from "framer-motion";
export default function App() {
  const x = useMotionValue(0);
  return (
    <motion.div
      style={{
        width: 100,
        height: 100,
        backgroundColor: "red",
        x,
        opacity: 1,
        scale: 0.5
      }}
    />
  );
}
```

We pass the `x` motion value into the `style` prop so we can set the horizontal position of the div.

## Layout Animation

We can create layout animations with Framer Motion.

The `layout` prop lets us animate an element to its new position when its layout changes.

Sample:

```javascript
import React from "react";
import { AnimateSharedLayout, motion } from "framer-motion";
const items = [
  { name: "foo", isSelected: true, id: 1 },
  { name: "bar", isSelected: false, id: 2 },
  { name: "baz", isSelected: true, id: 3 }
];
export default function App() {
  return (
    <AnimateSharedLayout>
      {items.map((item) => (
        <motion.li layout key={item.id}>
          {item.name}
          {item.isSelected && <motion.hr layoutId="underline" />}
        </motion.li>
      ))}
    </AnimateSharedLayout>
  );
}
```

to let us animate the changes in the layout with the `AnimateSharedLayout` component.

We have the `motion.li` to animate the li elements when the `li` layout change.

## Drag
We can add drag and drop capabilities to our elements with Framer Motion.

Sample:
```javascript
import React, { useRef } from "react";
import { motion } from "framer-motion";
export default function App() {
  const constraintsRef = useRef(null);
  return (
    <motion.div
      ref={constraintsRef}
      style={{ background: "green", width: 200, height: 200 }}
    >
      <motion.div
        drag
        dragConstraints={constraintsRef}
        style={{ background: "red", width: 100, height: 100 }}
      />
    </motion.div>
  );
}
```

We allow the red div to be dragged around within the green div. We do this by assigning a ref to the green div. Then we pass the ref as the value of the `dragConstraints` prop. The `drag` prop lets us enable dragging on the red div.