You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中GSAP结合Locomotive Scroll Beta元素固定失效求助

问题修复方案:Next.js中GSAP+Locomotive Scroll Beta滚动固定元素失效

1. 适配Next.js的DOM加载时机

Next.js(尤其App Router)默认服务端渲染,直接在组件顶层初始化会因DOM未挂载失效,必须用useEffect确保DOM就绪后执行:

'use client';
import { useEffect, useRef } from 'react';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import LocomotiveScroll from 'locomotive-scroll';
import 'locomotive-scroll/dist/locomotive-scroll.css';

gsap.registerPlugin(ScrollTrigger);

export default function PinComponent() {
  const containerRef = useRef(null);
  const scrollInstance = useRef(null);

  useEffect(() => {
    if (!containerRef.current) return;

    // 初始化Locomotive Scroll
    scrollInstance.current = new LocomotiveScroll({
      el: containerRef.current,
      smooth: true
    });

    // 关联ScrollTrigger与Locomotive滚动事件
    scrollInstance.current.on('scroll', ScrollTrigger.update);
    ScrollTrigger.scrollerProxy(containerRef.current, {
      scrollTop(value) {
        return arguments.length ? scrollInstance.current.scrollTo(value, 0, 0) : scrollInstance.current.scroll.instance.scroll.y;
      },
      getBoundingClientRect() {
        return {top: 0, left: 0, width: window.innerWidth, height: window.innerHeight};
      },
      pinType: containerRef.current.style.transform ? "transform" : "fixed"
    });

    // 创建固定元素的GSAP时间线
    const tl = gsap.timeline({
      scrollTrigger: {
        scroller: containerRef.current,
        trigger: '.pin-section',
        start: 'top top',
        end: 'bottom bottom',
        scrub: true,
        pin: '.pin-element'
      }
    });

    // 占位动画维持时间线长度(可替换为自定义动画)
    tl.to('.pin-element', {duration: 1, opacity: 1});

    // 组件卸载时清理实例
    return () => {
      ScrollTrigger.getAll().forEach(t => t.kill());
      scrollInstance.current?.destroy();
    };
  }, []);

  return (
    <div ref={containerRef} className="scroll-container">
      <div className="pin-section">
        <div className="pin-element">固定元素</div>
      </div>
      {/* 补充足够高度的内容区域,触发滚动效果 */}
      <div style={{height: '200vh'}}></div>
    </div>
  );
}

2. 修正容器样式

确保滚动容器的高度设置正确,让Locomotive Scroll能识别滚动区域:

.scroll-container {
  height: 100vh;
  overflow: hidden;
}

3. 关键配置说明

  • 必须添加'use client'指令,强制组件在客户端执行DOM操作
  • 明确指定scrollTrigger.scroller为Locomotive的容器元素,不能依赖全局window
  • 组件卸载时清理ScrollTrigger和Locomotive实例,避免内存泄漏

内容的提问来源于stack exchange,提问作者Nafiz Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 16:46:06