如何使用成帧器运动在反应组件之间切换?

Nik*_*las 2 reactjs framer-motion

在我的反应应用程序中,我需要在组件之间切换,就像在轮播中一样。我发现这个示例仅使用成帧器运动构建图像轮播: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>
 )
}
Run Code Online (Sandbox Code Playgroud)

我必须如何构建逻辑才能在组件(幻灯片)之间动态切换?在codesandbox示例中,图像通过数组更改:

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

<motion.img key={page} src={images[imageIndex]} />
Run Code Online (Sandbox Code Playgroud)

我怎样才能在 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,
    }}
  />
)
Run Code Online (Sandbox Code Playgroud)

Jos*_*onn 5

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

  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>
Run Code Online (Sandbox Code Playgroud)
  1. 如果您想在某些内容仍在动画播放时将某些内容动画化,而不需要进行大量内容转移,则需要将它们从流程中删除。(使用绝对定位并用相对定位的容器包裹)
      <div style={{ position: "relative", height: "300px", width: "300px" }}>
        <AnimatePresence initial={false} custom={direction}>
          ...
        </AnimatePresence>
      </div>
Run Code Online (Sandbox Code Playgroud)

以及子组件上

  height: 100%;
  width: 100%;
  position: absolute;
Run Code Online (Sandbox Code Playgroud)

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