Framer Motion的退出动画不起作用,我的div只是突然消失,而不是滑动消失。

huangapple go评论67阅读模式
英文:

Framer motion Exit animation doesnt work. my divs just disappear instead of sliding away

问题

我的动画文件

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 },
  },
};

我的JSX首页

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>
  );
};

初始和动画效果正常,但是当我将首页切换到另一个视图(URL相同,只是渲染另一个组件而不是首页)时,退出动画不起作用。我为所有motion div添加了唯一的键,但仍然不起作用。有任何帮助吗?谢谢!


<details>
<summary>英文:</summary>
My animations file
&lt;!-- begin snippet: js hide: false console: true babel: false --&gt;
&lt;!-- language: lang-js --&gt;
export const transition = { type: &quot;spring&quot;, duration: 1 };
export const slideAnimation = (direction) =&gt; {
return {
initial: {
x: direction === &quot;left&quot; ? -100 : direction === &quot;right&quot; ? 100 : 0,
y: direction === &quot;up&quot; ? 100 : direction === &quot;down&quot; ? -100 : 0,
opacity: 0,
transition: { ...transition, delay: 1 },
},
animate: {
x: 0,
y: 0,
opacity: 1,
transition: { ...transition, delay: 0 },
},
exit: {
x: direction === &quot;left&quot; ? -100 : direction === &quot;right&quot; ? 100 : 0,
y: direction === &quot;up&quot; ? 100 : direction === &quot;down&quot; ? -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 },
},
};
&lt;!-- end snippet --&gt;
and my jsx homepage is 
&lt;!-- begin snippet: js hide: false console: true babel: false --&gt;
&lt;!-- language: lang-js --&gt;
const HomePage = () =&gt; {
return (
&lt;AnimatePresence&gt;
&lt;motion.div className=&quot;card&quot; &gt;
&lt;motion.div className=&quot;card_section1&quot; {...slideAnimation(&quot;left&quot;)} key=&quot;custom&quot;&gt;
&lt;h2 className=&quot;title_name&quot;&gt;text&lt;/h2&gt;
&lt;motion.h3 className=&quot;subtitle&quot; {...slideAnimation(&quot;left&quot;)} key=&quot;custom2&quot;&gt;
{&quot; &quot;}
{&quot;&gt;&quot;} Front-End Developer
&lt;/motion.h3&gt;
&lt;motion.div
className=&quot;comments_container&quot;
key=&quot;custom3&quot;
{...slideAnimation(&quot;down&quot;)}
{...fadeAnimation}
&gt;
&lt;h6 className=&quot;comment&quot;&gt;{&quot;//&quot;} explore my projects&lt;/h6&gt;
&lt;h6 className=&quot;comment&quot;&gt;
{&quot;//&quot;} you can also see it on my Github page
&lt;/h6&gt;
&lt;h6 className=&quot;github&quot;&gt;
&lt;span style={{ color: &quot;#4D5BCE&quot; }}&gt;const&lt;/span&gt;{&quot; &quot;}
&lt;span style={{ color: &quot;#43D9AD&quot; }}&gt;githubLink&lt;/span&gt;
&lt;span style={{ color: &quot;white&quot; }}&gt; = &lt;/span&gt;
&lt;a style={{ color: &quot;#E99287&quot; }} href={githubUrl} target=&quot;_blank&quot; rel=&quot;noreferrer&quot;&gt;
text
&lt;/a&gt;
&lt;/h6&gt;
&lt;/motion.div&gt;
&lt;/motion.div&gt;
&lt;motion.div className=&quot;card_section2&quot; {...slideAnimation(&quot;left&quot;)} key=&quot;custom4&quot;&gt;
&lt;h3&gt;Main Tecnologies&lt;/h3&gt;
&lt;motion.div className=&quot;technologies_image&quot; {...fadeAnimation}&gt;
{Images.map((image, i) =&gt; {
return &lt;img key={i} src={image} alt={image} /&gt;;
})}
&lt;/motion.div&gt;
&lt;/motion.div&gt;
&lt;/motion.div&gt;
&lt;/AnimatePresence&gt;
);
};
&lt;!-- end snippet --&gt;
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&#39;ve added unique keys to all my motion divs but still doesnt work. Any help? THANKS!
</details>
# 答案1
**得分**: 2
`AnimatePresence`标签需要位于被有条件地渲染的组件之外。目前的设置是,`AnimatePresence`标签位于`HomePage`组件内部。当页面变化时,该组件会从DOM中删除,同时`AnimatePresence`标签也会被删除。没有任何内容可以运行退出动画。
你应该像这样更改(在你的`App`或父组件中):
```jsx
<AnimatePresence>
{currentPage === "home" && <HomePage key="homePage" />}
...等等
</AnimatePresence>

这样,AnimatePresence可以跟踪哪些元素被移除并在从DOM中移除之前运行它们的退出动画。

英文:

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):

&lt;AnimatePresence&gt;
{currentPage === &quot;home&quot; &amp;&amp; &lt;HomePage key=&quot;homePage&quot; /&gt;}
...etc
&lt;/AnimatePresence&gt;

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

答案2

得分: 2

我按照Cadin的评论修复了所有问题,但仍然出现了一些错误。
当动画出现时,我的页面/元素/层叠会改变大小,导致用户体验不佳。
我通过向我的AnimatePresence添加**mode="wait"**来解决了这个问题。

英文:

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

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

&lt;AnimatePresence mode=&quot;wait&quot;&gt;
{logic to render different things}
&lt;/AnimatePresence&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年7月13日 00:37:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672776.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定