GSAP ScrollTrigger分屏固定效果异常:固定元素消失移位求助
React中GSAP ScrollTrigger分屏固定滚动问题求助
我在React项目中使用GSAP ScrollTrigger实现分屏固定滚动效果,预期文本滚动时图片保持固定并随文本切换,但当触发元素(文本元素)到达start标记时,图片消失并出现在文本底部,调整scrub值后问题仍未解决,特此求助。
原代码
JSX代码
import { useEffect } from 'react'; import './Facilities.css' import gsap from 'gsap'; import ScrollTrigger from 'gsap/ScrollTrigger'; function Facilities() { const imagesUrl = ["imgs/mechines/cardio.jpg","imgs/mechines/weight.jpg","imgs/mechines/rope.jpg","imgs/mechines/sauna.jpg"] useEffect(()=>{ gsap.registerPlugin(ScrollTrigger); gsap.to(".imagesectionfacilities",{duration:1,scrollTrigger:{ trigger:".txtFacilities", start:"top top", end:"bottom bottom", markers:true, pin:".imagesectionfacilities", }})},[]) return ( <div className='facilites'> <div className='txtFacilities'> <div className="cardioFacilities">Cardio</div> <div className="cardioFacilities">Strength</div> <div className="cardioFacilities">Functional</div> <div className="cardioFacilities">Amenities</div> </div> <div className="imagesectionfacilities"> <img src={imagesUrl[0]} alt="" className='cardImg'/> </div> </div> ) } export default Facilities
CSS代码
.facilites{ height: auto; width: 100%; display: flex; justify-content: center; gap:40%; border: 1px solid rgb(0, 255, 21); } .cardImg{ height: 250px; width: 350px; border: none; border-radius: 10px; object-fit: cover; } .txtFacilities{ border: 1px solid rgb(255, 0, 0); } .cardioFacilities{ display: flex; font-size: 50px; color: white; font-weight: 500; align-items: center; justify-content: center; height: 100vh; } .imagesectionfacilities{ display: flex; font-size: 50px; color: white; font-weight: 500; align-items: center; justify-content: center; height: 100vh; border: 1px solid blue; }
问题原因及修复方案
- 布局冲突:原flex布局下,
pin操作会打乱flex排列规则,导致图片容器移位。需将图片容器脱离flex流,改用绝对定位。 - 滚动范围不匹配:原
end:"bottom bottom"未准确匹配文本块总滚动长度,导致固定逻辑失效。 - 缺少图片切换逻辑:原代码未实现文本滚动时的图片切换,需添加GSAP时间线动画配合滚动触发。
修改后的完整代码
JSX代码
import { useEffect, useRef } from 'react'; import './Facilities.css' import gsap from 'gsap'; import ScrollTrigger from 'gsap/ScrollTrigger'; function Facilities() { const imagesUrl = ["imgs/mechines/cardio.jpg","imgs/mechines/weight.jpg","imgs/mechines/rope.jpg","imgs/mechines/sauna.jpg"]; const imgRef = useRef(null); useEffect(()=>{ gsap.registerPlugin(ScrollTrigger); // 创建图片切换时间线 const tl = gsap.timeline({ scrollTrigger: { trigger: ".txtFacilities", start: "top top", end: "+=300vh", // 4个100vh区块,总滚动距离为3个屏幕高度 scrub: 1, markers: true, pin: ".imagesectionfacilities", pinSpacing: false // 取消自动添加的padding,避免布局偏移 } }); // 为每个文本区块添加图片切换动画 imagesUrl.forEach((_, index) => { if (index > 0) { tl.to(imgRef.current, { duration: 1, attr: { src: imagesUrl[index] }, ease: "none" }); } }); }, []); return ( <div className='facilites'> <div className='txtFacilities'> <div className="cardioFacilities">Cardio</div> <div className="cardioFacilities">Strength</div> <div className="cardioFacilities">Functional</div> <div className="cardioFacilities">Amenities</div> </div> <div className="imagesectionfacilities"> <img ref={imgRef} src={imagesUrl[0]} alt="" className='cardImg'/> </div> </div> ) } export default Facilities
CSS代码
.facilites{ position: relative; /* 作为图片容器的定位基准 */ height: auto; width: 100%; display: flex; justify-content: flex-start; /* 调整为靠左对齐文本 */ padding-left: 10%; /* 给文本留出左侧空间 */ border: 1px solid rgb(0, 255, 21); } .cardImg{ height: 250px; width: 350px; border: none; border-radius: 10px; object-fit: cover; } .txtFacilities{ border: 1px solid rgb(255, 0, 0); } .cardioFacilities{ display: flex; font-size: 50px; color: white; font-weight: 500; align-items: center; justify-content: center; height: 100vh; } .imagesectionfacilities{ position: absolute; /* 脱离flex布局 */ right: 10%; /* 固定在右侧 */ top: 50%; transform: translateY(-50%); /* 垂直居中 */ display: flex; align-items: center; justify-content: center; height: auto; /* 取消固定高度,适应图片 */ border: 1px solid blue; }
关键修改点说明
- 布局调整:父容器设为
relative,图片容器设为absolute并固定在右侧,避免flex布局干扰固定逻辑。 - 滚动范围修正:
end值设为+=300vh,匹配4个100vh文本块的滚动总长度。 - 图片切换逻辑:使用GSAP时间线,配合
scrub实现滚动时平滑切换图片。 - 取消pinSpacing:避免ScrollTrigger自动添加padding导致的布局偏移。
内容的提问来源于stack exchange,提问作者NINJA GAMER
相关产品推荐
相关产品推荐

