React中Framer Motion点击切换元素动画问题:无法实现延迟效果
解决Framer Motion点击切换元素的延迟动画问题
你的问题核心是缺少组件卸载时的动画控制,且进场动画未定义初始状态,导致无法实现示例中先退场再延迟进场的效果。以下是修正方案:
关键修改点
- 用
AnimatePresence包裹条件渲染的元素:Framer Motion需要这个组件追踪组件的挂载/卸载,从而触发退场和进场动画。 - 给退场元素添加
exit动画:让第一个元素在消失时有缩小淡出的过渡效果。 - 给进场元素设置
initial初始状态:配合animate实现从无到有的动画,再通过transition.delay让它等退场动画完成后启动。
修正后的代码
import { motion, AnimatePresence } from "framer-motion"; import Image from "next/image"; // 假设你使用Next.js的Image组件 // 组件内部逻辑 const [tileOpen, setTileOpen] = useState(false); const handleTrigger = () => setTileOpen(!tileOpen); return ( <AnimatePresence mode="wait"> {/* 等待退场动画完成再执行进场动画 */} {!tileOpen ? ( <motion.div key="tile" // 必须设置唯一key,让AnimatePresence识别元素变化 whileHover={{ scale: 1.2 }} exit={{ scale: 0, opacity: 0 }} // 退场动画:缩小至消失+透明 transition={{ duration: 0.4 }} // 退场动画时长 onClick={handleTrigger} className={styles.tile} /> ) : ( <motion.div key="tile-open" initial={{ scale: 0, opacity: 0 }} // 初始状态:完全缩小+透明 animate={{ scale: 1, opacity: 1 }} // 目标状态:正常大小+完全显示 transition={{ delay: 0.4, duration: 0.5 }} // 延迟时间匹配退场动画时长 onClick={handleTrigger} className={styles.tileOpen} > <Image src={`/test/test.svg`} alt="testimage" width={116} height={35} /> </motion.div> )} </AnimatePresence> );
代码说明
AnimatePresence mode="wait":强制等待前一个元素的退场动画完全结束,再渲染下一个元素的进场动画,和示例的动画顺序完全匹配。key属性:两个元素必须设置不同的key,否则AnimatePresence无法区分组件的挂载/卸载行为,动画不会触发。- 退场动画
exit:第一个元素点击后会先执行缩小+透明的过渡,时长0.4秒,模拟示例中的消失效果。 - 进场动画延迟:第二个元素的延迟设为0.4秒,刚好等第一个元素退场完成后开始进场,和示例的时间节奏一致。
内容的提问来源于stack exchange,提问作者Rajesh
相关产品推荐
相关产品推荐

