# Creating An Animation Sequence Using Framer Motion

By Jag Reehal, 2022-03-01. Canonical: https://arrangeactassert.com/posts/creating-an-animation-sequence-using-framer-motion/

<!-- Excerpt Start -->

[Framer Motion](https://www.framer.com/api/) makes creating a sequence of animations easy.

In this example, we will create a React component that animates a circle in the center of three boxes.

![framer animation sequence](/static/gifs/framer-animation-sequence.gif)

<!-- Excerpt End -->

This works by finding the bounding rectangle of each box. As we're using React a ref. Which is created like this

```tsx
const box1Ref = useRef<HTMLDivElement>(null);
```

and used as follows

```tsx
<div
  className="w-20 h-20 border-2 border-purple-800 bg-purple-300"
  ref="{box1Ref}"
></div>
```

With a reference to the element the calling [getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) provides us with position and size properties.

```tsx
const domRect: DOMRect | undefined = box1Ref.current?.getBoundingClientRect();
```

With this information we can to calculate the position where the circle to should move to.

```tsx
const calculateCenter = (box, circle) => {
  return {
    top: box.y + box.height / 2 - (circle.y + circle.height / 2),
    left: box.x + box.width / 2 - (circle.x + circle.width / 2),
  };
};
```

Now we can create an animation sequence that moves the circle between the three boxes, which is easy as [Framer Motion](https://www.framer.com/api/) returns a promise for animations which is resolved upon when the animation is complete.

```tsx
const circleRect = circleRef.current?.getBoundingClientRect();
const box1 = calculateCenter(
  box1Ref.current?.getBoundingClientRect(),
  circleRect,
);
const box2 = calculateCenter(
  box2Ref.current?.getBoundingClientRect(),
  circleRect,
);
const box3 = calculateCenter(
  box3Ref.current?.getBoundingClientRect(),
  circleRect,
);
await animation.start({
  opacity: 1,
  transition: { duration: 1 },
});
await animation.start({
  top: box1.top,
  left: box1.left,
  transition: { duration: 1 },
});
await animation.start({
  top: box2.top,
  left: box2.left,
  transition: { duration: 1 },
});
await animation.start({
  top: box3.top,
  left: box3.left,
  transition: { duration: 1 },
});
```

The complete code for the example is available on CodePen

<p class="codepen" data-height="600" data-default-tab="js" data-slug-hash="NWwOEmo" data-user="jagreehal" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/jagreehal/pen/NWwOEmo">
  Untitled</a> by jagreehal (<a href="https://codepen.io/jagreehal">@jagreehal</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>