Currency Converter

I was experimenting with the layoutId prop in Framer Motion recently and in my opinion, it's one of the most powerful Framer Motion features for building interactions & animations. It allows you to animate between components seamlessly with just a single line of code.

Euro19458.67 EUR
Use Max
€20
1€ = 1,08$
DollarReceive Dollar
$21.61

Essentially, each card you see here has two states, and each state renders content conditionally based on the state.

<div className="card">
  <AnimatePresence initial={false}>
    {openCard !== "euro" ? (
      <motion.div className="content">
        <span className="text-collapsed">$20</span>
      </motion.div>
    ) : (
      <motion.div className="content">
        <span className="text-expanded">$20</span>
      </motion.div>
    )}
  </AnimatePresence>
</div>

This code snippet is simplified for clarity.

Often, I find myself scrolling on X, wondering how some of some of the animations and interactions are built. Before understanding how shared layout animations work in Framer Motion, I thought it was usually a single component, in this case, the price, getting altered somehow in a fixed layout.

However, it's much simpler than that. The only thing you need to do is to convert the two components (each in their respective state) that you want to animate between into motion components and give them the same layoutId prop. Framer Motion then works its magic.

You can, of course, change the styling, position, and structure of the code however you like and Framer Motion will still animate between the two components.

<div className="card">
  <AnimatePresence initial={false}>
    {openCard !== "euro" ? (
      <motion.div className="content">
        <motion.span layoutId="card1price" className="text-collapsed">
          $20
        </motion.span>
      </motion.div>
    ) : (
      <motion.div className="content">
        <motion.span layoutId="card1price" className="text-expanded">
          $20
        </motion.span>
      </motion.div>
    )}
  </AnimatePresence>
</div>

This code snippet is simplified for clarity.

This might be super obvious to people who are familiar with Framer Motion, but I thought it was a cool thing to share for those who are still learning (myself included). These concepts can be harder to grasp when you're transitioning into design engineering from a different background, like product design in my case.

The interaction was inspired by Family. In case you have any questions you can reach me at j@kbo.sk or X.