Framer Motion + Next.js:layoutId与initial属性冲突致页面过渡异常
Framer Motion + Next.js 图片过渡透明度问题解决思路
场景与需求
- 首页展示3张图片概览
- 点击图片时,其他图片淡出,目标图片放大并跳转至大图页面
- 返回时,大图缩小,其他图片延迟淡入
当前问题
通过layoutId实现了图片尺寸的正常过渡,但给带layoutId的图片容器添加initial/animate/exit透明度属性后,这些透明度会作用到layoutId的过渡流程中,导致大图在过渡过程中也变得透明。
现有代码
import { motion } from "framer-motion"; export default function Image({ id }) { return ( <motion.div layoutId={`wrapper_image_${id}`} transition={{ duration: 0.2 }} initial={{ opacity: 0.2 }} animate={{ opacity: 1 }} exit={{ opacity: 0.2 }} className="relative w-full h-full" > <motion.img className="h-full w-full object-cover" src={`/mountain${id}.jpeg`} /> </motion.div> ); }
解决思路
分离动画载体:将
layoutId布局过渡与透明度动画拆到不同元素上。让外层容器负责透明度的initial/animate/exit逻辑,内层单独的motion.div承载layoutId和尺寸过渡。这样布局过渡的元素不会被透明度影响,只有非目标图片的外层容器会执行淡出。
示例调整:import { motion } from "framer-motion"; export default function Image({ id, isTarget }) { return ( <motion.div initial={{ opacity: 0.2 }} animate={{ opacity: 1 }} exit={{ opacity: isTarget ? 1 : 0.2 }} transition={{ duration: 0.2 }} className="relative w-full h-full" > <motion.div layoutId={`wrapper_image_${id}`} className="w-full h-full" > <motion.img className="h-full w-full object-cover" src={`/mountain${id}.jpeg`} /> </motion.div> </motion.div> ); }状态控制非目标图片:在首页组件中维护点击状态,仅让被点击的图片保持透明度1,其他图片触发淡出动画。带
layoutId的元素不设置任何透明度相关属性,只负责尺寸过渡,彻底避免透明度对布局过渡的干扰。自定义过渡配置:利用Framer Motion的过渡拆分配置,为
layout和opacity分别设置动画规则,同时结合状态确保只有非目标图片才会触发透明度的exit动画,目标图片的透明度始终保持1。
示例过渡配置:transition={{ layout: { duration: 0.2 }, opacity: { duration: 0.2 } }}结合AnimatePresence条件渲染:在
AnimatePresence中根据点击状态控制非目标图片的exit动画触发,目标图片因需要保留layoutId过渡,不执行透明度的退出动画。
内容的提问来源于stack exchange,提问作者Sef
相关产品推荐
相关产品推荐

