如何用Framer Motion的useAnimate实现元素进视口时opacity变为1?
问题:Framer Motion useAnimate 动画提前触发,无法仅在元素进入视口时执行
我希望HTML元素进入视口区域时展示动画,为此使用了Framer Motion的useAnimate钩子,但动画在元素进入视口前就触发了。以下是我的代码:
const Intro = () => { const [scope, animate] = useAnimate(); const isInView = useInView(scope); useEffect(() => { if (isInView) { animate("h4", { opacity: [0, 1] }, { delay: 2 }); } }, [isInView]); return ( <div className="intro"> <div ref={scope} className="row"> <h4 className="text-center mb-4 font-weight-bold"> BOOK THEBANDWALA FOR YOUR SPECIAL EVENTS </h4> <p> We provide the trusted service, our service is value for money. Anyone can book online, we do not charge any extra amount by our customers.We provide quality service as per our rates and never compromise to our quality. Search and find best service as per your requirement, we have a wide range of rates and quality that will fit your specific need. </p> </div>
解决方案
问题核心在于useInView的默认配置:它默认会在元素部分进入视口时就返回true,且初始状态可能直接触发动画。同时当前代码没有限制动画仅执行一次,可能导致元素反复进出视口时重复触发。可以通过以下步骤修复:
配置
useInView的触发规则
添加参数自定义触发条件,确保动画仅在元素完全进入视口时触发,且只执行一次:const isInView = useInView(scope, { once: true, // 动画仅触发一次 threshold: 1, // 元素100%进入视口才返回true initial: false // 初始状态设为false,避免组件挂载即触发 });优化动画与初始状态
给目标元素设置初始透明状态,避免页面加载时的闪烁问题,同时完善动画触发逻辑:const Intro = () => { const [scope, animate] = useAnimate(); const isInView = useInView(scope, { once: true, threshold: 1, initial: false }); useEffect(() => { if (isInView) { animate("h4", { opacity: 1 }, { delay: 2, duration: 0.5 }); } }, [isInView, animate]); return ( <div className="intro"> <div ref={scope} className="row"> {/* 初始设置为透明 */} <h4 className="text-center mb-4 font-weight-bold" style={{ opacity: 0 }}> BOOK THEBANDWALA FOR YOUR SPECIAL EVENTS </h4> <p> We provide the trusted service, our service is value for money. Anyone can book online, we do not charge any extra amount by our customers.We provide quality service as per our rates and never compromise to our quality. Search and find best service as per your requirement, we have a wide range of rates and quality that will fit your specific need. </p> </div> </div> ); };参数说明
once: true:确保动画仅在元素首次进入视口时执行,后续进出不再触发threshold: 1:可根据需求调整(比如设为0.5表示元素50%进入视口就触发)- 初始
opacity:0:避免页面加载时元素先显示再透明的闪烁问题
内容的提问来源于stack exchange,提问作者Paras Chouhan
相关产品推荐
相关产品推荐

