【问题标题】:Animate presence not working in next js for exit animations only? [duplicate]动画存在在下一个 js 中仅适用于退出动画吗? [复制]
【发布时间】:2021-10-02 14:43:08
【问题描述】:

我正在尝试在下一个 js 中为我的组件设置退出动画,但我只能提供初始动画。

谁能告诉我这里出了什么问题?

这是我的示例代码:

 <AnimatePresence >
        <motion.div key="modalBackground" className={styles['auth-modal-layout']} key="modalBackground" initial="hidden" animate="visible" variants={
                {
                    hidden:{
                        opacity:0
                    },
                    visible:{
                        opacity:1,
                        transition:{
                            duration:.4,
                        }
                    },
                }
            } >
            
            <motion.div key="modalForm" className={styles['auth-modal-form']} initial="hidden" exit="pageExit" animate="visible" exit="hidden"  variants={{
                hidden:{
                    translateY:100,
                    opacity:0
                },
                visible:{
                    translateY:0,
                    opacity:1,
                    transition:{
                        duration:.4
                    }
                },
                pageExit:{
                    opacity:0,
                    transition:{
                        when:"afterChildren",
                        duration:.4
                    }
                }
            }} >
                {modal()}
            </motion.div>
               
        </motion.div>
        </AnimatePresence> 

【问题讨论】:

  • 在下面查看我修改后的答案

标签: javascript css reactjs next.js framer-motion


【解决方案1】:

&lt;AnimatePresence&gt; 需要包装有条件渲染的组件。它不能在里面。

您需要将&lt;AnimatePresence&gt; 标记移至更高级别或将条件逻辑移至组件中。你很可能会做前者,像这样:

<AnimatePresence>
    {modalIsVisible && <ModalComponent />}
</AnimatePresence>

(在此示例中,ModalComponent 包含您在上面显示的代码)。

否则,您需要始终渲染组件并传入一个 prop 以用于有条件地渲染子组件。就您而言(模态窗口),我认为这不是您想要的。

【讨论】:

  • 那么我需要将Animate Presence 移动到更高的级别吗?
  • 是的,该标签表示您想要动画显示正在从虚拟 dom 添加或删除的组件。在您的示例中,标签内的任何内容都不会有条件地呈现,因此它不会产生任何影响。假设条件逻辑处于更高级别,您需要将 AnimatePresence 标记移至该级别。
  • 这很好用!!我将&lt;AnimatePresence /&gt; 移到了更高的级别!谢谢!
  • 有没有办法,Animate Presence 可以在不传递条件的情况下工作?就像在其范围结束后卸载组件一样??
  • 我不确定您所说的“一旦其范围结束”是什么意思。它应该在组件卸载时运行退出动画(当它从 DOM 中移除时)。但是如果你移除了包含 AnimatePresence 标签的父组件,那么 Framer Motion 就没有机会运行动画了。该标签正在监视其子项中的 DOM 更改,以进行动画进出。如果您卸载标签本身,它就不能再对其子级执行任何动画。它会立即消失,连同它的孩子。
【解决方案2】:

你这样做,更多例子here

  <AnimatePresence>
     <motion.div
        // initial state opacity
        initial={{ opacity: 0 }}
        //animation of component appearence
        animate={{ opacity: 1 }}
        // how your element will appears f.e(duration in seconds)
        transition={{ delay: 0.5 }}
        // your exit animation
        exit={{ opacity: 0 }}
      >
       {your_content_here}
      </motion.div>
  </AnimatePresence>

如果您发出一些错误,则不是nextjs。尝试在framer的代码/库中查找问题

你也在你的 div 中输入(?ok 2 exit?):

initial="hidden" exit="pageExit" animate="visible" exit="hidden"

检查valid motion components。始终尝试从文档中获取示例。

附:如果您需要移动“更高”,您只需包装您的父组件,或者您可以将代码包装在您的_app.js 中。 但是这个方法意味着每个页面都会加载framer lib的AnimatePresence代码。

function MyApp({ Component, pageProps }) {
  
  return (
    <AnimatePresence>
     <Component {...pageProps} />
    </AnimatePresence>
  )
  
}

修改: 我检查了AnimatePresence 的行为,它实际上并没有在做他的工作。我检查了我是如何做同样的事情的。这是一个如何做的想法,代码示例如下。

//npm install this before: npm i react-intersection-observer
import { useInView } from "react-intersection-observer";

//in your hooks part, where you place hooks
const controls = useAnimation();
const [ref, inView] = useInView();
useEffect(() => {
  if (inView) {
     controls.start("visible");
  }
  else {
     controls.start("hidden");
  }
}, [controls, inView]);

//and the component, check how I did it (example)
<motion.div
 style={{marginTop: '1000px', marginBottom: '1000px'}}
 ref={ref}
 animate={controls}
 initial="hidden"
 transition={{ duration: 2 }}
 variants={{
     visible: { opacity: 1, scale: 1 },
     hidden: { opacity: 0, scale: 0 }
 }}

>
   <img src="https://super-monitoring.com/blog/wp-content/uploads/2020/03/framer.png"></img>
</motion.div>

由于许多我不记得的原因,我没有使用 AnimationPresence。 问题 AnimationPresence 并没有清楚地“理解”用户目前在页面上的位置。我认为这就是他们在framer examples 中添加isVisible 变量的原因。 react-intersection-observer 正在努力检测用户的位置。很抱歉修改部分之前的混乱信息。

附:还要检查this

【讨论】:

  • 您的第一个示例与 OP 犯了同样的错误。 AnimatePresence 标签内没有条件逻辑。渲染堆栈中没有添加或删除任何内容,因此没有任何动画。
猜你喜欢
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 2014-08-27
  • 2021-12-04
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多