Communitygithub.com

FunwayHQ/quar-design

Projete e anime cenas 2D no Quar Animator através de seu servidor MCP (as ferramentas quar-animator — list_projects, get_scene_context, apply_edit_batch, render_frame, render_preview, export…). Use quando o usuário quiser algo projetado, desenhado, animado, rigado ou exportado no Quar Animator — uma animação de logotipo, um cartão de título, um banner em loop, tipografia cinética, um ciclo de caminhada de personagem, uma microinteração de UI para Lottie, slides — ou quiser um projeto Quar existente melhorado.

O que é quar-design?

Este skill capacita um agente AI a atuar como um designer de movimento 2D completo usando o editor de animação vetorial Quar Animator através de seu servidor MCP. O agente pode criar, ler, editar e animar projetos em nuvem, seguindo um fluxo de trabalho iterativo: planejar, construir, visualizar resultados, corrigir e exportar. As ferramentas suportam manipulação de nós vetoriais (retângulos, elipses, textos, imagens, vídeos), animação de propriedades (posição, escala, rotação, opacidade, preenchimento), trabalho com ossos e malhas, e exportação para formatos como Lottie, MP4, WebM, GIF e PNG. O skill se destaca por seu loop rigoroso: cada lote de edições é executado primeiro como 'dry run' (simulação) para inspecionar o layout e as animações antes de confirmar a alteração, usando imagens de visualização para validação visual. O agente deve seguir melhores práticas de design (alinhamento, contraste, hierarquia) e verificar a qualidade da animação (timing, overlap, suavidade) antes de exportar. É compatível com Claude Code, Cursor, Codex e outras plataformas que suportam o protocolo MCP.

Funciona com~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/FunwayHQ/quar-animator-skills/tree/main/plugins/quar-design/skills/quar-design

Perguntar na sua IA favorita

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

Documentação

Projetando e Animando no Quar Animator

O Quar Animator é um editor de animação vetorial 2D; suas ferramentas MCP leem e editam os projetos em nuvem do usuário. Você trabalha como um designer de movimento que pode ver seu trabalho: planeje, construa, olhe, corrija, anime, olhe o movimento, exporte. Cada olhada é uma imagem do servidor — confie nela acima do que você pretendia fazer.

Se as ferramentas quar-animator não estiverem disponíveis, diga isso e aponte o usuário para a configuração no README deste skill (conecte o MCP em https://api.animator.quar.pro/mcp); não improvise outra maneira de fazer o arquivo.

O ciclo

  1. Leia. list_projects (ou create_project {nome} para um começo novo — dê ao usuário seu editorUrl, que o abre no editor deles; um marcado como stillUploading ainda não tem versão, seus vídeos ainda estão sendo enviados do editor: nada para abrir até que tenha), depois get_scene_context {project_id}. Observe o seq — passe-o como base_seq para cada edição, para que uma edição falhe em vez de aterrissar em alterações que você não viu. Observe frameRate, duration, artboardTimelines e o que está bloqueado (do usuário: deixe em paz a menos que seja solicitado).
  2. Planeje antes de tocar em qualquer coisa: o quadro (tamanho do artboard), o layout, a paleta, o tipo, o que se move e quando. Escreva o plano em algumas linhas para o usuário. Use reference/design.md e reference/motion.md; para um tipo conhecido de peça, siga sua receita em recipes/.
  3. Construa com uma simulação. Um apply_edit_batch para uma etapa coerente (o fundo, o layout, o tipo…) com dry_run: true. Isso não salva nada e retorna o que mudaria, placed — o at e bounds de cada nó adicionado ou alterado no resultado hipotético, para medir um layout antes de salvá-lo — e uma imagem (preview_frame; preview_node para mostrar um artboard ou nó; preview_size até 1024). Dê ao add_node seus próprios ids ("id": "title") para que operações posteriores no lote possam se referir a eles.
  4. Olhe e corrija. Julgue a imagem de acordo com a lista de verificação em reference/design.md: alinhamento, espaçamento, hierarquia, contraste, nada cortado. Corrija o lote e simule novamente até que esteja correto. Em seguida, envie-o sem dry_run, com uma message ("Layout: título, subtítulo e logotipo").
  5. Anime da mesma forma: operações animate (uma por propriedade, a curva inteira de uma vez) em um lote, simule com preview_frame em um momento revelador, depois confirme.
  6. Olhe o movimento. render_preview com count: 8–12 (distribuído ao longo da linha do tempo do que desenha — a de um artboard) ou os frames exatos onde as coisas acontecem (no máximo 16) fornece uma folha de contato legendada (com count, sua última célula é o quadro N, que as exportações não reproduzem). Verifique temporização, sobreposição, pausas, se nada pula, e para loops se o último quadro corresponde ao primeiro. Corrija com animate, move_keyframes, set_easing.
  7. Exporte quando solicitado (export, depois get_export {export_id, wait: true}), e leia seus detalhes: o que o Lottie não conseguiu transferir (unsupported: tipos de nó, camadas com efeitos, modos de mesclagem), os quadros, o tamanho. Dê ao usuário o link imediatamente — ele funciona uma vez, dentro de uma hora; get_export novamente fornece um novo.
  8. Diga ao usuário o que você fez, em algumas linhas, e que cada etapa é uma versão que eles podem desfazer (list_versions, restore_version).

Mantenha os lotes com propósito: uma versão por etapa significativa (não uma por forma, nem a peça inteira em uma só tentativa cega). Um lote aceita até 500 operações e é tudo-ou-nada.

As chamadas

Os argumentos ficam lado a lado — nunca aninhados em um objeto options.

create_project      {name}
get_scene_context   {project_id, page?, node?, depth?}
get_node            {project_id, node, page?}          (todas as propriedades armazenadas, seus keyframes)
get_timeline        {project_id, page?, node?, property?} (cada keyframe, com sua easing; de uma propriedade)
get_animatable_properties {node_type}                  (o que um tipo pode animar: ossos aceitam x, y também)
list_fonts          {}                                 (as famílias em que o texto pode ser desenhado, e seus pesos)
measure_text        {text, font_family?, font_weight?, font_size?, letter_spacing?, line_height?, box_width?}
                                                       (o x e advance de cada glifo, larguras das linhas, ascent, descent)
apply_edit_batch    {project_id, ops: [...], base_seq?, message?, dry_run?, preview_frame?,
                     preview_page?, preview_node?, preview_size?}
render_frame        {project_id, frame?, node?, page?, size?, transparent?}
render_preview      {project_id, frames? | count?, node?, page?, size?, transparent?}
capture_canvas      {project_id, frame?, page?}        (o editor aberto do usuário desenha; a versão salva se não responder)
export              {project_id, format, node?, frame?, start_frame?, end_frame?, fps?, width?, height?}
get_export          {export_id, wait?, include_file?}
list_versions       {project_id}
restore_version     {project_id, seq}

Uma op é {"op": <nome>, …seus argumentos}; cada op aceita sua própria page opcional (não há page no próprio lote). As ops são os nomes das ferramentas de edição: add_node, update_node, set_style, delete_node, duplicate_node, group_nodes, mask_nodes, ungroup_node, reorder_node, set_pivot, convert_to_outlines, add_keyframe, animate, remove_keyframe, move_keyframes, set_easing, clear_animation, add_page, delete_page, rename_page, duplicate_page, set_document, set_artboard_duration, add_bone, pose_bone, set_ik_target, bind_mesh (no máximo 20 operações bind_mesh e 60 camadas em um lote: vincule várias formas em uma), unbind_mesh, set_video_clip (abaixo). get_bindings lê quais ossos cada camada vinculada segue; uma camada vinculada pode ser excluída (sua vinculação vai junto). Onde um nome é compartilhado (uma forma e um osso ambos "Coxa E"), use o id.

[
  { "op": "add_node", "type": "rectangle", "id": "card", "parent": "frame", "x": 0, "y": 0,
    "width": 640, "height": 360, "cornerRadius": 24, "fill": "#1f1d29" },
  { "op": "set_style", "node": "card",
    "effects": [{ "type": "drop-shadow", "color": "#07060b", "offsetY": -16, "blur": 40, "opacity": 0.4 }] },
  { "op": "animate", "node": "card", "property": "y",
    "keyframes": [{ "frame": 0, "value": -120 }, { "frame": 18, "value": 0, "easing": "easeOutCubic" }] },
  { "op": "animate", "node": "card", "property": "scale",
    "keyframes": [{ "frame": 0, "value": { "x": 0.9, "y": 0.9 } }, { "frame": 18, "value": { "x": 1, "y": 1 } }] },
  { "op": "animate", "node": "card", "property": "fill",
    "keyframes": [{ "frame": 0, "value": "#1f1d29" }, { "frame": 18, "value": "#a855f7" }] }
]

Valores: números para x, y, rotation, opacity, tamanhos; {x, y} para position e scale; "#rrggbb" para fill e stroke. Efeitos: drop-shadow e inner-shadow aceitam color, offsetX, offsetY, blur, spread, opacity; layer-blur aceita radius.

Fatos que pegam as pessoas

  • Y aponta para cima. O x, y de um nó é sua âncora — o centro para a maioria das formas, incluindo artboards. Um y maior fica mais alto na tela. (os dados do caminho svg são a exceção: Y para baixo, como em arquivos SVG, no próprio espaço do nó ao redor de seu centro.)
  • Dois espaços. at e bounds (em get_scene_context e no placed de uma simulação) são coordenadas da página; o x, y de um nó — e os keyframes neles — estão no espaço de seu pai. Dentro de um artboard ou grupo que não está no centro da página, os dois diferem: chaveie ao redor do próprio x/y do nó (get_node), não seu at.
  • Os filhos são desenhados de trás para frente: irmãos posteriores estão na frente. Adicione o fundo primeiro e a forma focal por último, ou reordene com reorder_node {node, to: "front"|"back"|…, index?}.
  • Um artboard é branco a menos que receba um preenchimento: "fill": "none" para um transparente (um Lottie de aplicativo, um adesivo).
  • Pivôs. Escala e rotação ocorrem em torno da posição de um nó, seu pivô — o centro para a maioria das formas. Para pivotar em outro lugar — um membro em sua articulação, um logotipo comprimindo no chão, uma palavra crescendo para a direita — set_pivot {node, at: "bottom"} (um lugar em sua própria caixa: left, top-right…) ou {node, x, y} (um ponto na página); ele permanece onde está na tela. Grupos, retângulos e imagens aceitam um pivô; coloque qualquer outra coisa em um grupo primeiro (group_nodes {nodes: [ele], id} — seu grupo fica na origem de seu pai até ser pivotado), depois pivote o grupo. Defina pivôs antes de animar rotação ou escala: giros animados ocorrem em torno do pivô. (update_node não pode alterar um pai: reorder_node {node, parent} move um nó para dentro, mantendo-o no lugar.)
  • Máscaras. mask_nodes {nodes, mask?, mode?} coloca os nós e uma máscara (uma forma, texto ou imagem; o mais à frente dos nós quando não nomeado) em um grupo que os mostra apenas dentro dela — revelações, vinhetas, uma imagem em um quadro, algo indo atrás de uma borda. A máscara não é desenhada; anime-a (seu tamanho, posição, escala) para revelar. mode: clip (seu contorno), alpha (sua opacidade: um degradê de transparência), luminance (branco mostra, preto esconde).
  • rotation é em graus anti-horário, interpolado como escrito: 0 → 360 é uma volta inteira; −360 gira no sentido horário.
  • Gradientes: angle 0° corre da esquerda → direita, 90° de baixo → cima (270° de cima → baixo).
  • Sombras: offsetY negativo coloca uma sombra abaixo.
  • letterSpacing é em pixels (−2 a 100 px é tipo de exibição apertado).
  • Um caminho mantém seu próprio centro como sua posição: chaveie x/y ao redor de seu valor atual (leia-o com at de get_scene_context), nunca ao redor de 0.
  • Texto e fontes. O texto é desenhado, disposto e medido em sua própria família quando é Inter (sempre presente: todos os pesos de 100 a 900, itálico em 400 e 700) ou uma das Google Fonts do editor (list_fonts: famílias e seus pesos — apenas upright; um peso ausente assume o mais próximo). O servidor busca uma Google Font na primeira vez que um documento a usa. Sua largura é exata (avanços, kerning, espaçamento entre letras); sua altura é a caixa da linha (linhas × tamanho × lineHeight). Uma família não na lista é desenhada e medida em Inter, e as respostas dizem isso (fonts): escolha da lista, ou verifique a própria fonte do usuário com capture_canvas enquanto o projeto estiver aberto no editor deles. measure_text define o texto sem colocá-lo: o x e advance de cada glifo, a largura de cada linha, a ascent e descent da fonte — para cursores, sublinhados e encaixar uma palavra em uma largura. convert_to_outlines {node} transforma texto em um grupo de caminhos de letras (<id>-1…, nomeados por sua letra) para animação letra por letra: escalone-as, recolorize uma, faça uma saltar. Unidirecional.
  • Linhas do tempo. duration e frameRate são do documento. Cada artboard no topo de uma página reproduz sua própria linha do tempo — os keyframes de suas camadas, em seu próprio comprimento (artboardTimelines; set_artboard_duration {artboard, duration}; a do documento até que tenha uma). Uma linha do tempo de N quadros aceita keyframes em 0…N; exportações e slides reproduzem quadros 0…N−1, então, para um loop, o quadro N deve ser igual ao quadro 0. Alongue uma linha do tempo antes de chavear após seu fim (set_document {duration} para a página).
  • Slides. Nas apresentações e exportações de vídeo do editor, e em exportações GIF e sequência PNG de uma página com vários artboards (sem node, sem intervalo), os artboards reproduzem um após o outro — o mais à frente primeiro (o topo do painel Camadas), cada um por seu próprio comprimento, encaixado no tamanho do primeiro. Um artboard adicionado depois está na frente, então reproduziria primeiro: adicione slides posteriores com index: 0, ou reorder_node eles. artboardTimelines os lista na ordem em que reproduzem. Exporte um artboard com node. MP4 e WebM vêm do editor (Arquivo › Exportar), não do MCP.
  • easing é a curva para dentro de um keyframe a partir do anterior. Os nomes estão em reference/motion.md; [x1, y1, x2, y2] fornece uma Bézier cúbica. Uma easing com overshoot (easeOutBack) em um keyframe que já é o overshoot overshoota duas vezes: use easeOutCubic para o pico e a easing elástica para o assentamento.
  • Vídeos. Uma camada de vídeo ("type": "video": um MP4, MOV ou WebM, ou um GIF animado que o usuário importou) é uma imagem que é reproduzida enquanto seu clipe o faz, e não mostra nada fora dele a menos que segure. get_scene_context fornece seu video: o file, gif, seu length (segundos), e seu clip — start (o quadro em que começa), end (o quadro em que para), offset (segundos cortados do início do vídeo), duration (segundos do vídeo que uma passagem reproduz), speed, loop e loopFor (segundos que ele repete), hold (sua última imagem permanece após seu fim) — e seu sound vinculado (um clipe na linha do tempo que se move com ele). Altere o clipe com set_video_clip {node, moveTo?, trimStart?, trimEnd?, speed?, loop?, hold?, stopAt?, unlinkSound?} — quadros da linha do tempo em que a camada reproduz, aplicados na ordem loop, speed, moveTo, trimStart, trimEnd, hold, stopAt:
    • moveTo o inicia em um quadro; trimStart faz um quadro ser seu primeiro, seu fim permanecendo no lugar (mais tarde corta o início do vídeo, mais cedo reproduz mais dele); trimEnd faz com que pare em um quadro (mais cedo corta o fim; mais tarde reproduz mais, até o fim do vídeo — ou, com loop, repete até então: {loop: true, trimEnd: 300} preenche um slide de 10 segundos).
    • speed 0.25–4 (o som mantém seu tom); hold: true mantém a última imagem; stopAt termina em um quadro, segurando o que mostra lá (um GIF congelado no meio); loop: false em um GIF também o segura.
    • Seu som segue cada alteração, e a linha do tempo em que reproduz é alongada para reproduzi-lo até seu fim (o resultado diz timelineLengthened). unlinkSound: true torna o som independente. Caso contrário, uma camada de vídeo é uma imagem: mova, dimensione (width, height), arredonde (cornerRadius), desbote, adjustments, efeitos, modos de mesclagem, máscaras (também pode mascarar), pivôs e keyframes como para uma imagem — mas sem puxar cantos e sem ossos. duplicate_node copia seu som junto; delete_node exclui seu som.

…

[truncado para tradução]

Habilidades Relacionadas