【问题标题】:How can i switch between react components using framer motion?如何使用成帧器运动在反应组件之间切换?
【发布时间】:2021-05-12 15:51:31
【问题描述】:

在我的 React 应用程序中,我需要像在轮播中一样在组件之间切换。我发现此示例仅使用帧运动来构建图像轮播:https://codesandbox.io/s/framer-motion-image-gallery-pqvx3?file=/src/Example.tsx:1715-1725

我想让它适应组件之间的切换。目前我的页面看起来像这样:

const variants = {
  enter: (direction: number) => {
    return {
      x: direction > 0 ? 100 : -100,
      opacity: 0,
    }
  },
  center: {
    zIndex: 1,
    x: 0,
    opacity: 1,
  },
  exit: (direction: number) => {
    return {
      zIndex: 0,
      x: direction < 0 ? 100 : -100,
      opacity: 0,
    }
  },
}

const Page = () => {

const [[page, direction], setPage] = useState([0, 0])
const paginate = (newDirection: number) => {
  setPage([page + newDirection, newDirection])
}
return (
   <motion.div
     key={page}
     custom={direction}
     variants={variants}
     initial="enter"
     animate="center"
     exit="exit"
   >
     <!-- my components, between which I want to switch, should appear here -->
   </motion.div>
 )
}

我将如何构建能够在我的组件(幻灯片)之间动态切换的逻辑?在代码框示例中,图像是通过数组更改的:

const imageIndex = wrap(0, images.length, page);

<motion.img key={page} src={images[imageIndex]} />

如何在 jsx 元素之间切换?

编辑

Joshua Wootonn 的回答是正确的,但您还需要将 custom 属性添加到 TestComp 以使动画与这样的动态变体一起工作:

const TestComp = ({ bg }: { bg: string }) => (
  <motion.div
    custom={direction}
    variants={variants}
    initial="enter"
    animate="center"
    exit="exit"
    transition={{
      x: { type: "spring", stiffness: 100, damping: 30 },
      opacity: { duration: 0.2 },
    }}
    className="absolute w-full h-full"
    style={{
      background: bg,
    }}
  />
)

【问题讨论】:

    标签: reactjs framer-motion


    【解决方案1】:

    上述答案中缺少一些东西以使退出动画正常工作。

    1. 如果您希望退出动画在 AnimationPresense 中工作,您需要为其子级设置键
            <AnimatePresence initial={false} custom={direction}>
              {page === 0 && <TestComp key="0" bg="rgb(171, 135, 255)" />}
              {page === 1 && <TestComp key="1" bg="rgb(68, 109, 246)" />}
              {page === 2 && <TestComp key="2" bg="rgb(172, 236, 161)" />}
            </AnimatePresence>
    
    1. 如果您想在某些内容仍在制作动画的同时制作动画,而不需要大量内容转换,则需要将它们从流程中移除。 (使用绝对定位并用相对定位的容器包裹)
          <div style={{ position: "relative", height: "300px", width: "300px" }}>
            <AnimatePresence initial={false} custom={direction}>
              ...
            </AnimatePresence>
          </div>
    

    在子组件上

      height: 100%;
      width: 100%;
      position: absolute;
    

    工作代码框:https://codesandbox.io/s/framer-motion-carousel-animation-wetrf?file=/src/App.tsx:658-708

    【讨论】:

    • 感谢您的更正。我也刚刚注意到了。还有一个问题:有没有可能让整个事情变得更有活力?我可以使用&lt;Slide&gt;&lt;/Slide&gt; 组件而不是条件渲染吗?然后,父组件会自动检测已定义了多少张幻灯片并基于此创建一个数组?
    • 最动态的方法是维护一个数组并将其直接映射到 AnimatePresense 中。由于需要显式键,这是 React 的一个限制,它们必须直接映射到 AnimatePresense 中。更多细节在这里:framer.com/api/motion/animate-presence/…
    【解决方案2】:

    您的组件应返回&lt;motion.div&gt;(或&lt;motion.section&gt;&lt;motion.span&gt; 等)。 在页面组件中,您应该使用&lt;AnimatePresence /&gt; 组件(如示例中所示):

    <AnimatePresence initial={false} custom={direction}>
      {COMPONENTS}
    </AnimatePresence>
    

    然后你必须决定哪个组件会出现:

    {page === 0 && <ComponentOne />}
    {page === 1 && <ComponentTwo/>}
    {page === 2 && <ComponentThree/>}
    

    您可以使用variants 控制的动画。

    您可以在此处查看快速演示:https://codesandbox.io/s/quizzical-hypatia-7wqjc?file=/src/App.tsx

    【讨论】:

      猜你喜欢
      • 2023-02-07
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 1970-01-01
      相关资源
      最近更新 更多