Communitygithub.com

billel-chami/video-to-gsap

Use esta habilidade quando receber uma gravação de vídeo, GIF ou animação de protótipo (ex: protótipo Figma). Ela desconstrói a coreografia do movimento em temporização, curvas de easing, trajetórias espaciais e escalonamentos, e implementa animações GSAP aceleradas por hardware e sem vazamentos de memória no Next.js 16 usando @gsap/react e useGSAP.

O que é video-to-gsap?

Esta habilidade é projetada para desenvolvedores que desejam transformar gravações de vídeo, GIFs ou protótipos de animação (como protótipos do Figma) em animações GSAP de alto desempenho para o Next.js 16. Ela analisa a coreografia do movimento, identificando sequências de ações, temporização, curvas de easing e trajetórias espaciais. A implementação resultante utiliza apenas propriedades de composição (transform e opacity) para garantir 60/120 FPS suaves, evitando travamentos e degradação do INP. A habilidade também impõe boas práticas como o uso do hook useGSAP com escopo de ref para eliminar vazamentos de memória, eliminação de FOUC com autoAlpha e conformidade com preferências de movimento reduzido. Ela é ideal para interações fluidas em e-commerce, transições de página, animações acionadas por scroll e microinterações em geral.

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

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Extração de Movimento de Vídeo e Protótipo (video-to-gsap)

1. Propósito e Gatilhos

Microinterações fluidas e movimento cinematográfico diferenciam experiências de comércio de alto nível. No entanto, animações web mal implementadas causam bloqueio de thread, quadros perdidos (jank), vazamentos de memória e má Interaction to Next Paint (INP). Esta habilidade governa a extração e implementação de animações suaves como manteiga a 60/120 FPS.

Gatilhos:

  • Quando o usuário fornecer um clipe de vídeo, GIF ou protótipo de movimento Figma.
  • Ao animar sobreposições de carrinho, transições de página, expansões de acordeão, hovers em cartões de produto ou celebrações de conclusão de checkout.
  • Ao criar animações acionadas por scroll com ScrollTrigger.

2. Protocolo de Desconstrução de Movimento

Ao analisar um clipe de movimento, identifique sistematicamente:

  1. A Sequência de Coreografia:
    • Cena / Gatilho: Qual ação inicia o movimento (hover, scroll, mudança de rota, clique)?
    • Antecipação: Há um contra-movimento sutil antes do movimento principal?
    • Ação e Deslocamento: Quais elementos se movem, em quais direções, a que distância (px, rem ou %)?
    • Estabilização e Seguimento: Ele ultrapassa (spring/elastic) ou desacelera suavemente (power3.out, expo.out)?
  2. Detalhamento de Temporização:
    • Duração de cada elemento (ex: entrada do drawer: 450ms, fade do fundo: 300ms).
    • Offset de escalonamento entre filhos escalonados (ex: cartões de grade de produto: 0.06s de escalonamento).
  3. Assinatura de Easing:
    • Linear: estritamente para loops contínuos (ex: marquee).
    • Ease-out (power2.out, expo.out): para entradas de UI (entrada rápida, estabilização suave).
    • Ease-in (power2.in): para saídas de UI (acelera para fora da tela).
    • Ease-in-out (power3.inOut): para transformações de estado que permanecem na vista.

3. Padrões de Desempenho e Aceleração de Hardware

Regra 1: Anime Apenas Propriedades de Composição

  • Permitido: transform (x, y, xPercent, yPercent, scale, rotation, skew) e opacity (ou autoAlpha do GSAP).
  • Estritamente Proibido: Animar propriedades de layout ou pintura (width, height, top, left, right, bottom, margin, padding, border-width). Estas forçam a CPU do navegador a recalcular a geometria do layout e repintar pixels a cada quadro, causando degradação do INP e perda de quadros.

Regra 2: Zero Vazamentos de Memória com useGSAP com Escopo

  • Sempre use o pacote oficial @gsap/react e o hook useGSAP.
  • Forneça um scope container ref. Cada seletor dentro será automaticamente escopado, e todas as timelines, tweens e instâncias ScrollTrigger serão limpas e mortas quando o componente desmontar.
  • Isso previne listeners de eventos zumbis e retenção de memória em Single Page Apps e ciclos de fast-refresh do React 19.

Regra 3: Elimine FOUC (Flash de Conteúdo Não Estilizado)

  • Use autoAlpha em vez de opacity. autoAlpha define visibility: hidden quando a opacidade chega a 0, prevenindo cliques fantasmas e flashes de renderização antes da hidratação.
  • Alternativamente, declare estados ocultos padrão no CSS e revele-os com gsap.fromTo.

4. Blueprint de Implementação em Produção

"use client";

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

// Garanta que os plugins sejam registrados com segurança
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(
    () => {
      // Timeline de entrada acelerada por hardware
      const tl = gsap.timeline({
        defaults: {
          ease: "expo.out",
          duration: 0.8,
        },
      });

      tl.from(".showcase-header", {
        autoAlpha: 0,
        y: 30,
        clearProps: "all", // Limpa estilos inline pós-animação
      }).from(
        ".product-card",
        {
          autoAlpha: 0,
          y: 40,
          scale: 0.96,
          stagger: 0.08,
          duration: 0.7,
          clearProps: "transform,opacity",
        },
        "-=0.4" // Sobreposição perfeita
      );
    },
    { scope: containerRef } // Limite de limpeza com escopo
  );

  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">Coleção em Destaque</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. Conformidade com Movimento Reduzido

Sempre respeite os usuários que preferem movimento reduzido:

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

// Verifique a preferência de acessibilidade
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;

if (prefersReducedMotion) {
  // Renderiza instantaneamente no estado final de descanso sem animação
  gsap.set([".showcase-header", ".product-card"], { autoAlpha: 1, y: 0, scale: 1 });
  return;
}

Habilidades Relacionadas