GSAP + Lenis 平滑滚动实战

#gsap#lenis#animation
GSAP + Lenis 平滑滚动实战

同步原理

Lenis 和 GSAP ScrollTrigger 需要同步才能正确工作。核心思路是:

  1. 禁用 Lenis 的自动 RAFautoRaf: false
  2. 用 GSAP ticker 驱动 Lenisgsap.ticker.add() 替代 requestAnimationFrame
  3. Lenis 滚动事件更新 ScrollTriggerlenis.on('scroll', ScrollTrigger.update)
  4. 禁用 GSAP 延迟平滑gsap.ticker.lagSmoothing(0)

核心代码

import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import Lenis from 'lenis';

gsap.registerPlugin(ScrollTrigger);

const lenis = new Lenis({ autoRaf: false });

lenis.on('scroll', ScrollTrigger.update);

gsap.ticker.lagSmoothing(0);
gsap.ticker.add((time) => {
  lenis.raf(time * 1000);
});

销毁逻辑

在页面切换(View Transitions)时,必须销毁旧的 Lenis 实例和 ticker 回调, 否则会导致多个实例同时运行、滚动异常。

export function destroySmoothScroll() {
  if (lenis) {
    gsap.ticker.remove(tickerCallback);
    lenis.destroy();
    lenis = null;
  }
}

降级处理

当用户启用了 prefers-reduced-motion: reduce 时,应跳过平滑滚动初始化, 直接使用浏览器原生滚动。这在 scroll.jsinitSmoothScroll() 中已处理。