Frame Motion:仅检测Y轴可见性触发横向滚动元素动画
解决横向滚动元素Y轴可见即触发Frame Motion动画的问题
默认情况下,Frame Motion的whileInView会同时检测元素在X、Y轴上的可见性,所以即使Y轴在视口内,X轴超出的话也不会触发动画。要实现只看Y轴的需求,得自定义可见性判断逻辑,用useInView钩子来实现:
- 导入
useInView钩子替代组件自带的视口检测 - 自定义相交判断函数,只校验Y轴的可见性
- 根据判断结果手动控制动画状态
具体代码修改如下:
import { motion, useInView, useRef } from "framer-motion"; const ScrollTriggerYOnly = ({ variant, duration, delay, children, ...props }) => { const ref = useRef(null); // 自定义Y轴可见性判断逻辑 const isInView = useInView(ref, { once: true, margin: "100px", threshold: (entry) => { const { top, bottom } = entry.boundingClientRect; const viewportHeight = window.innerHeight; // 只要元素在Y轴方向和视口有重叠,就判定为可见 return bottom > 0 && top < viewportHeight; } }); return ( <motion.div ref={ref} variants={variant} initial="hidden" // 根据自定义判断结果触发动画 animate={isInView ? "visible" : "hidden"} transition={{ duration, delay }} {...props} > {children} </motion.div> ); };
关键说明:
useInView的threshold参数支持传入函数,我们通过boundingClientRect获取元素Y轴位置,只要元素没完全在视口上方或下方,就判定为可见- 移除原组件的
whileInView和viewport配置,改用animate属性由自定义的isInView状态控制 - 保留
once: true确保动画只触发一次,margin参数仍可用来调整触发动画的提前/延后范围
这样修改后,不管元素在X轴是否超出视口,只要Y轴方向和视口有重叠,就会启动动画。
内容的提问来源于stack exchange,提问作者Phoenixlaw9
相关产品推荐
相关产品推荐

