基于GSAP ScrollTrigger实现垂直卡片滚动动画需求求助
GSAP ScrollTrigger 垂直卡片切换动画解决方案
初始状态配置
先统一设置所有卡片的默认非激活样式,再单独激活第一张卡片:
// 批量设置非首卡片的初始状态 gsap.set('.card:not(:first-child)', { scale: 0.7, opacity: 0.6 }); // 确保首卡片处于激活状态 gsap.set('.card:first-child', { scale: 1, opacity: 1 });
滚动触发的卡片切换动画
遍历所有卡片,为每一组相邻卡片创建滚动触发的动画时间线,实现滚动时的状态切换:
const cards = gsap.utils.toArray('.card'); cards.forEach((card, idx) => { // 最后一张卡片无需处理切换 if (idx === cards.length - 1) return; const nextCard = cards[idx + 1]; gsap.timeline({ scrollTrigger: { trigger: card, start: 'top 50%', // 触发点:卡片顶部抵达视口中线 end: 'bottom 50%', // 结束点:卡片底部离开视口中线 scrub: true, // 动画进度与滚动进度绑定 // markers: true // 调试时可开启查看触发边界 } }) // 当前卡片淡出缩小 .to(card, { scale: 0.7, opacity: 0.6, ease: 'power1.inOut' }) // 下一张卡片淡入放大(与当前卡片动画同步开始) .to(nextCard, { scale: 1, opacity: 1, ease: 'power1.inOut' }, 0); });
SVG指示器跟随联动
让指示器根据当前激活卡片的位置移动,需要在滚动动画中同步更新指示器的Y轴位置:
const indicator = document.querySelector('.svg-indicator'); // 初始定位到第一张卡片位置 gsap.set(indicator, { y: cards[0].offsetTop }); cards.forEach((card, idx) => { if (idx === cards.length - 1) return; const nextCard = cards[idx + 1]; const nextCardTop = nextCard.offsetTop; gsap.timeline({ scrollTrigger: { trigger: card, start: 'top 50%', end: 'bottom 50%', scrub: true } }) .to(card, { scale: 0.7, opacity: 0.6 }) .to(nextCard, { scale: 1, opacity: 1 }, 0) // 同步移动指示器到下一张卡片位置 .to(indicator, { y: nextCardTop, ease: 'power1.inOut' }, 0); });
额外提示
- 确保卡片容器有足够的垂直高度,保证滚动能触发所有切换逻辑,可给容器设置
min-height: 200vh这类样式。 - 如果卡片高度不统一,可通过
gsap.utils.mapRange动态计算触发点,适配不同卡片的位置。 - 调试时可以开启
markers: true,直观查看ScrollTrigger的触发边界位置。
内容的提问来源于stack exchange,提问作者Akki Jangir
相关产品推荐
相关产品推荐

