Communitygithub.com

Scroll-Animation (GSAP + ScrollTrigger + Lenis)

Erstelle Scroll-gesteuerte Animationen mit GSAP, ScrollTrigger, SplitText und Lenis für sanftes Scrollen – Enthüllungen, fixierte Abschnitte, horizontales Scrollen, Parallaxe, scrubbare Timeline und Texteffekte in Vanilla JS, React, Next.js, Vue/Nuxt oder Astro mit korrektem Setup, Bereinigung und responsiven Alternativen.

Was ist Scroll-Animation (GSAP + ScrollTrigger + Lenis)?

Diese Fähigkeit (Skill) ermöglicht es dir, professionelle Scroll-basierte Animationen und interaktive Geschichten auf modernen Webprojekten umzusetzen. Sie basiert auf den bewährten Bibliotheken GSAP, ScrollTrigger, SplitText und Lenis und deckt eine breite Palette von Effekten ab: von eleganten Einblendungen über fixierte Abschnitte (Pin) und Parallaxe bis hin zu horizontalem Scrollen und Textanimationen. Der Skill unterstützt gängige Frameworks wie React, Next.js (App Router), Vue/Nuxt, Astro und reines Vanilla JavaScript. Er liefert nicht nur Installations- und Konfigurationsanleitungen, sondern betont auch kritische Best Practices, die in der Praxis oft zu Fehlern führen: korrekte Verwendung von ScrollTrigger (niemals innerhalb von verschachtelten Tweens), die Trennung von Lenis und ScrollSmoother, eine zentrale Setup-Datei für alle Projekte und die Integration mit den jeweiligen Framework-Lebenszyklen (useGSAP, gsap.context, onMounted/onUnmounted). Ein besonderer Schwerpunkt liegt auf Barrierefreiheit (prefers-reduced-motion), Responsivität (gsap.matchMedia) und Performance (Animation nur von transforms/opacity, Vermeidung von Layout-Änderungen). Der Skill ist als Ergänzung zu den offiziellen GreenSock-Skills gedacht und fokussiert auf die praktische Projektintegration und das Vermeiden typischer Fehler.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/KILN-skills/kiln/tree/HEAD/skills/scroll-animation

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht Scroll-Animation (GSAP + ScrollTrigger + Lenis)?

Wenn die offiziellen GreenSock-Skills (gsap-core, gsap-scrolltrigger, gsap-react, gsap-plugins) installiert sind, verwende diese für API-Details; dieser Skill behandelt Projekteinrichtung, Integration und die Fehler, die echte Websites zum Absturz bringen.

1. Installation

npm i gsap lenis
npm i @gsap/react   # Nur React / Next.js

Alle GSAP-Plugins (ScrollTrigger, SplitText, Flip, ScrollSmoother, MorphSVG, DrawSVG…) sind im öffentlichen gsap-Paket enthalten und für die kommerzielle Nutzung kostenlos. Importiere aus gsap/<PluginName> und rufe gsap.registerPlugin(...) einmal auf.

2. Ein einziges Setup-Modul

Erstelle lib/motion/setup.(js|ts) (oder animations/), das einmal auf dem Client importiert wird:

import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { SplitText } from "gsap/SplitText";
import Lenis from "lenis";
import "lenis/dist/lenis.css";

gsap.registerPlugin(ScrollTrigger, SplitText);

export function initSmoothScroll() {
  if (matchMedia("(prefers-reduced-motion: reduce)").matches) return null;
  const lenis = new Lenis();
  lenis.on("scroll", ScrollTrigger.update);
  const tick = (time) => lenis.raf(time * 1000); // GSAP-Zeit ist in Sekunden, Lenis erwartet ms
  gsap.ticker.add(tick);
  gsap.ticker.lagSmoothing(0);
  return () => { gsap.ticker.remove(tick); lenis.destroy(); };
}

Verwende entweder Lenis oder GSAP ScrollSmoother, nicht beide.

3. Framework-Integration

React / Next.js (App Router) – Dateien, die GSAP verwenden, benötigen "use client". Verwende immer useGSAP (automatische Bereinigung, kein doppelter Durchlauf im Strict Mode):

"use client";
import { useRef } from "react";
import gsap from "gsap";
import { useGSAP } from "@gsap/react";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(useGSAP, ScrollTrigger);

export function Features() {
  const root = useRef<HTMLElement>(null);
  useGSAP(() => {
    const mm = gsap.matchMedia();
    mm.add("(prefers-reduced-motion: no-preference)", () => {
      gsap.from(".feature", {
        autoAlpha: 0, y: 32, stagger: 0.08, ease: "power3.out",
        scrollTrigger: { trigger: root.current, start: "top 75%" },
      });
    });
  }, { scope: root }); // Selektoren sind auf diese Komponente beschränkt
  return <section ref={root}>…</section>;
}
  • Event-Handler, die Animationen erzeugen: mit contextSafe aus useGSAP umschließen.
  • Smooth-Scroll-Provider: eine Client-Komponente im Root-Layout, die initSmoothScroll() in einem Effekt aufruft (oder ReactLenis von lenis/react mit autoRaf: false und dem GSAP-Ticker).
  • Routenwechsel in Next.js: nach oben scrollen (lenis.scrollTo(0, { immediate: true })) und ScrollTrigger.refresh() aufrufen, nachdem die neue Seite gemountet ist.

Vue / Nuxt – Erstelle in onMounted innerhalb von gsap.context(() => {…}, rootEl), rufe ctx.revert() in onUnmounted auf. Nuxt: Client-only-Plugin (plugins/gsap.client.ts).

Astro / statische Webseiten mit mehreren Seiten – Ein <script> im Layout; bei View Transitions erneut initialisieren auf astro:page-load und Trigger auf astro:before-swap beenden.

Vanilla – Eine main.js, die nach DOM-Ready ausgeführt wird; pro Abschnitt in gsap.context() gruppieren.

4. ScrollTrigger-Regeln, die 90% der Fehler verhindern

  • Setze scrollTrigger auf eine Timeline oder einen Tween der obersten Ebene – niemals auf Tweens, die innerhalb einer Timeline verschachtelt sind.
  • Verwende ease: "none" mit scrub.
  • Die Reihenfolge der Erstellung ist wichtig: Erstelle Trigger von oben nach unten in der Seitenreihenfolge (oder setze refreshPriority), besonders bei Pins.
  • Pinne einen Wrapper, nicht das Element, das du animierst. Pinne nicht innerhalb eines transform-Elterns. Vermeide pinSpacing: false, es sei denn, es ist beabsichtigt.
  • Verwende Funktionswerte (x: () => …) + invalidateOnRefresh: true für alles, was von der Viewport-Größe abhängt.
  • Rufe ScrollTrigger.refresh() auf, nachdem Bilder/Schriftarten/dynamische Inhalte das Layout ändern (window.addEventListener("load", …), document.fonts.ready).
  • Debugge mit markers: true – entferne sie vor dem Deployment.
  • Initial verborgene Zustände: Verwende gsap.from/fromTo oder autoAlpha, die von JS gesetzt werden, damit der Inhalt ohne JS sichtbar ist.
  • once: true für Enthüllungen, die nicht wiederholt werden sollen (die meisten).

5. Responsiv & reduzierte Bewegung

Umschließe jede Szene mit gsap.matchMedia():

const mm = gsap.matchMedia();
mm.add({
  isDesktop: "(min-width: 1024px)",
  isMobile: "(max-width: 1023px)",
  motionOK: "(prefers-reduced-motion: no-preference)",
}, ({ conditions: c }) => {
  if (!c.motionOK) return;            // statisches Layout, keine Animation
  if (c.isDesktop) { /* gepinnte / horizontale Szenen */ }
  if (c.isMobile)  { /* nur einfache Fade-Ups */ }
});

matchMedia setzt automatisch zurück, wenn sich die Bedingungen ändern – keine manuelle Bereinigung nötig.

6. Performance

  • Animiere x/y/scale/rotation/autoAlpha (Transforms + Opacity). Vermeide das Animieren von width/height/top/left und starkem filter: blur() auf großen Flächen.
  • Bevorzuge eine Timeline pro Abschnitt gegenüber Dutzenden separaten Triggern; ScrollTrigger.batch für viele identische Enthüllungen.
  • gsap.quickTo für Pointer-Follow-Effekte.
  • Große Bilder in gescrubbten Szenen: korrekte sizes und vermeide das Skalieren großer Bitmaps in jedem Frame.

7. Überprüfung

Scrolle die ganze Seite schnell hoch und runter; ändere die Fenstergröße; lade mitten auf der Seite neu; navigiere weg und zurück (SPA) – keine Sprünge, keine doppelten Pins, keine Konsolenfehler. Teste mit aktivierter reduzierter Bewegung, bei 375px und mit CPU-Drosselung.

Rezepte für häufige Effekte: ../motion-direction/references/patterns.md.

Verwandte Skills