Communitygithub.com

billel-chami/video-to-gsap

Extrahiere Bewegungsabläufe aus Videos, GIFs oder Prototypen (z.B. Figma) und erstelle hardwarebeschleunigte, speicherlecksichere GSAP-Animationen für Next.js 16 mit @gsap/react und useGSAP.

Was ist video-to-gsap?

Dieses Skill analysiert Videoclips, GIFs oder Figma-Prototypen und dekonstruiert daraus die Bewegungsabläufe – wie Timing, Easing-Kurven, räumliche Trajektorien und Staffelungen. Es implementiert anschließend hardwarebeschleunigte, speicherlecksichere GSAP-Animationen in Next.js 16 unter Verwendung von `@gsap/react` und dem `useGSAP`-Hook. Das Skill stellt sicher, dass nur Composite-Eigenschaften wie `transform` und `opacity` animiert werden, um Layout-/Paint-Berechnungen zu vermeiden und CPU-Last zu minimieren. Es enthält außerdem Regeln zur Vermeidung von Flash of Unstyled Content (FOUC) mittels `autoAlpha`, zur automatischen Bereinigung von Timelines und ScrollTrigger-Instanzen bei Komponentenaushang, sowie einen Baustein für die Unterstützung von `prefers-reduced-motion`. Entwickler profitieren so von flüssigen 60/120 FPS Animationen ohne Ruckler oder Speicherlecks.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/billel-chami/nextjs-medusa-handbook/tree/HEAD/.agents/skills/video-to-gsap

In Ihrer bevorzugten KI fragen

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

Dokumentation

Video- & Prototyp-Bewegungsextraktion (video-to-gsap)

1. Zweck & Auslöser

Flüssige Mikrointeraktionen und filmische Bewegungen unterscheiden hochwertige E-Commerce-Erlebnisse. Schlecht implementierte Web-Animationen verursachen jedoch Thread-Blockaden, ausgelassene Frames (Ruckler), Speicherlecks und eine schlechte Interaction to Next Paint (INP). Dieses Skill steuert die Extraktion und Implementierung von butterweichen 60/120 FPS Animationen.

Auslöser:

  • Wenn der Benutzer einen Videoclip, ein GIF oder ein Figma-Bewegungsprototyp bereitstellt.
  • Beim Animieren von Warenkorb-Slide-Overn, Seitenübergängen, Akkordeon-Expandern, Produktkarten-Hover-Effekten oder Checkout-Abschluss-Animationen.
  • Beim Erstellen von scrollgesteuerten Animationen mit ScrollTrigger.

2. Bewegungsdekonstruktionsprotokoll

Beim Analysieren eines Bewegungsclips systematisch identifizieren:

  1. Die Choreografie-Sequenz:
    • Bühne / Auslöser: Welche Aktion startet die Bewegung (Hover, Scrollen, Routenwechsel, Klick)?
    • Antizipation: Gibt es eine subtile Gegenbewegung vor der primären Bewegung?
    • Aktion & Verschiebung: Welche Elemente bewegen sich, in welche Richtungen, über welche Entfernung (px, rem oder %)?
    • Beruhigung & Nachlauf: Überschwingt es (Spring/Elastic) oder verlangsamt es sich sanft (power3.out, expo.out)?
  2. Zeitliche Aufschlüsselung:
    • Dauer jedes Elements (z.B. Drawer-Eingang: 450ms, Hintergrund-Einblendung: 300ms).
    • Staffelungsabstand zwischen gestaffelten Kindern (z.B. Produktgitter-Karten: 0.06s Stagger).
  3. Easing-Signatur:
    • Linear: streng für kontinuierliche Schleifen (z.B. Laufschrift).
    • Ease-out (power2.out, expo.out): für UI-Eingänge (schneller Eintritt, sanftes Absetzen).
    • Ease-in (power2.in): für UI-Ausgänge (beschleunigt aus dem Bildschirm).
    • Ease-in-out (power3.inOut): für Zustandsänderungen, die im Sichtfeld bleiben.

3. Leistungs- & Hardwarebeschleunigungsstandards

Regel 1: Nur Composite-Eigenschaften animieren

  • Erlaubt: transform (x, y, xPercent, yPercent, scale, rotation, skew) and opacity (oder GSAP autoAlpha).
  • Streng verboten: Animieren von Layout- oder Paint-Eigenschaften (width, height, top, left, right, bottom, margin, padding, border-width). Diese zwingen den Browser-CPU, bei jedem Frame die Layout-Geometrie neu zu berechnen und Pixel neu zu zeichnen, was zu INP-Verschlechterung und ausgelassenen Frames führt.

Regel 2: Keine Speicherlecks mit scoped useGSAP

  • Immer das offizielle @gsap/react-Paket und den useGSAP-Hook verwenden.
  • Einen scope-Container-Ref bereitstellen. Jeder Selektor wird automatisch gescoped und alle Timeline-, Tween- und ScrollTrigger-Instanzen werden beim Aushängen der Komponente sauber zurückgesetzt und zerstört.
  • Dies verhindert Zombie-Event-Listener und Speicherrückstände in Single Page Apps und React 19 Fast-Refresh-Zyklen.

Regel 3: FOUC (Flash of Unstyled Content) vermeiden

  • autoAlpha anstelle von opacity verwenden. autoAlpha setzt visibility: hidden, wenn die Opazität 0 erreicht, und verhindert so Geisterklicks und Rendering-Flashes vor der Hydratation.
  • Alternativ CSS-Standard-Ausblendungszustände deklarieren und mit gsap.fromTo sichtbar machen.

4. Produktionsimplementierungs-Blueprint

"use client";

import { useRef } from "react";
import gsap from "gsap";
import { useGSAP } from "@gsap/react";
import { ScrollTrigger } from "gsap/ScrollTrigger";

// Registrierung der Plugins sicherstellen
if (typeof window !== "undefined") {
  gsap.registerPlugin(useGSAP, ScrollTrigger);
}

interface ProductShowcaseProps {
  readonly items: Array<{ id: string; title: string; price: string }>;
}

export function ProductShowcase({ items }: ProductShowcaseProps) {
  const containerRef = useRef<HTMLDivElement | null>(null);

  useGSAP(
    () => {
      // Hardwarebeschleunigte Eingangstimeline
      const tl = gsap.timeline({
        defaults: {
          ease: "expo.out",
          duration: 0.8,
        },
      });

      tl.from(".showcase-header", {
        autoAlpha: 0,
        y: 30,
        clearProps: "all", // Inline-Stile nach der Animation bereinigen
      }).from(
        ".product-card",
        {
          autoAlpha: 0,
          y: 40,
          scale: 0.96,
          stagger: 0.08,
          duration: 0.7,
          clearProps: "transform,opacity",
        },
        "-=0.4" // Nahtlose Überlappung
      );
    },
    { scope: containerRef } // Gescopte Bereinigungsgrenze
  );

  return (
    <section ref={containerRef} className="w-full py-16 px-6">
      <div className="showcase-header max-w-4xl mx-auto text-center mb-12">
        <h2 className="text-h1 font-bold text-content-primary">Featured Collection</h2>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-7xl mx-auto">
        {items.map((item) => (
          <article
            key={item.id}
            className="product-card will-change-transform bg-surface-elevated rounded-lg p-6 border border-border-subtle"
          >
            <h3 className="text-h3 font-semibold text-content-primary">{item.title}</h3>
            <p className="text-content-secondary mt-2">{item.price}</p>
          </article>
        ))}
      </div>
    </section>
  );
}

5. Einhaltung reduzierter Bewegung

Immer Benutzer respektieren, die reduzierte Bewegung bevorzugen:

const { contextSafe } = useGSAP({ scope: containerRef });

// Zugänglichkeitspräferenz prüfen
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;

if (prefersReducedMotion) {
  // Sofort im endgültigen Ruhezustand rendern, ohne Animation
  gsap.set([".showcase-header", ".product-card"], { autoAlpha: 1, y: 0, scale: 1 });
  return;
}

Verwandte Skills