如何用Framer Motion实现React页面间Div的跨组件过渡动画?
实现方案与代码示例
核心思路是利用Framer Motion的**layoutId**属性结合AnimatePresence,让两个组件内的Div共享布局动画上下文,自动完成从Comp1尺寸到Comp2尺寸的缩放过渡。
关键步骤说明
layoutId:给两个组件中的目标Div设置相同的layoutId,Framer Motion会将它们识别为同一逻辑元素,自动跟踪并生成尺寸变化的过渡动画,无需手动计算尺寸。AnimatePresence:必须包裹切换的组件,同时给每个组件分配唯一key,确保Framer Motion能捕获组件的卸载/挂载状态,触发过渡动画。mode="wait":配置该属性可让旧组件的退出动画完成后再挂载新组件,避免视觉重叠,让过渡更自然。
代码实现
父组件(控制切换逻辑)
import { useState } from 'react'; import { AnimatePresence, motion } from 'framer-motion'; import Comp1 from './Comp1'; import Comp2 from './Comp2'; export default function App() { const [showComp2, setShowComp2] = useState(false); return ( <div> <button onClick={() => setShowComp2(prev => !prev)}>切换组件</button> <AnimatePresence mode="wait"> {showComp2 ? ( <Comp2 key="comp2" /> ) : ( <Comp1 key="comp1" /> )} </AnimatePresence> </div> ); }
Comp1(动态尺寸组件)
import { motion } from 'framer-motion'; export default function Comp1() { // 模拟内容变化导致Div尺寸动态调整 const dynamicContent = "示例短内容"; return ( <div style={{ marginTop: '20px' }}> <motion.div layoutId="target-div" style={{ padding: '16px', borderRadius: '8px', backgroundColor: '#ffcccc' }} > {dynamicContent} </motion.div> </div> ); }
Comp2(固定更大尺寸组件)
import { motion } from 'framer-motion'; export default function Comp2() { return ( <div style={{ marginTop: '20px' }}> <motion.div layoutId="target-div" style={{ padding: '16px', borderRadius: '8px', backgroundColor: '#ccffcc', width: '400px' // 固定更大的宽度,或由长内容自然撑开 }} initial={false} // 禁用初始入场动画,直接显示最终状态 > 示例长内容示例长内容示例长内容示例长内容示例长内容示例长内容 </motion.div> </div> ); }
自定义动画效果(可选)
如果需要调整过渡的速度、弹性等,可以给motion.div添加transition属性:
transition={{ type: "spring", stiffness: 300, damping: 30, duration: 0.5 }}
内容的提问来源于stack exchange,提问作者InesM
相关产品推荐
相关产品推荐

