Next.js中GSAP ScrollTrigger在Safari下Footer动画的滚动闪烁问题求助
需求与实现架构
- 基于Next.js框架,使用GSAP免费版实现参考Raxo网站的Footer Reveal动画:当特定区块滚动至视口底部时,Footer向上覆盖主内容
- 核心实现逻辑:
- 滚动过程中固定主内容
- 用户滚动至页面底部时,Footer向上滑动并覆盖主内容
- 采用GSAP ScrollTrigger实现动画,React构建组件结构
现存问题
- 固定抖动问题:主内容固定效果不流畅,尤其是Footer开始覆盖的过渡阶段,画面抖动不稳定
- Footer闪烁问题:在Safari(macOS及iOS)中,Footer在动画过程中出现明显闪烁;Chrome中仅轻微闪烁,可接受
- 快速滚动留白问题:快速滚动时,设置为100vh的Footer会轻微移位,底部出现空白区域,疑似未完全固定
相关代码
"use client"; import { useEffect, useRef } from "react"; import gsap from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); export default function CustomLayout({ children }) { const titleRef = useRef(null); const containerRef = useRef(null); const mainContentRef = useRef(null); useEffect(() => { if (!titleRef.current || !containerRef.current || !mainContentRef.current) return; const title = titleRef.current; const container = containerRef.current; const mainContent = mainContentRef.current; gsap.set(container, { y: "100%", force3D: true, backfaceVisibility: "hidden" }); gsap.set(mainContent, { opacity: 1, scale: 1, force3D: true, backfaceVisibility: "hidden" }); const timeline = gsap.timeline() .to(mainContent, { opacity: 1, scale: 0.99, duration: 1, ease: "power3.out", }) .to(mainContent, { y: "-2%", duration: 0.5, ease: "power2.inOut", }); ScrollTrigger.create({ trigger: title, start: "bottom bottom", end: () => `+=${container.getBoundingClientRect().height}`, pin: mainContent, animation: timeline, pinSpacing: false, scrub: 1, onEnter: () => { gsap.to(container, { y: 0, duration: 1, ease: "power4.out", clearProps: "transform", }); }, onLeaveBack: () => { gsap.to(container, { y: "100%", duration: 1, ease: "power4.out", clearProps: "transform", }); }, }); ScrollTrigger.refresh(); return () => { ScrollTrigger.killAll(); }; }, []); return ( <div className="flex flex-col"> <header>Header Content</header> <main ref={mainContentRef} className="flex-grow bg-gray-100"> {children} <div ref={titleRef} className="h-[1px] opacity-0 bg-transparent flex items-center"> <p className="relative lg:absolute h-0 w-full bg-red-500 text-5xl font-bold text-white text-center"> Footer Title </p> </div> </main> <footer style={{ minHeight: "100vh", transform: "translateZ(0)", willChange: "transform", }} ref={containerRef} className="lg:relative bg-black text-white h-[calc(100vh+180px)] sm:h-auto z-[2] overflow-hidden" > Footer Content </footer> </div> ); }
已尝试方案
- 添加
force3D: true和backfaceVisibility: hidden,未解决问题 - 调整ScrollTrigger的start、end、pinSpacing等参数,测试invalidateOnRefresh、fastScrollEnd等配置无效
- 开启/关闭CSS硬件加速(
transform: translateZ(0)、will-change: transform),问题仍存在 - 调整GSAP动画时长和scrub值,仅轻微改善固定效果,未解决留白问题
- 使用Lenis实现平滑滚动,导致Safari闪烁更严重
环境信息
- 浏览器:问题主要出现在Safari(macOS、iOS)
- GSAP版本:免费版gsap@3.x
- React版本:react@18.x
- 框架:Next.js
预期效果
主内容滚动固定流畅,Footer Reveal动画无闪烁、抖动;快速滚动时Footer保持位置,底部无空白区域
内容的提问来源于stack exchange,提问作者Talukder Habib Riyadh
相关产品推荐
相关产品推荐

