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
- Leia.
list_projects(oucreate_project {nome}para um começo novo — dê ao usuário seueditorUrl, que o abre no editor deles; um marcado comostillUploadingainda não tem versão, seus vídeos ainda estão sendo enviados do editor: nada para abrir até que tenha), depoisget_scene_context {project_id}. Observe oseq— passe-o comobase_seqpara cada edição, para que uma edição falhe em vez de aterrissar em alterações que você não viu. ObserveframeRate,duration,artboardTimelinese o que está bloqueado (do usuário: deixe em paz a menos que seja solicitado). - 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.mdereference/motion.md; para um tipo conhecido de peça, siga sua receita emrecipes/. - Construa com uma simulação. Um
apply_edit_batchpara uma etapa coerente (o fundo, o layout, o tipo…) comdry_run: true. Isso não salva nada e retorna o que mudaria,placed— oateboundsde cada nó adicionado ou alterado no resultado hipotético, para medir um layout antes de salvá-lo — e uma imagem (preview_frame;preview_nodepara mostrar um artboard ou nó;preview_sizeaté 1024). Dê aoadd_nodeseus próprios ids ("id": "title") para que operações posteriores no lote possam se referir a eles. - 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 semdry_run, com umamessage("Layout: título, subtítulo e logotipo"). - Anime da mesma forma: operações
animate(uma por propriedade, a curva inteira de uma vez) em um lote, simule compreview_frameem um momento revelador, depois confirme. - Olhe o movimento.
render_previewcomcount: 8–12(distribuído ao longo da linha do tempo do que desenha — a de um artboard) ou osframesexatos onde as coisas acontecem (no máximo 16) fornece uma folha de contato legendada (comcount, 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 comanimate,move_keyframes,set_easing. - Exporte quando solicitado (
export, depoisget_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_exportnovamente fornece um novo. - 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,yde um nó é sua âncora — o centro para a maioria das formas, incluindo artboards. Um y maior fica mais alto na tela. (os dados do caminhosvgsã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.
atebounds(emget_scene_contexte noplacedde uma simulação) são coordenadas da página; ox,yde 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ópriox/ydo nó (get_node), não seuat. - 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_nodenã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:
angle0° corre da esquerda → direita, 90° de baixo → cima (270° de cima → baixo). - Sombras:
offsetYnegativo 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/yao redor de seu valor atual (leia-o comatdeget_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 comcapture_canvasenquanto o projeto estiver aberto no editor deles.measure_textdefine o texto sem colocá-lo: oxeadvancede 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.
durationeframeRatesã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 comindex: 0, oureorder_nodeeles.artboardTimelinesos lista na ordem em que reproduzem. Exporte um artboard comnode. 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 emreference/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: useeaseOutCubicpara 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_contextfornece seuvideo: ofile,gif, seulength(segundos), e seuclip—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,loopeloopFor(segundos que ele repete),hold(sua última imagem permanece após seu fim) — e seusoundvinculado (um clipe na linha do tempo que se move com ele). Altere o clipe comset_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:moveToo inicia em um quadro;trimStartfaz um quadro ser seu primeiro, seu fim permanecendo no lugar (mais tarde corta o início do vídeo, mais cedo reproduz mais dele);trimEndfaz com que pare em um quadro (mais cedo corta o fim; mais tarde reproduz mais, até o fim do vídeo — ou, comloop, repete até então:{loop: true, trimEnd: 300}preenche um slide de 10 segundos).speed0.25–4 (o som mantém seu tom);hold: truemantém a última imagem;stopAttermina em um quadro, segurando o que mostra lá (um GIF congelado no meio);loop: falseem 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: truetorna 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_nodecopia seu som junto;delete_nodeexclui seu som.
…
[truncado para tradução]