React中GSAP无限循环动画未无缝衔接,末尾现空白求助
解决React+GSAP无缝无限滚动动画问题
问题根源
当前动画仅移动原元素容器,当容器完全移出视口后无后续元素填补空白,导致视觉断层。要实现无缝循环,核心是让动画结束时,后续元素刚好衔接在原元素的视觉位置上。
解决方案步骤
- 复制元素列表:在原元素后渲染完全相同的一份元素,使容器总长度变为原来的2倍,确保滚动过程中始终有元素填充视口。
- 调整动画目标位置:动画移动距离设为容器总宽度的一半,当动画完成一轮时,复制的元素刚好衔接原元素的起始位置,配合无限重复实现无缝效果。
- 优化元素key值:为复制的元素设置唯一key,避免React渲染警告。
修改后的完整代码
import { useEffect, useRef } from "react"; import gsap from "gsap"; export default function MoreAboutMe() { const tagReelRowRefs = useRef([]); // 定义原元素数量,方便后续复制 const itemCount = 6; const items = Array.from({ length: itemCount }, (_, i) => i); useEffect(() => { const reelEl = tagReelRowRefs.current[0]; if (!reelEl) return; const totalWidth = reelEl.scrollWidth; // 移动距离为总宽度的一半,刚好让复制的元素衔接原元素 const moveDistance = totalWidth / 2; gsap.set(reelEl, { rotate: 45, y: 0, x: 0 }); const tl = gsap.timeline({ repeat: -1, ease: "none" }); tl.to(reelEl, { duration: 20, y: -moveDistance, x: -moveDistance, ease: "none", }); }, [items.length]); return ( <div className="relative z-10 w-full h-[300px] gap-4 overflow-hidden cursor-default" {/* 调整父容器高度,适配旋转后的元素 */} > <div className="relative flex text-center whitespace-nowrap" ref={(el) => (tagReelRowRefs.current[0] = el)} > {/* 渲染原元素+复制元素 */} {[...items, ...items].map((index, idx) => ( <div key={`item-${idx}`} className={`relative line-height-[100%] text-[3.75vw] px-[58px] flex-none uppercase`} > <div className="w-[300px] h-[200px] bg-white rounded-2xl relative z-10 inline-block text-black"> l {index} </div> </div> ))} </div> </div> ); }
关键修改说明
- 元素复制:通过
[...items, ...items]渲染两份相同元素,确保容器滚动时始终有元素填补视口。 - 动画距离调整:
moveDistance = totalWidth / 2,移动一半总宽度后,复制元素的起始位置刚好对应原元素的起始位置,重复动画时视觉上无断层。 - 父容器高度:显式设置
h-[300px]适配旋转45度后的元素高度,避免元素被裁剪。 - 唯一key:用
item-${idx}作为key,确保原元素和复制元素的key不重复。
内容的提问来源于stack exchange,提问作者agoumi
相关产品推荐
相关产品推荐

