Explicador GSAP — o nível de vídeo produzido
Constrói um explicador HTML/SVG/GSAP autossuficiente que se parece com uma animação produzida para o YouTube, não com uma apresentação de slides: uma linha do tempo GSAP por cena que conduz uma coreografia com sensação de física, um mascote anfitrião voador persistente, mundos gradientes em camadas com profundidade, populações de personagens, uma 'câmera' com vinheta e granulado, e um player com busca. Use uma estrutura apenas com CSS para pequenos funis de incorporação; use ISTO para vídeos de conteúdo de nível YouTube.
A construção de referência é scaffold.html nesta pasta da skill — um exemplo funcional de 5 cenas (tópico: 'Como os Juros Compostos Crescem') com todos os padrões abaixo em contexto, retenção + sobreposição zero verificadas. Ele é fornecido com GSAP removido: execute python3 inline-gsap.py scaffold.html uma vez (busca GSAP 3.13 em um vendor/ ignorado por git, depois o incorpora) e abra o arquivo — ele deve reproduzir. Leia sempre que um padrão abaixo não estiver claro.
Comece aqui — o caminho que não pode falhar
- Escreva o roteiro de cena PRIMEIRO como um documento markdown: por cena — timestamp, duração, VISUAL, texto NA TELA, linha de NARRAÇÃO. Termine com uma lista de verificação de precisão e verifique cada afirmação nele. As durações das cenas se tornam o array
SCENES; as linhas de narração se tornam a transcriçãosr-only. - Copie
scaffold.htmlpara<topic>.html. Ele tem todas as armadilhas pré-corrigidas: relógio da estrutura, cromo de busca, voos do anfitrião, fundos do mundo, sobreposições de câmera, personagens da população, movimento reduzido, transcrição. Executeinline-gsap.pynele e abra-o antes de tocar em qualquer coisa — ele deve reproduzir. - Substitua as cenas uma de cada vez, mantendo os cinco exemplos funcionais como sua fonte de expressões até que cada um seja substituído: S0 = gancho escuro com revelação de giro; S1 = queda com quique (física); S2 = voo de derramamento/motionPath + DrawSVG; S3 = a prova de colisão de sobreposição forçada (o padrão principal); S4 = retenção de CTA. Atualize
SCENES,FL,ACTS,CH_STARTSjuntos — eles são estruturas paralelas indexadas por cena. - QA de cada cena com quadros congelados (veja QA), corrija, depois publique (arquivo autossuficiente).
Nunca escreva a coreografia de uma cena do zero quando um padrão abaixo corresponder — adapte o padrão. É assim que você atinge o padrão, independentemente do modelo.
Contrato de arquitetura (já conectado no scaffold)
- Palco fixo 800×500 dimensionado para o contêiner (
fitScale). O relógio da cena é setTimeout (arraySCENES, segundos por cena; última entrada999= retenção de CTA;advance()chamadone()nele). - Texto/chips/legendas entram por primitivas CSS (
.fufade-up,.pppop,.fifade-in) comanimation-delayinline — barato e reproduzível. Coreografia principal é GSAP:runScene(i)(chamado deshowScene) elimina a linha do tempo anterior e constróigsap.timeline()a partir deFL[i](voo do anfitrião) +ACTS[i](ato da cena). - Cada
ACTS[i]DEVE começar com redefiniçõesgsap.set(...)para todos os elementos que toca — as cenas reativam na reprodução/busca e os tweens eliminados deixam estilos inline obsoletos. - Elementos de propriedade do GSAP recebem a classe
g-hero(ou vivem dentro de um) e nunca carregam.fu/.pp/.fi— um proprietário por elemento. pause()/resume()chamacurTl.pause()/play(); o lado CSS é congelado pela classe.paused. A navegação sempre retoma a reprodução (uma cena pausada recém-cortada fica nas entradas opacidade-0 — nunca 'buscar e permanecer pausado').- Player: barra de progresso clicável para busca (
sceneAt(frac)), botões anterior/próximo, teclas ←/→, marcas de capítulo (CH_STARTS), reprodução automática ao rolar, pausa automática ao ocultar aba. - O entregável é a trilha visual silenciosa (mestre permanece silencioso); a narração é enviada como um arquivo separado
<topic>-vo.html(variante de visualização) construído pelo pipeline ElevenLabs (veja Produção de narração). A transcriçãosr-onlyÉ o roteiro da narração. Reajustar o tempo para uma leitura = ESTENDERSCENES[i]para clipe+1.5–2s (estender nunca abandona batidas; apenas cortes o fazem).
A biblioteca de padrões (adapte, não invente)
Todos existem textualmente em scaffold.html — copie o mais próximo.
- Voo do anfitrião —
FL[i] = [[fração, x, y, apontando], ...]. Primeiro waypoint = último da cena anterior (cortes perfeitos). Pernas longas fazem curva automática via MotionPath (emfly()). A ponta do lápis fica no deslocamento do ator ≈ (−10, +95): para apontar para um alvo, estacione o anfitrião acima e à direita dele. Envie o anfitrião para fora do palco (x=850) quando uma cena precisar do quadro. - Queda com peso —
gsap.set(els,{y:-300,opacity:0})depois.to(els,{y:0,opacity:1,ease:'bounce.out',stagger:.09}). A distribuição escalonada + o quique SÃO a sensação física. (layMarblesempacota linhas dentro do recipiente; a largura da linha é 168, não 180 — mais larga e as quedas furam a parede.) - Colisão de sobreposição forçada (pico da prova) — duas barras caem em uma única trilha que não pode segurar ambas; a segunda tenta desviar (
xyoyo), falha, se acomoda; o segmento sobreposto aparece comback.oute brilha (boxShadowyoyo repeat:-1); então dois mini-personagens de ambos os distintivos aparecem dentro dele. Intenção → falha → consequência é o que faz parecer vivo. - Derramar/transformar — o contêiner gira (
transformOriginno bico), o conteúdo voa para fora um por um em arcosmotionPath({path:[{x,y},{x,y}],curviness:1.6}, ease:'power1.in'), aterrissa em uma linha, faz cross-fade para a nova forma desenhada com DrawSVG. - Revelação de giro — um ✓ tentador aparece (
back.out(2.4)), balança, depois troca pelo ✗ que entra com força (scale:3→1, power4.out) + um flash de fundo (backgroundColoryoyo). - Tentar e depois quebrar — a resposta brilha/pulsa (
scaleyoyo ×3), depois morre (opacity:.25, scale:.92, rotation:-3, power2.in); a resposta correta aparece depois. - Impacto de carimbo —
gsap.set(stamp,{opacity:0,scale:2.6,rotation:-14})→.to({opacity:1,scale:1,rotation:0,duration:.35,ease:'power4.out'}). - DrawSVG —
gsap.set(path,{drawSVG:'0%'})→.to({drawSVG:'100%'}); retorno = desenhar até 72% depois reverter rapidamente. DrawSVG sobrescrevestroke-dasharray— linhas tracejadas renderizam sólidas enquanto desenha; projete de acordo. - População como personagens (o movimento mais Kurzgesagt) — fábrica de mini-personagens
minion(size, badges): quantidades são pequenos personagens, não pontos. Enxame ambiente de 3 personagens em loops CSS de 35–55s; grupos contêm seu elenco de personagens; o momento de prova são personagens usando ambos os distintivos. - Corte de cena (integrado em
runScene) — dois painéis enviesados (acento lidera, tinta rastro .09s) varrem o palco em cada corte. Deixe-o ligado; é a vitória mais barata de 'transições reais'. Ideias de cena ricas em adereços que valem a pena roubar: um personagem de página viva, uma ruína de marcador, um arquivo, uma agulha de medidor, uma corrida de barra de progresso.
O conjunto de plugins gratuito (GSAP 3.13 — TODOS gratuitos desde a aquisição pela Webflow)
inline-gsap.py busca + incorpora core + DrawSVG + MotionPath + MorphSVG, SplitText, Physics2D, PhysicsProps, CustomEase, CustomWiggle, CustomBounce, Flip, ScrambleText. Tudo é licenciado gratuitamente. inline-gsap.py <arquivo> injeta tudo + um bloco registerPlugin no marcador <!--GSAP_INLINE-->; --refresh troca o conjunto em um arquivo já incorporado. Padrões comprovados (todos vivos no scaffold):
- Cascata de caracteres SplitText — dividir UMA VEZ na inicialização via um registro (
splitOnce(chave,sel)armazenando em cache emSPL{}— re-dividir em cada re-execução de cena aninha spans). Ponto de partida: caracteres de{opacity:0,y:14}, stagger .016, início ≤.15s. Palavra principal: caracteres de{y:-64,rotation:-9}comback.out(1.9)stagger .07; ou{scale:2.7}power4 stagger .11 = impacto de carimbo. Cenas escondem via opacidade (não display:none) para que a divisão na inicialização seja segura. - Trava de definição ScrambleText — uma linha de recompensa se embaralha no lugar:
scrambleText:{text:'≥ 1',chars:'<>=~≠≤≥',speed:.6}. Prefira escapes JS\upara símbolos em strings JS. Conjuntos de caracteres temáticos (símbolos matemáticos para definições) leem melhor do que 'upperCase' — uma longa embaralhada aleatória de maiúsculas parece uma falha de carregamento. - Assentamento CustomWiggle —
CustomWiggle.create('wigSettle',{wiggles:4,type:'easeOut'}), depoisrotation:'+=10', ease:'wigSettle'— oscila e RETORNA AO INÍCIO, então valores relativos nunca se acumulam em repetições. Use para: aterrissagens de carimbo, reações de personagens, a batida-tap-tap do lápis do anfitrião na chegada (if(wp[i][3]&&!wp[i-1][3])emfly()). - Queda CustomBounce com achatamento —
CustomBounce.create('thud',{strength:.58,squash:2.4})cria suavizações emparelhadas'thud'+'thud-squash'. O auxiliardrop(tl,targets,time,dur,stagger)executa 3 tweens sincronizados: pop de opacidade,ycom 'thud',scaleX:1.45,scaleY:.55com 'thud-squash' (transformOrigin:'50% 100%'na redefinição). Estritamente melhor quebounce.out— o achatamento É o peso. - Explosão Physics2D —
burst(tl,scene,x,y,n,time,colors): partículas de celebração/detritos onde a aterrissagem não importa (picos de colisão, carimbos de vitória). Ângulos/velocidades indexados por semente ((i*53)%140) = idêntico na repetição, sem Math.random. Remove.pfxobsoletos na reentrada; fade-out antes do fim da cena para que nada perdure. - Fusão MorphSVG — o movimento mais Kurzgesagt: N objetos 'se tornam' o conceito. Itens aterrissam em uma linha → um caminho de cápsula aparece sobre eles →
morphSVGpara a silhueta de seta enquantofillfaz tween ('mesmos objetos, nova forma', literalmente). A redefinição precisa degsap.set(path,{morphSVG:D_ORIGINAL})— um caminho com morph mantém seudmutado. - Flip: NÃO USE aqui — em um palco de coordenadas absolutas fixo de 800×500 você sempre sabe o delta; um simples tween
y:é determinístico sob QAtl.pause(t), enquanto a medição em tempo de execução do Flip quebra a limpeza de quadros congelados (e callbacks não disparam em buscas suprimidas). O Flip só vale a pena em layouts de reflow reais (listas orientadas por DOM, contêineres responsivos). Uma batida de 'reivindicar o lugar vago' é um tween de delta conhecido.
Criação de ativos (padrões 10x-pass — como os adereços param de parecer divs estilizados)
Mergulho profundo: a disciplina completa de geração de ativos (ordem de construção, fábricas, contratos SVG, portões de qualidade) vive na skill explicador-ativos — use-a sempre que CRIAR ou reconstruir um ativo; esta seção é a referência rápida.
- O adesivo de uma receita — profundidade inteiramente de
box-shadowem camadas: gota de tinta dura para baixo-direita (3px 3px 0 var(--ink)) +inset 0 2px 0 rgba(255,255,255,.3-.5)brilho superior +inset 0 -3px 0 rgba(0,0,0,.1)sombra inferior +inset 0 0 0 1-2px rgba(255,255,255,.14)borda de corte. Os insets translúcidos funcionam em QUALQUER cor de fundo, então uma passagem CSS em.xchip/.qbar/.stamp/.l3 spaneleva cada variante, clara e escura. Mantenha uma escala de raio (sm 10 / base 13 / lg 16) e UMA direção de luz (superior-esquerda) em todo o filme. - Dois tons em qualquer preenchimento sólido — troque
background:rgba(...)porlinear-gradient(180deg, mais claro, base)+ os insets de brilho/sombra. A cor semântica sobrevive; a superfície parece iluminada. - Receita de recipiente artesanal (baldes/jarras/copos) — elipse de sombra base → corpo gradiente → 2 faixas de aro cônicas com destaque branco de 1px → anel de borda + uma ELIPSE DE ABERTURA INTERNA MAIS ESCURA (essa única elipse escura é o que faz uma boca parecer 3D) → curva especular suave. Interpole os pontos finais da faixa ao longo dos lados do trapézio.
- Arte de linha artesanal em um seletor —
filter:drop-shadow(0 1.5px .5px rgba(0,0,0,.17))estático em todos os traços desenhados dá a cada seta/caixa um lado inferior de dois tons e revela COM a animação DrawSVG (filtro é independente de dashoffset). - Decore adereços orientados a GSAP com pseudo-elementos —
::before/::after(linhas pautadas, tiras adesivas, rachaduras, linhas de menisco) andam automaticamente na transformação da linha do tempo: zero nova coreografia, zero mudança de pegada. Rastreie quais pseudos estão 'ocupados' por classe — colisões são silenciosas. - Personagens de fábrica: ids apenas em singletons — o anfitrião (uma instância) pode carregar gradientes/especulares com sufixo
uid; uma fábrica com muitas inclusões (mini-personagens) deve permanecer LIVRE de id (apenas preenchimentos simples) ou os ids duplicam por todo o documento. - Preserve o contrato de coreografia ao recriar — construa um inventário de seletores a partir do roteiro PRIMEIRO; seletores posicionais são minas terrestres (
.bkt3 path= PRIMEIRO caminho deve permanecer o corpo com tween — lidere com elipses, não caminhos). Novas transformações decorativas vão em wrappers<g>. - Ressalva de brilho seguro para texto — em chips que carregam texto herói/SplitText, o brilho deve ser box-shadows inset (pintar DEBAIXO do texto), nunca uma sobreposição
::beforeposicionada (pinta SOBRE os caracteres e os escurece). - Receita de pilha de papel + orelha de cão (qualquer adereço de folha) — 2 retângulos traseiros deslocados (±0.6–1.5° rotação, creme mais escuro,
overflow:visibleno svg), triângulo de sombra de canto cortado + aba dobrada, uma régua de margem, caminho de brilho superior-esquerdo. Pegada inalterada, apenas sangria visual. - Kit de frente de gaveta/móvel — retângulo frontal + faixa de brilho superior + placa de etiqueta + barra de puxador recuada + linha de sombra de profundidade entre unidades; parametrizar paleta para a unidade destacada, manter sua classe de animação.
- Nuvem vetorial de dois tons — elipse base colorida + 3 círculos brancos sobrepostos + uma elipse superior mais brilhante; recolorir o tom base por variante de humor.
- Sobreposição de cartão de blueprint — svg filho posicionado absolutamente (grade pautada fraca + 4 marcas de canto) como primeiro filho de um cartão: textura de desenho técnico com efeito zero na classe de tween do cartão ou filho de texto.
A camada de cinema (padrões Kurzgesagt-pass)
- Rig de câmera
#xplCam— um wrapper apenas de conteúdo DENTRO de#xplStageque contém as cenas (camadas de ambiente, ator, vig/granulado ficam fora). Aproximações por batida em recompensas (~1.02–1.05, transformOrigin no herói), afastamentos em revelações, redefinir escala para 1 emrunScenea cada corte. Nunca dimensione#xplStageem si — isso é função defitScale. A cena principal ganha UM rastejo lento e ininterrupto ao longo de todo o seu ato. Verifique o risco de clipe contra os limites VISÍVEIS do adereço, não contêineres de largura total. - Ponto de atuação do anfitrião
actorBody— div.xpl-actor > [data-host], independente defly()(x/y externo) earmEl. Auxiliares: pulo (y-8 yoyo), inclinação (±4° em direção ao alvo apontado), susto (recuo+inclinação), giro de 360° na maior vitória. Redefinir cada corte. Personalidade de entrada de mini-personagem: espiar por trás de uma borda (deslocamento x → 0) ANTES do pop. - Luz de recompensa — um
#xplGlowradial desfocado compartilhado (mix-blend-mode:screen, tingir via var CSS), posicionado + iluminado atrás do objeto herói em cada maior batida de cena, redefinido por corte. Sensação instantânea de 'iluminado' por ~15 linhas. - Deriva de hora do dia — semear um
filterbase em#envFarna inicialização (para que tweens interpolem, nunca pulem denone), depois suavizar brilho/matiz/saturação por cena. O matiz só precisa percorrer um arco de 6–10° (o tom errado quebra a atmosfera). Deriva do dia (quente, alto contraste) para fim de tarde (dourado, mais suave) para o 'momento de insight' (branco nítido + brilho). A semente da meia-noite é 'tom mais legal, saturação baixa, contraste baixo' — melancolia ou mau presságio.
Estrutura do roteiro & método de produção de narração
Roteiro de cena obrigatório — escreva em markdown antes de qualquer código. O roteiro define todo o design visual e timing. Cada cena no array SCENES já tem um campo duration (segundos) que orquestra o relógio e o marcador de progresso. A narração é produzida separadamente via pipeline de texto-para-fala (ElevenLabs) e sincronizada com uma variante de visualização (<topic>-vo.html) que estende as durações das cenas conforme necessário.
Formato do roteiro:
| Cena | Timestamp | Duração | VISUAL | Texto na TELA | Narração |
|------|-----------|---------|--------|---------------|----------|
| S0 | 0.0–2.5s | 2.5s | Fundo escuro. Dado de 6 faces aparece, gira, para em '?' | 'Quer entender juros compostos?' | 'Você já se perguntou como o dinheiro realmente cresce?' |
| ... | ... | ... | ... | ... | ... |
Regras de produção:
- O script de narração (coluna Narração) é uma transcrição exata da gravação de voz final. Embaralhar/reordenar palavras no script causa incompatibilidade de sincronização labial na variante VO.
- O array
SCENESno JavaScript controla a linha do tempo visual. A variante VO tem durações estendidas (SCENES[i] = clipe + 1.5–2s) para dar tempo à fala. A duração do clipe visual permanece a original para a versão silenciosa. - Sempre verifique se cada afirmação no script de narração é factual. A lista de verificação de precisão no final do roteiro de cena verifica cada afirmação. Não invente números ou analogias — peça ao usuário fatos verificados.
- A versão VO inclui um botão 'Ler' para pausar/reproduzir a narração junto com o player de busca visual.
Plano de QA & manutenção
Cada cena deve ser inspecionada quadro a quadro:
- Congelamento
.paused—tl.pause()deve manter um quadro coerente (sem opacidade-zero, sem elementos sobrepostos). Verifique especialmente: entradas de fade-in, partículas, transições de corte. - Busca para cada posição do marcador — clique em cada marca de capítulo na barra de progresso; a cena deve aparecer completamente resolvida (não em estado de animação inicial).
- Teste de reprodução repetida — após o fim, clique em reproduzir novamente; o reset do GSAP com
gsap.set()no início de cadaACTS[i]deve limpar todos os estilos da execução anterior. - Verificação de movimento reduzido — com
prefers-reduced-motion, o GSAP deve pular todas as animações e pular para o quadro final de cada cena. Verifique se o elemento.sr-onlyé visível para leitores de tela. - Teste de janela de visualização — redimensione de 320px para 1920px de largura;
fitScaledeve dimensionar o palco proporcionalmente sem overflow. O player deve permanecer operável. - Atraso de carregamento de fonte — as fontes são carregadas na inicialização; se uma fonte falhar, o fallback não deve quebrar o layout (verifique tamanhos em px/rem).
Se uma cena falhar no QA:
- Verifique se
runScene(i)é chamado antes de qualquer atualização de elemento - Verifique se há IDs SVG duplicados (mini-personagens injetados com id fixo em vez de dinâmico)
- Verifique se
drawSVGnão está conflitando comstroke-dasharrayinline - Verifique se
gsap.set(...)reset está presente para cada novo elemento da cena
Scripts de construção
| Comando | Descrição |
|---|---|
python3 inline-gsap.py <arquivo> | Busca GSAP 3.13 + plugins em vendor/, incorpora no marcador <!--GSAP_INLINE--> |
python3 inline-gsap.py <arquivo> --refresh | Recarrega o conjunto de plugins em um arquivo já incorporado |
python3 inline-gsap.py <arquivo> --silent | Ignora a verificação de rede (usa cache) |
python3 vo-preview.py <topic>.html | Gera <topic>-vo.html com durações estendidas + controle de narração |
Resumo do contrato de código (scaffold.html aplica)
- Elementos: palco (
#xplStage), câmera (#xplCam), ator ([data-host]), fundos (#envNear,#envMid,#envFar), brilho (#xplGlow), sobreposições de câmera (#xplVig,#xplGrain) - Variáveis globais (escopo de módulo):
SCENES,FL,ACTS,CH_STARTS,curTl,sceneIx,playing - Funções:
runScene(i),advance(),sceneAt(frac),fly(tl, fl, time),drop(...),burst(...),splitOnce(key,sel) - Estados:
.pausedno palco congela animações CSS;playingbooleano rastreia o estado do player de mídia - Nunca: use
display:noneem elementos GSAP, use Math.random para animações, use Flip, ignore o resetgsap.setno início deACTS[i], aninhe spans SplitText em re-execuções