Sam
Sam

Reputation: 7058

Have one element fade in on top of the other one with Framer Motion

I am trying to fade out one div in the same space as I am trying to fade another div in using Framer Motion. Even with a delay on the transition, the object itself renders immediately which causes the other object in the same space to jump around.

Here is a small code example of what I'm trying to do:

  const [short, setShort] = useState(false);

  return (
    <div>
      <img src="image.jpg" />
      <AnimatePresence>
        {!short && (
          <motion.span
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ delay: 1.5 }}
            key="logoText"
          >
            TEXT
          </motion.span>
        )}
        {short && (
          <motion.span
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{delay: 1.5}}
            key="searchBox"
          >
            SOME DIFFERENT TEXT
          </motion.span>
        )}
      </AnimatePresence>

      <Button onClick={() => setShort(!short)}>Toggle</Button>
    </div>
  );
};

Essentially the space taken up by SOME DIFFERENT TEXT instantly appears, pushing the Toggle button out to the right, and then pushes in once TEXT has disappeared. And then SOME DIFFERENT TEXT is pushed out again to the right as soon as the button is clicked.

How can I get both items to take up the same space, so they seamlessly transition into each other?

Upvotes: 2

Views: 5017

Answers (1)

Sam
Sam

Reputation: 7058

You can add the exitBeforeEnter prop (https://www.framer.com/api/motion/animate-presence/#animatepresenceprops.exitbeforeenter) to the AnimatePresence component, which will ensure TEXT is fully removed before SOME DIFFERENT TEXT appears

Upvotes: 2

Related Questions