Lenis

Lesson 17

Lenis is initialized with new Lenis(). To sync with GSAP, pass Lenis into the GSAP ticker: gsap.ticker.add((time) => lenis.raf(time * 1000)). gsap.ticker.lagSmoothing(0) prevents GSAP from dropping frames. lenis.on('scroll', ScrollTrigger.update) keeps all ScrollTrigger positions accurate. The result: ScrollTrigger-powered animations (fade-ins, parallax scrub) play through Lenis’s smooth virtual scroll seamlessly.

Source Code script.js
gsap.registerPlugin(ScrollTrigger);

// ── Lenis setup ───────────────────────────────────────────────
const lenis = new Lenis();

// Drive Lenis from GSAP ticker for frame-perfect sync
gsap.ticker.add((time) => {
  lenis.raf(time * 1000);
});
gsap.ticker.lagSmoothing(0);

// Keep ScrollTrigger positions in sync with Lenis scroll
lenis.on('scroll', ScrollTrigger.update);

// ── Fade-in blocks ────────────────────────────────────────────
gsap.utils.toArray('.fade-block').forEach(el => {
  gsap.to(el, {
    opacity: 1,
    y: 0,
    duration: 0.7,
    ease: 'power2.out',
    scrollTrigger: {
      trigger: el,
      start: 'top 85%',
    },
  });
});

// ── Parallax background ───────────────────────────────────────
gsap.to('.parallax-bg', {
  yPercent: 30,
  ease: 'none',
  scrollTrigger: {
    trigger: '.parallax-section',
    start: 'top bottom',
    end: 'bottom top',
    scrub: true,
  },
});