skip to Main Content

My animations file

export const transition = { type: "spring", duration: 1 };

export const slideAnimation = (direction) => {
  return {
    initial: {
      x: direction === "left" ? -100 : direction === "right" ? 100 : 0,
      y: direction === "up" ? 100 : direction === "down" ? -100 : 0,
      opacity: 0,
      transition: { ...transition, delay: 1 },
    },
    animate: {
      x: 0,
      y: 0,
      opacity: 1,
      transition: { ...transition, delay: 0 },
    },
    exit: {
      x: direction === "left" ? -100 : direction === "right" ? 100 : 0,
      y: direction === "up" ? 100 : direction === "down" ? -100 : 0,
      transition: { ...transition, delay: 0 },
    },
  };
};

export const fadeAnimation = {
  initial: {
    opacity: 0,
    transition: { ...transition, delay: 0.5 },
  },
  animate: {
    opacity: 1,
    transition: { ...transition, delay: 0.3 },
  },
  exit: {
    opacity: 0,
    transition: { ...transition, delay: 0 },
  },
};

and my jsx homepage is

const HomePage = () => {
  return (
    <AnimatePresence>
      <motion.div className="card" >
        <motion.div className="card_section1" {...slideAnimation("left")} key="custom">
          <h2 className="title_name">text</h2>
          <motion.h3 className="subtitle" {...slideAnimation("left")} key="custom2">
            {" "}
            {">"} Front-End Developer
          </motion.h3>
          <motion.div
            className="comments_container"
            key="custom3"
            {...slideAnimation("down")}
            {...fadeAnimation}
          >
            <h6 className="comment">{"//"} explore my projects</h6>
            <h6 className="comment">
              {"//"} you can also see it on my Github page
            </h6>
            <h6 className="github">
              <span style={{ color: "#4D5BCE" }}>const</span>{" "}
              <span style={{ color: "#43D9AD" }}>githubLink</span>
              <span style={{ color: "white" }}> = </span>
              <a style={{ color: "#E99287" }} href={githubUrl} target="_blank" rel="noreferrer">
                text
              </a>
            </h6>
          </motion.div>
        </motion.div>
        <motion.div className="card_section2" {...slideAnimation("left")} key="custom4">
          <h3>Main Tecnologies</h3>
          <motion.div className="technologies_image" {...fadeAnimation}>
            {Images.map((image, i) => {
              return <img key={i} src={image} alt={image} />;
            })}
          </motion.div>
        </motion.div>
      </motion.div>
    </AnimatePresence>
  );
};

Initial and animate animations works fine, but exit animations doesnt work when i switch the homepage to another view (same url but just rendering another component instead of Homepage).
I’ve added unique keys to all my motion divs but still doesnt work. Any help? THANKS!

2

Answers


  1. Chosen as BEST ANSWER

    I fixed everything with Cadin comment but i still was having some bugs. When animations popped my page / elements / divs were resizing, creating a bad user experience. I fixed this by adding mode="wait" to my AnimatePresence

    <AnimatePresence mode="wait">
        {logic to render different things}
    </AnimatePresence>


  2. The AnimatePresence tag needs to be outside of the component that’s being conditionally rendered. The way you have it set up now, the AnimatePresence tag is inside the HomePage component. When the page changes, the component gets removed from the DOM along with the AnimatePresence tag. There’s nothing left to run the exit animation.

    You’d want to have something more like this (in your App or whatever is the parent component):

    <AnimatePresence>
       {currentPage === "home" && <HomePage key="homePage" />}
       ...etc
    </AnimatePresence>
    

    That way AnimatePresence can track which elements are being removed and run their exit animations before pulling them from the DOM.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search