Next.js + Framer Motion实现响应式滚动动画(支持Resize更新)
解决方案
要实现窗口 resize 时自动更新滚动动画的 offset 和 opacity 参数,核心是让 Framer Motion 的滚动监听逻辑在屏幕尺寸变化时重新初始化。以下是修改后的代码及说明:
修改后的完整组件代码
const Home2Images = ({ slice }) => { const ref = useRef(null); // 监听屏幕尺寸变化,自动更新断点状态 const isDesktop = useMediaQuery({ query: '(min-width: 768px)' }); // 可选:打印断点切换日志 useEffect(() => { console.log(isDesktop ? "DESKTOP" : "MOBILE"); }, [isDesktop]); // 根据当前断点设置滚动动画参数 const { scrollYProgress } = useScroll({ target: ref, offset: isDesktop ? ['start 80%', 'start 50%'] : ["start 55%", "end 10%"] }); const opacity = useTransform( scrollYProgress, isDesktop ? [0, 1] : [0, 0.3, 0.7, 1], isDesktop ? [0.3, 1] : [0.25, 1, 1, 0.25] ); // 假设你已定义 sliceVariation 和 projectslug const sliceVariation = slice.variation; const projectslug = slice.primary.projectSlug; // 根据你的 Prismic 字段调整 return ( <> <PrismicLink href={`project/${projectslug}`}> <motion.section ref={ref} {/* 关键:通过 key 属性触发组件重新挂载,更新动画参数 */} key={isDesktop ? 'desktop-scroll-section' : 'mobile-scroll-section'} className={`home-layout home-layout-1 ${sliceVariation}`} data-slice-type={slice.slice_type} data-slice-variation={slice.variation} {/* 将 opacity 动画应用到组件 */} style={{ opacity }} > {/* 你的切片内容 */} </motion.section> </PrismicLink> </> ); };
关键修改点说明
- 添加
key属性:给motion.section绑定与isDesktop关联的key。当屏幕尺寸变化导致isDesktop切换时,React 会卸载旧的组件实例并挂载新实例,从而重新执行useScroll和useTransform钩子,加载对应断点的动画参数。 - 自动响应断点变化:
useMediaQuery会监听窗口 resize 事件并自动更新isDesktop的值,触发组件重新渲染和挂载。 - 应用 opacity 动画:将计算得到的
opacity变量通过style属性绑定到motion.section,确保动画生效。
工作流程
- 页面加载时:根据初始屏幕尺寸设置对应的
offset和opacity参数,初始化滚动动画。 - 窗口 resize 时:
useMediaQuery检测到断点变化,更新isDesktop→ 触发motion.section重新挂载 → 重新执行滚动动画钩子,加载新的参数 → 动画自动切换为当前屏幕尺寸对应的效果。
内容的提问来源于stack exchange,提问作者Dikeneko
相关产品推荐
相关产品推荐

