简体   繁体   English

Framer Motion 出口 animation 没有使用 react-router-dom 在手风琴上触发

[英]Framer Motion exit animation not firing on accordion with react-router-dom

So I've got this accordion-layout working with react-router-dom using a rather unconventional markup structure.因此,我使用一种非常规的标记结构使这个手风琴布局与react-router-dom一起工作。

Demo:https://codesandbox.io/s/falling-violet-kvqn2?file=/src/Case.js演示:https://codesandbox.io/s/falling-violet-kvqn2?file=/src/Case.js

Shortened code for one accordion header:一架手风琴 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>

And I'm trying to get framer-motion to animate between the accordion pages.我正在尝试让framer-motion在手风琴页面之间制作动画。 Like in the gif below就像下面的 gif

You can see that it works fine to animate the in transition.您可以看到它可以很好地in过渡设置动画。 But struggles to animate the exit prop on page change.但是很难在页面更改时为exit道具设置动画。 Clicking on an accordion header, the content is abruptly hidden.单击手风琴 header,内容突然隐藏。 Looks like it is being removed from the DOM without any consideration to AnimateSharedLayout or AnimatePresence .看起来它正在从 DOM 中删除,而不考虑AnimateSharedLayoutAnimatePresence I tried adding in exitBeforeEnter props but it doesn't work.我尝试添加exitBeforeEnter道具,但它不起作用。

Any ideas?有任何想法吗?

在此处输入图像描述

You will need to make some changes in your code:您需要对代码进行一些更改:

  1. Work with variants -> you can orchestration animations start: By default, all these animations will start simultaneously.使用变体-> 您可以编排动画开始:默认情况下,所有这些动画将同时开始。 But by using variants, we gain access to extra transition props like when, delayChildren, and staggerChildren that can let parents orchestrate the execution of child animations.但是通过使用变体,我们可以访问额外的过渡道具,例如 when、delayChildren 和 staggerChildren,它们可以让父母协调子动画的执行。

  2. Also, looks like you will need to work with width to change div sizes.此外,看起来您需要使用width来更改 div 大小。 I tried to do with flexBasis but i really couldnt do it, the transition just doesnt work.我试图用 flexBasis 做,但我真的做不到,过渡不起作用。

  3. Remove <Route> as a "wrapper" of motion.div.删除<Route>作为motion.div 的“包装器”。 It also stops the motion to do the animations/transitions.它还停止运动以进行动画/过渡。

  4. Add <AnimatePresence> as a wrapper of motion.div children.添加<AnimatePresence>作为motion.div子项的包装。 You can check more here你可以在这里查看更多

So, my code looks like this:所以,我的代码如下所示:

I create this 2 variants:我创建了这 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:运动.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>

I also added some inline styles to all Cases:我还在所有案例中添加了一些内联 styles :

<div
      <!-- Avoid div to wrap when it is collapsing -->
      style={{
        whiteSpace: "nowrap",
        overflow: "hidden"
      }}
    >
      home 0
    </div>

And finally最后

You can check the code here!你可以在这里查看代码!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM