问题描述
因此,我使用了一种非常规的标记结构来与react-router-dom
一起使用这种手风琴布局。
演示: https://codesandbox.io/s/falling-violet-kvqn2?file=/src/Case.js
一个手风琴头的缩短代码:
<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
在手风琴页面之间进行动画处理。就像下面的gif
您可以看到为in
过渡设置动画效果很好。但是,很难为页面更改上的exit
道具设置动画。单击手风琴标题,内容将突然隐藏。似乎它已从DOM中删除,而没有考虑到AnimateSharedLayout
或AnimatePresence
。我尝试添加exitBeforeEnter
道具,但不起作用。
有什么想法吗?
解决方法
您将需要对代码进行一些更改:
-
使用变体->您可以orchestration动画开始: 默认情况下,所有这些动画将同时开始。但是,通过使用变体,我们可以使用额外的过渡道具,例如when,delayChildren和staggerChildren,它们可以让父母协调孩子动画的执行。
-
此外,您似乎需要使用
width
来更改div大小。我尝试使用flexBasis,但我真的做不到,过渡功能根本无法使用。 -
将
<Route>
删除为motion.div的“包装”。它还会停止执行动画/过渡的动作。 -
添加
<AnimatePresence>
作为motion.div
子级的包装。您可以查看更多here
所以,我的代码如下:
我创建了这2个变体:
const divVariants = {
expanded: {
width: "55%",transition: {
duration: 1.2,ease: [0.83,0.17,1]
}
},collapsed: {
width: "15%",1]
}
}
};
const tagVariants = {
show: {
opacity: 1,transition: {
delay: 1,duration: 1.2,hidden: {
opacity: 0,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!