如何在React中让Framer Motion 3.3.0的scrollYProgress生效?
旧版Framer Motion scrollYProgress失效解决方案
1. 合并useViewportScroll调用
旧版Framer Motion中,重复调用useViewportScroll()会生成多个独立的滚动监听实例,直接导致scrollYProgress无法初始化和更新。将两次调用合并为一次:
// 替换原有的两次解构代码 const { scrollY, scrollYProgress } = useViewportScroll();
2. 手动计算滚动进度(绕开内置bug)
如果合并调用后问题仍存在,说明旧版内置的scrollYProgress存在已知bug,可通过scrollY手动计算滚动进度:
import { useTransform, useViewportScroll } from "framer-motion"; import { useEffect } from "react"; export const TwelveTwelveAni: React.FC<TwelveTwelveAniProps> = (props) => { const { headerOne, headerTwo, registerRef } = props; const classes = useStyles(props); const { scrollY } = useViewportScroll(); // 计算页面总可滚动高度 const getTotalScrollHeight = () => document.documentElement.scrollHeight - window.innerHeight; let totalScrollHeight = getTotalScrollHeight(); // 手动映射scrollY到0-1的进度值 const scrollYProgress = useTransform(scrollY, [0, totalScrollHeight], [0, 1]); // 监听窗口 resize,动态更新总滚动高度 useEffect(() => { const handleResize = () => { totalScrollHeight = getTotalScrollHeight(); scrollYProgress.set(scrollY.get() / totalScrollHeight); }; window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, [scrollY, scrollYProgress]); scrollY.onChange((value) => console.log(value)); scrollYProgress.onChange((value) => console.log(value)); const xLeft = useTransform(scrollYProgress, [0, 1], [-1100, 1000]); const xRight = useTransform(scrollY, [0, 2500], [1000, -1100]); // ...原return内容 };
3. 确认滚动容器是否为window
如果页面滚动是在MUI的自定义容器内(比如设置了overflow: auto的Box/Grid),useViewportScroll仅监听window滚动,此时需改用useScroll监听目标容器:
import { useScroll } from "framer-motion"; // 使用传入的registerRef作为滚动目标容器 const { scrollY, scrollYProgress } = useScroll({ target: registerRef, offset: ["start start", "end end"] // 可选,自定义进度计算的滚动范围 });
修改完成后重新测试,控制台应能正常打印scrollYProgress的数值,xLeft对应的动画也会正常触发。
内容的提问来源于stack exchange,提问作者DanBilly
相关产品推荐
相关产品推荐

