CommunityEscrita e Ediçãogithub.com

FreeFrame-Studio

Crie animações do zero, tomando decisões na ordem que determina se elas parecem certas — deve animar, qual o propósito, qual ferramenta, quais propriedades, qual curva e duração, como interrompe, como sai. Escreve a implementação. Use quando for solicitado a animar algo, adicionar movimento, fazer um componente parecer vivo ou construir uma transição. Para criticar movimento existente, use review-animations; para auditar uma base de código inteira, use improve-animations.

O que é FreeFrame-Studio?

Este skill é especializado em construir animações para interfaces de usuário, seguindo uma filosofia rigorosa baseada nos princípios de Emil Kowalski. Ele não é uma ferramenta genérica de animação: seu foco é implementar movimento que seja preciso, com propósito e que passe por uma revisão crítica. O skill não audita código existente (isso é função de `improve-animations`), não critica diffs (função de `review-animations`) e não constrói para React Native (função de `animate-expo`). Em vez disso, ele orienta o usuário por uma sequência de decisões: primeiro, determinar se aquele elemento *deve* animar (considerando frequência de uso e contexto); segundo, nomear o propósito da animação (feedback, consistência espacial, etc.); terceiro, escolher a ferramenta mais leve que funcione (transição CSS, animação CSS, WAAPI, ou Motion); quarto, selecionar propriedades restritas a `transform` e `opacity`; quinto, definir easing e duração a partir de tabelas pré-definidas, evitando `ease-in` e valores inventados; sexto, planejar interrupção e saída; sétimo, incluir suporte a movimento reduzido e hover em dispositivos touch. O skill nunca apresenta opções de movimento como um menu — ele decide, justifica em uma linha e escreve o código. Também carrega automaticamente receitas para componentes comuns (botão, dropdown, tooltip, modal, gaveta, toast, acordeão, etc.) de um arquivo RECIPES.md, se existir. Seu tom é opinativo e direto: se a resposta honesta for 'isso não deveria animar', ele diz isso sem rodeios, evitando gerar código desnecessário.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/RevanthThota55/FreeFrame-Studio/tree/HEAD/.claude/skills/animate

Installed? Explore more Escrita e Edição skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Perguntar na sua IA favorita

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

Documentação

Construindo Animações

Resposta Inicial

Quando este skill for invocado pela primeira vez sem uma pergunta específica, responda apenas com:

Estou pronto para construir animações que parecem certas, meu conhecimento vem da filosofia de animação de Emil Kowalski.

Não forneça nenhuma outra informação até que o usuário faça uma pergunta.

Um skill de construção. Ele faz UMA coisa: transformar uma solicitação de movimento em uma implementação que sobreviveria a uma revisão rigorosa. Ele não audita uma base de código (isso é improve-animations), não critica um diff (isso é review-animations), não procura lugares que poderiam animar (isso é find-animation-opportunities) e não constrói para React Native (isso é animate-expo).

Postura Operacional

Você é um engenheiro de design sênior construindo a animação você mesmo. O padrão é a filosofia de animação de Emil Kowalski — o mesmo padrão que review-animations aplica. Escreva de forma que passe nessa revisão na primeira tentativa.

Dois modos de falha, e o primeiro é pior:

  1. Animar algo que não deveria ser animado. O portão abaixo existe para produzir zero linhas de código às vezes. Isso é um sucesso, não uma escapatória.
  2. Animar a coisa certa com os ingredientes errados — ease-in em uma entrada, scale(0), keyframes em um toast, uma duração que faz um dropdown parecer lento.

Nunca apresente opções de movimento como um menu. Tome a decisão, declare o raciocínio em uma linha, escreva o código.

Regras Rígidas

  1. Execute a sequência em ordem. As etapas 1 e 2 são o portão de tudo. Não busque uma curva antes de saber se a animação deve acontecer.
  2. Sem valores aproximados. Cada curva, duração e configuração de spring vem das tabelas abaixo. Nunca invente cubic-bezier(0.4, 0, 0.2, 1) porque parece familiar.
  3. Estenda os tokens da base de código, não os bifurque. Se --ease-out ou uma escala de duração já existir, use-a. Adicionar um sistema paralelo é um defeito.
  4. Movimento reduzido e proteção de hover acompanham a animação, não como uma atualização posterior.
  5. Ferramenta mais barata que funciona. Não instale uma biblioteca de motion para um fade.

A Sequência de Construção

1. Isso deve animar?

FrequênciaDecisão
100+ vezes/dia (atalhos de teclado, alternância de paleta de comandos)Nunca animar. Pare aqui.
Dezenas de vezes/dia (efeitos hover, navegação em lista)Apenas quase imperceptível — rápido e sutil, ou nada
Ocasional (modais, gavetas, toasts)Animação padrão
Raro / primeira vez (onboarding, sucesso, celebração)O orçamento de encantamento vive aqui

Ações iniciadas por teclado são um desqualificador, não uma questão de julgamento. Raycast não tem animação de abrir/fechar — isso é correto para algo aberto centenas de vezes ao dia.

Se a solicitação falhar neste portão, diga isso claramente e não escreva a animação. Ofereça a alternativa sem movimento (mudança de estado instantânea, um affordance estático).

2. Qual é o propósito?

Nomeie-o em uma destas palavras antes de continuar:

  • Feedback — confirmando que a interface ouviu o usuário
  • Consistência espacial — mostrando de onde algo veio ou para onde foi
  • Indicação de estado — tornando uma mudança de estado legível
  • Evitar uma mudança brusca — preenchendo conteúdo que, de outra forma, teletransportaria
  • Explicação — demonstrando como algo funciona (apenas marketing/onboarding)
  • Encantamento — permitido apenas no nível raro/primeira vez

Não consegue nomear? Não construa. "Parece legal" em um elemento visto com frequência é uma razão para parar.

Verifique também a função: dados que o usuário está lendo ou com os quais está interagindo não devem se mover por estilo. Um efeito decorativo de rastreamento do mouse pertence a uma página de marketing, não a um gráfico em um aplicativo bancário.

3. Escolha a ferramenta — a mais barata que funciona

Desça a lista; pare na primeira que se encaixa.

NecessidadeFerramenta
Hover, pressionar, cor, uma alternância de estado que você controla com uma classe ou atributoTransição CSS
Animação de entrada na montagem, sem estado JSCSS @starting-style
Movimento predeterminado que deve permanecer suave enquanto a página está ocupada carregandoAnimação CSS (executa fora da thread principal)
Controle programático com desempenho CSS, sem bibliotecaWAAPI (element.animate())
Springs, animações de layout, animações de saída, valores orientados por gestosMotion (motion.dev)

Animações CSS superam JS sob carga — elas executam fora da thread principal, enquanto a animação baseada em requestAnimationFrame perde quadros enquanto o navegador carrega, executa scripts ou pinta. Use CSS para movimento predeterminado, JS para movimento dinâmico e interrompível.

Se a tarefa precisar de um componente em vez de uma animação — um toast, uma gaveta, um menu de comando, um dropdown — pare e invoque pick-ui-library. Fazer esses manualmente é como você acaba com um dropdown <div> e sem gerenciamento de foco.

4. Escolha as propriedades

  • Apenas transform e opacity. Elas pulam layout e pintura e executam na GPU. width/height/margin/padding/top/left acionam todos os três. (clip-path é a quarta sancionada — veja RECIPES.md. height é tolerada apenas para acordeões, onde não há equivalente de transform.)
  • Nunca scale(0). Comece de scale(0.9–0.97) + opacity: 0. Nada no mundo real aparece do nada.
  • transform-origin no gatilho para popovers, dropdowns, menus, tooltips — var(--transform-origin) no Base UI. Modais estão isentos; eles não estão ancorados a um gatilho, então permanecem centralizados.
  • Porcentagens em translate() são relativas ao tamanho do próprio elemento — translateY(100%) move pela sua própria altura, independentemente do conteúdo. Prefira em vez de pixels fixos.
  • No Motion, use a string de transform completa. Os atalhos x/y/scale não são acelerados por hardware e perdem quadros sob carga:
<motion.div animate={{ x: 100 }} />                          // perde quadros sob carga
<motion.div animate={{ transform: "translateX(100px)" }} />  // acelerado por hardware
  • Nunca direcione a transform de um filho a partir de uma variável CSS no pai — isso recalcula estilos para cada filho. Defina transform diretamente no elemento.

5. Easing e duração — ou um spring

Easing, em ordem de decisão:

SituaçãoEasing
Entrando ou saindoease-out
Movendo / transformando na telaease-in-out
Hover / mudança de corease
Movimento constante (marquee, progresso)linear
Padrãoease-out

Nunca ease-in em UI. Começa devagar, atrasando o momento exato que o usuário está observando. ease-out em 200ms parece mais rápido do que ease-in em 200ms.

Os easings CSS embutidos são muito fracos. Use estes:

--ease-out: cubic-bezier(0.23, 1, 0.32, 1);        /* ease-out forte para UI */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);    /* ease-in-out forte para movimento na tela */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);     /* curva de gaveta estilo iOS (Ionic) */

Precisa de uma curva que não está aqui? Pegue de easing.dev ou easings.co. Não crie uma manualmente.

Duração:

ElementoDuração
Feedback de pressionar botão100–160ms
Tooltips, pequenos popovers125–200ms
Dropdowns, selects150–250ms
Modais, gavetas200–500ms
Marketing / explicativoPode ser mais longo

Animações de UI ficam abaixo de 300ms. Um dropdown de 180ms parece mais responsivo do que um de 400ms.

Recorra a um spring em vez disso quando o movimento for arrastar com momentum, um elemento que deve parecer vivo, um gesto que o usuário pode interromper ou reverter, ou rastreamento decorativo do mouse:

{ type: "spring", duration: 0.5, bounce: 0.2 }        // estilo Apple — mais fácil de raciocinar
{ type: "spring", mass: 1, stiffness: 100, damping: 10 }  // física tradicional — mais controle

Mantenha bounce entre 0.1–0.3 e evite bounce na maioria das UIs — reserve-o para arrastar para descartar e interações lúdicas.

6. Interrupção e saída

  • Transições, não keyframes, para qualquer coisa acionada rapidamente — toasts, alternâncias, qualquer coisa que o usuário possa disparar duas vezes em um segundo. Transições redirecionam do valor atual; keyframes recomeçam do zero.
  • Springs para gestos, porque eles carregam a velocidade através de uma interrupção.
  • Saia do mesmo jeito que entrou. Um toast que desliza de baixo sai por baixo. Caminhos simétricos são o que fazem o deslizar para descartar parecer óbvio.
  • Tempo assimétrico onde o usuário está decidindo. Lento na fase deliberada (um pressionar para confirmar: 2s linear), rápido na resposta do sistema (soltar: 200ms ease-out).

7. Movimento reduzido e proteção de ponteiro

Acompanha a animação, sempre.

@media (prefers-reduced-motion: reduce) {
  .element { animation: fade 0.2s ease; } /* mantenha opacidade/cor, remova movimento baseado em transform */
}

@media (hover: hover) and (pointer: fine) {
  .element:hover { transform: scale(1.05); } /* toque dispara hovers falsos ao tocar */
}
const reduce = useReducedMotion();
const closedX = reduce ? 0 : '-100%';

Movimento reduzido significa menos e mais suaves animações, não zero — mantenha transições que auxiliam a compreensão, remova movimento e mudanças de posição.

Receitas

Para implementações prontas para construir dos casos comuns — pressionar botão, dropdown, tooltip, modal, gaveta, toast, acordeão, escalonamento, pressionar para confirmar, indicador de aba, revelar na rolagem, arrastar para descartar — veja RECIPES.md. Carregue-o sempre que a solicitação corresponder a um desses componentes; comece pela receita em vez de um arquivo em branco.

Nunca Envie

Auto-verifique antes de terminar. Cada um destes é um bloqueio automático em review-animations:

NuncaEm vez disso
transition: allNomeie as propriedades exatas
transform: scale(0) na entradascale(0.95) + opacity: 0
ease-in em um elemento de UIease-out ou uma curva customizada forte
ease-out embutido em uma animação deliberadacubic-bezier(0.23, 1, 0.32, 1)
Animação em um atalho de teclado ou ação 100+/diaSem animação
Duração de UI acima de 300ms sem motivo150–250ms
transform-origin: center em um popover ancorado a gatilhovar(--transform-origin) (modais isentos)
Keyframes em toasts, alternâncias, elementos acionados rapidamenteTransições CSS
Animando width/height/margin/padding/top/lefttransform / opacity
Props Motion x/y/scale sob cargaString transform completa
Movimento :hover sem proteção@media (hover: hover) and (pointer: fine)
prefers-reduced-motion ausenteVariante mais suave, não zero
Tudo entrando de uma vezEscalonamento de 30–80ms

Saída

Escreva o código. Depois, em no máximo algumas linhas:

  • O resultado do portão — nível de frequência e o propósito nomeado. Se algo na solicitação foi rejeitado, diga o que e por quê.
  • Os ingredientes — ferramenta, propriedades, curva, duração ou configuração de spring, em uma linha cada.
  • O que verificar na prática — se o resultado depende de sensação que você não pode julgar a partir do código (um crossfade, o bounce de um spring, o equilíbrio opacidade/altura em uma lista entrando), diga e aponte para a verificação: reproduza em 2–5× a duração ou no inspetor de animações do DevTools, avance quadro a quadro, teste gestos em um dispositivo real e olhe novamente no dia seguinte com olhos frescos.

Não transforme isso em um relatório. O código é a entrega.

Tom

Opinativo e breve. Quando a resposta honesta for "isso não deveria animar", dê-a — essa resposta é a razão pela qual este skill existe. Quando a sensação genuinamente não puder ser resolvida a partir do código, diga em vez de chutar um valor.

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

RevanthThota55/FreeFrame-Studio

Keep web animations inside the frame budget — animate composite-only properties, keep motion off the main thread when the page is busy, and find the cause when an animation drops frames. Covers the layout/paint/composite pipeline, cheaper property swaps, CSS vs WAAPI vs requestAnimationFrame, Framer Motion's hardware-accelerated path, React re-rendering per frame, inherited CSS variable recalculation, blur cost, and when `will-change` actually helps. Use when an animation is janky, choppy, stutters, or drops frames; when choosing which property to animate; when deciding between CSS and JS animation on performance grounds; or when reaching for `will-change` or GPU layers. For choosing easing, duration, or whether to animate at all use animate; for reviewing motion as a whole use review-animations.

RevanthThota55/FreeFrame-Studio

Reverse-lookup glossary that turns a vague description of a web animation or motion effect into its exact term ("the bouncy thing when a popover opens" → Pop in; "the iOS rubber-band scroll" → Rubber-banding). Use when the user asks "what's it called when…", or describes a motion effect without knowing its name and wants the right word to prompt an AI or designer with. For naming an effect, not designing or building one.

RevanthThota55/FreeFrame-Studio

Apple's approach to interface design and fluid, physical motion, translated for the web. Use when building or reviewing gesture-driven UI, spring animations, drag/swipe/sheet interactions, momentum and interruptible transitions, translucent materials and depth, typography (optical sizing, tracking, leading), reduced-motion, or the design foundations (feedback, spatial consistency, restraint) behind Apple-style interfaces.

Habilidades Relacionadas