我如何使用 framer motion 在 React 组件之间切换?
How can i switch between react components using framer motion?
在我的 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>
)
}
我将如何构建能够在我的组件(幻灯片)之间动态切换的逻辑?在 codesandbox 示例中,图像是通过数组更改的:
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,
}}
/>
)
您的组件应该 return <motion.div>
(或 <motion.section>
、<motion.span>
等)。
在页面组件中,您应该使用 <AnimatePresence />
组件(如示例中所示):
<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
上述答案中缺少一些让退出动画正常工作的内容。
- 如果您希望退出动画在 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>
- 如果您想在不移动大量内容的情况下为某些内容设置动画,而某些内容仍在动画中,则需要将它们从流程中移除。 (使用绝对定位,用相对定位的容器包装)
<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
在我的 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>
)
}
我将如何构建能够在我的组件(幻灯片)之间动态切换的逻辑?在 codesandbox 示例中,图像是通过数组更改的:
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,
}}
/>
)
您的组件应该 return <motion.div>
(或 <motion.section>
、<motion.span>
等)。
在页面组件中,您应该使用 <AnimatePresence />
组件(如示例中所示):
<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
上述答案中缺少一些让退出动画正常工作的内容。
- 如果您希望退出动画在 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>
- 如果您想在不移动大量内容的情况下为某些内容设置动画,而某些内容仍在动画中,则需要将它们从流程中移除。 (使用绝对定位,用相对定位的容器包装)
<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