react-router-dom Framer Motion 退出动画不会在手风琴上触发
Framer Motion exit animation not firing on accordion with react-router-dom
所以我得到了这个 accordion-layout 与 react-router-dom
一起使用的非常规标记结构。
演示:
https://codesandbox.io/s/falling-violet-kvqn2?file=/src/Case.js
一架手风琴的缩短代码header:
<motion.div
layout
transition={transition}
key={item.id}
style={{
flex: isActive ? 1 : 0,
flexBasis: isActive ? null : 56,
...
}}
>
<NavLink
style={{
...
}}
exact={true}
to={item.url}
/>
<Route exact path={item.url}>
<motion.div
transition={{ delay: 1, ...transition }}
variants={{
open: { opacity: 1 },
collapsed: { opacity: 0 }
}}
initial="collapsed"
animate="open"
exit="collapsed"
layout
style={{
...
}}
>
<Home />
</motion.div>
</Route>
</motion.div>
我正在尝试让 framer-motion
在手风琴页面之间设置动画。就像下面的动图
您可以看到它可以很好地为 in
过渡设置动画。但是很难在页面更改时为 exit
道具设置动画。单击手风琴 header,内容突然隐藏。看起来它正在从 DOM 中删除,而没有考虑 AnimateSharedLayout
或 AnimatePresence
。我尝试添加 exitBeforeEnter
道具,但它不起作用。
有什么想法吗?
您需要对代码进行一些更改:
使用变体 -> 你可以orchestration动画开始:
默认情况下,所有这些动画将同时启动。但是通过使用变体,我们可以访问额外的过渡道具,例如 when、delayChildren 和 staggerChildren,它们可以让 parents 协调 child 动画的执行。
此外,看起来您需要使用 width
来更改 div 大小。我尝试使用 flexBasis,但我真的做不到,转换不起作用。
删除 <Route>
作为 motion.div 的“包装”。它还会停止执行 animations/transitions.
的动作
添加<AnimatePresence>
作为motion.div
children的封装。您可以查看更多here
因此,我的代码如下所示:
我创建了这 2 个变体:
const divVariants = {
expanded: {
width: "55%",
transition: {
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
},
collapsed: {
width: "15%",
transition: {
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
}
};
const tagVariants = {
show: {
opacity: 1,
transition: {
delay: 1,
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
},
hidden: {
opacity: 0,
transition: {
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
}
};
motion.div :
<!-- Parent -->
<motion.div
layout
variants={divVariants}
animate={isActive ? "expanded" : "collapsed"}
initial={false}
data-section={item.id}
key={item.id}
style={{
overflow: "hidden",
zIndex: i,
display: "flex",
position: "relative",
backgroundColor: `hsl(${i * 20},100%,50%)`
}}
>
<!-- Children -->
<AnimatePresence>
{isActive && (
<motion.div
layout
variants={tagVariants}
initial="hidden"
animate="show"
exit="hidden"
style={{
padding: 20,
maxWidth: "100%",
maxHeight: "100%",
width: "100%",
height: "100%",
overflowY: "hidden",
overflowX: "hidden"
}}
>
<Tag data={data} />
</motion.div>
)}
</AnimatePresence>
我还为所有案例添加了一些内联样式:
<div
<!-- Avoid div to wrap when it is collapsing -->
style={{
whiteSpace: "nowrap",
overflow: "hidden"
}}
>
home 0
</div>
最后
可以查看代码here!
所以我得到了这个 accordion-layout 与 react-router-dom
一起使用的非常规标记结构。
演示: https://codesandbox.io/s/falling-violet-kvqn2?file=/src/Case.js
一架手风琴的缩短代码header:
<motion.div
layout
transition={transition}
key={item.id}
style={{
flex: isActive ? 1 : 0,
flexBasis: isActive ? null : 56,
...
}}
>
<NavLink
style={{
...
}}
exact={true}
to={item.url}
/>
<Route exact path={item.url}>
<motion.div
transition={{ delay: 1, ...transition }}
variants={{
open: { opacity: 1 },
collapsed: { opacity: 0 }
}}
initial="collapsed"
animate="open"
exit="collapsed"
layout
style={{
...
}}
>
<Home />
</motion.div>
</Route>
</motion.div>
我正在尝试让 framer-motion
在手风琴页面之间设置动画。就像下面的动图
您可以看到它可以很好地为 in
过渡设置动画。但是很难在页面更改时为 exit
道具设置动画。单击手风琴 header,内容突然隐藏。看起来它正在从 DOM 中删除,而没有考虑 AnimateSharedLayout
或 AnimatePresence
。我尝试添加 exitBeforeEnter
道具,但它不起作用。
有什么想法吗?
您需要对代码进行一些更改:
使用变体 -> 你可以orchestration动画开始: 默认情况下,所有这些动画将同时启动。但是通过使用变体,我们可以访问额外的过渡道具,例如 when、delayChildren 和 staggerChildren,它们可以让 parents 协调 child 动画的执行。
此外,看起来您需要使用
width
来更改 div 大小。我尝试使用 flexBasis,但我真的做不到,转换不起作用。删除
的动作<Route>
作为 motion.div 的“包装”。它还会停止执行 animations/transitions.添加
<AnimatePresence>
作为motion.div
children的封装。您可以查看更多here
因此,我的代码如下所示:
我创建了这 2 个变体:
const divVariants = {
expanded: {
width: "55%",
transition: {
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
},
collapsed: {
width: "15%",
transition: {
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
}
};
const tagVariants = {
show: {
opacity: 1,
transition: {
delay: 1,
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
},
hidden: {
opacity: 0,
transition: {
duration: 1.2,
ease: [0.83, 0, 0.17, 1]
}
}
};
motion.div :
<!-- Parent -->
<motion.div
layout
variants={divVariants}
animate={isActive ? "expanded" : "collapsed"}
initial={false}
data-section={item.id}
key={item.id}
style={{
overflow: "hidden",
zIndex: i,
display: "flex",
position: "relative",
backgroundColor: `hsl(${i * 20},100%,50%)`
}}
>
<!-- Children -->
<AnimatePresence>
{isActive && (
<motion.div
layout
variants={tagVariants}
initial="hidden"
animate="show"
exit="hidden"
style={{
padding: 20,
maxWidth: "100%",
maxHeight: "100%",
width: "100%",
height: "100%",
overflowY: "hidden",
overflowX: "hidden"
}}
>
<Tag data={data} />
</motion.div>
)}
</AnimatePresence>
我还为所有案例添加了一些内联样式:
<div
<!-- Avoid div to wrap when it is collapsing -->
style={{
whiteSpace: "nowrap",
overflow: "hidden"
}}
>
home 0
</div>
最后
可以查看代码here!