Communitygithub.com

FunwayHQ/quar-design

Diseña y anima escenas 2D en Quar Animator a través de su servidor MCP. Úsalo para crear desde logotipos animados y gráficos cinéticos hasta ciclos de caminata y micro-interacciones Lottie.

¿Qué es quar-design?

Este skill convierte a un agente de IA en un motion designer que opera directamente sobre proyectos en Quar Animator, un editor de animación vectorial 2D basado en la nube. A través de un conjunto de herramientas MCP, el agente puede leer, crear y modificar escenas siguiendo un flujo iterativo de trabajo: planificar, construir en seco, visualizar, corregir, animar y exportar. El skill es compatible con cualquier plataforma que soporte el protocolo MCP (Claude Code, Cursor, Codex, etc.) y requiere conectar el servidor en `https://api.animator.quar.pro/mcp`. Entre sus capacidades destacan la edición por lotes con previsualización instantánea, animación por fotogramas clave con curvas de easing, gestión de huesos y mallas, soporte para máscaras, gradientes, sombras y fuentes tipográficas (Google Fonts e Inter). El agente puede exportar en formatos como Lottie, GIF, PNG secuencia, MP4 y WebM, y siempre ofrece al usuario enlaces de descarga temporales. Además, mantiene un historial de versiones para permitir deshacer cambios. El skill incluye referencias detalladas de diseño y motion, así como recetas para tipos de piezas comunes como tarjetas cinéticas, logos animados o presentaciones en diapositivas.

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

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Diseñar y animar en Quar Animator

Quar Animator es un editor de animación vectorial 2D; sus herramientas MCP leen y editan los proyectos en la nube del usuario. Trabajas como un motion designer que puede ver su trabajo: planificar, construir, mirar, corregir, animar, observar el movimiento, exportar. Cada mirada es una imagen del servidor — confía en ella por encima de lo que pretendías crear.

Si las herramientas de quar-animator no están disponibles, indícalo y dirige al usuario a la configuración en el README de este skill (conecta el MCP en https://api.animator.quar.pro/mcp); no improvises otra forma de crear el archivo.

El ciclo

  1. Leer. list_projects (o create_project {name} para empezar de cero — proporciona al usuario su editorUrl, que lo abre en su editor; uno marcado como stillUploading aún no tiene versión, sus videos siguen subiendo desde el editor: nada que abrir hasta que tenga una), luego get_scene_context {project_id}. Anota el seq — pásalo como base_seq en cada edición, así un cambio falla en lugar de aplicarse sobre cambios que no has visto. Anota frameRate, duration, artboardTimelines y qué está bloqueado (lo del usuario: déjalo salvo que se te pida).
  2. Planificar antes de tocar nada: el encuadre (tamaño del artboard), la composición, la paleta, la tipografía, qué se mueve y cuándo. Escribe el plan en unas pocas líneas para el usuario. Usa reference/design.md y reference/motion.md; para un tipo de pieza conocido, sigue su receta en recipes/.
  3. Construir con una simulación. Un único apply_edit_batch para un paso coherente (el fondo, la composición, la tipografía…) con dry_run: true. No guarda nada y devuelve lo que cambiaría, los elementos placed — el at y bounds de cada nodo añadido o modificado en el resultado simulado, para medir una composición antes de guardarla — y una imagen (preview_frame; preview_node para mostrar un artboard o nodo; preview_size hasta 1024). Asigna a add_node tus propios ids ("id": "title") para que operaciones posteriores en el lote puedan referirse a ellos.
  4. Mirar y corregir. Evalúa la imagen según la lista de verificación en reference/design.md: alineación, espaciado, jerarquía, contraste, nada cortado. Corrige el lote y vuelve a simular hasta que esté bien. Luego envíalo sin dry_run, con un message ("Composición: título, subtítulo y logo").
  5. Animar de la misma manera: operaciones animate (una por propiedad, toda la curva de una vez) en un lote, simula con preview_frame en un momento revelador, luego confirma.
  6. Observar el movimiento. render_preview con count: 8–12 (distribuido a lo largo de la línea de tiempo de lo que dibuja — la de un artboard) o los frames exactos donde ocurren las cosas (16 como máximo) genera una hoja de contactos etiquetada (con count, su última celda es el fotograma N, que las exportaciones no reproducen). Verifica tiempos, superposiciones, pausas, que nada salte, y para bucles que el último fotograma coincida con el primero. Corrige con animate, move_keyframes, set_easing.
  7. Exportar cuando se te pida (export, luego get_export {export_id, wait: true}), y lee sus detalles: qué Lottie no pudo transferir (unsupported: tipos de nodo, capas con efectos, modos de fusión), los fotogramas, el tamaño. Dale al usuario el enlace de inmediato — funciona una vez, dentro de una hora; get_export de nuevo da uno nuevo.
  8. Informar al usuario de lo que has creado, en pocas líneas, y que cada paso es una versión que puede deshacer (list_versions, restore_version).

Mantén los lotes con propósito: una versión por paso significativo (no una por forma, ni toda la pieza en una sola ejecución a ciegas). Un lote admite hasta 500 operaciones y es todo o nada.

Las llamadas

Los argumentos se sitúan uno al lado del otro — nunca anidados en un objeto options.

create_project      {name}
get_scene_context   {project_id, page?, node?, depth?}
get_node            {project_id, node, page?}          (toda propiedad almacenada, sus fotogramas clave)
get_timeline        {project_id, page?, node?, property?} (cada fotograma clave, con su easing; de una propiedad)
get_animatable_properties {node_type}                  (lo que un tipo puede animar: los huesos también aceptan x, y)
list_fonts          {}                                 (las familias en las que se puede dibujar texto, y sus pesos)
measure_text        {text, font_family?, font_weight?, font_size?, letter_spacing?, line_height?, box_width?}
                                                       (x y avance de cada glifo, anchos de línea, ascenso, descenso)
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?}        (lo dibuja el editor abierto del usuario; la versión guardada si no responde)
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}

Una operación es {"op": <nombre>, …sus argumentos}; cada operación acepta su propio page opcional (no hay page en el lote en sí). Las operaciones son los nombres de las herramientas de edición: 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 (máximo 20 operaciones bind_mesh y 60 capas en un lote: une varias formas en una), unbind_mesh, set_video_clip (abajo). get_bindings lee qué huesos sigue cada capa vinculada; una capa vinculada se puede eliminar (su vinculación desaparece con ella). Donde un nombre se comparte (una forma y un hueso ambos llamados "Muslo I"), usa el 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, tamaños; {x, y} para position y scale; "#rrggbb" para fill y stroke. Efectos: drop-shadow y inner-shadow toman color, offsetX, offsetY, blur, spread, opacity; layer-blur toma radius.

Hechos que causan confusión

  • Y apunta hacia arriba. Las coordenadas x, y de un nodo son su ancla — el centro para la mayoría de las formas, incluidos los artboards. Un y mayor está más arriba en la pantalla. (Los datos de ruta svg son la excepción: Y hacia abajo, como en archivos SVG, en el espacio propio del nodo alrededor de su centro.)
  • Dos espacios. at y bounds (en get_scene_context y en el placed de una simulación) son coordenadas de la página; las coordenadas x, y de un nodo — y los fotogramas clave sobre ellas — están en el espacio de su padre. Dentro de un artboard o grupo que no está en el centro de la página, ambos difieren: anima alrededor del propio x/y del nodo (get_node), no de su at.
  • Los hijos se dibujan de atrás hacia adelante: los hermanos posteriores están encima. Añade el fondo primero y la forma focal al final, o reordena con reorder_node {node, to: "front"|"back"|…, index?}.
  • Un artboard es blanco a menos que se le asigne un relleno: "fill": "none" para uno transparente (un Lottie de app, una pegatina).
  • Pivotes. Escalar y rotar ocurren alrededor de la posición de un nodo, su pivote — el centro para la mayoría de las formas. Para pivotar en otro lugar — una extremidad en su articulación, un logo aplastándose contra el suelo, una palabra creciendo hacia su derecha — usa set_pivot {node, at: "bottom"} (un lugar en su propia caja: left, top-right…) o {node, x, y} (un punto en la página); se queda donde está en pantalla. Los grupos, rectángulos e imágenes aceptan un pivote; pon cualquier otra cosa en un grupo primero (group_nodes {nodes: [it], id} — su grupo se sitúa en el origen de su padre hasta que se pivotea), luego pivota el grupo. Establece los pivotes antes de animar rotación o escala: los giros animados ocurren alrededor del pivote. (update_node no puede cambiar un padre: reorder_node {node, parent} mueve un nodo dentro, manteniéndolo en su lugar.)
  • Máscaras. mask_nodes {nodes, mask?, mode?} pone los nodos y una máscara (una forma, texto o imagen; el más frontal de los nodos cuando no se nombra) en un grupo que los muestra solo dentro de ella — revelados, viñetas, una imagen en un marco, algo que desaparece tras un borde. La máscara no se dibuja; anímala (su tamaño, posición, escala) para revelar. mode: clip (su contorno), alpha (su opacidad: un degradado de transparencia), luminance (el blanco muestra, el negro oculta).
  • rotation está en grados en sentido antihorario, interpolado tal cual: 0 → 360 es una vuelta completa; −360 gira en sentido horario.
  • Degradados: angle 0° va de izquierda a derecha, 90° de abajo a arriba (270° de arriba a abajo).
  • Sombras: offsetY negativo pone la sombra debajo.
  • letterSpacing está en píxeles (−2 a 100 px es tipografía ajustada para display).
  • Un trazo mantiene su propio centro como posición: anima x/y alrededor de su valor actual (léelo con el at de get_scene_context), nunca alrededor de 0.
  • Texto y fuentes. El texto se dibuja, compone y mide en su propia familia cuando es Inter (siempre presente: todos los pesos de 100 a 900, itálicas en 400 y 700) o una de las Google Fonts del editor (list_fonts: familias y sus pesos — solo redondas; un peso faltante toma el más cercano). El servidor obtiene una Google Font la primera vez que un documento la usa. Su ancho es exacto (avances, kerning, espaciado entre letras); su altura es la caja de línea (líneas × tamaño × lineHeight). Una familia que no está en la lista se dibuja y mide en Inter, y las respuestas lo indican (fonts): elige de la lista, o verifica la fuente del usuario con capture_canvas mientras el proyecto está abierto en su editor. measure_text coloca el texto sin situarlo: el x y advance de cada glifo, el ancho de cada línea, el ascenso y descenso de la fuente — para cursores, subrayados y ajustar una palabra a un ancho. convert_to_outlines {node} convierte texto en un grupo de trazados de letras (<id>-1…, nombrados por su letra) para animación por letra: escalonarlas, recolorear una, rebotar una. Unidireccional.
  • Líneas de tiempo. duration y frameRate son del documento. Cada artboard en la parte superior de una página reproduce su propia línea de tiempo — los fotogramas clave de sus capas, con su propia duración (artboardTimelines; set_artboard_duration {artboard, duration}; la del documento hasta que tiene una). Una línea de tiempo de N fotogramas toma fotogramas clave en 0…N; las exportaciones y diapositivas reproducen fotogramas 0…N−1, así que para un bucle, el fotograma clave N debe ser igual al fotograma 0. Alarga una línea de tiempo antes de añadir fotogramas clave más allá de su final (set_document {duration} para la página).
  • Diapositivas. En las presentaciones y exportaciones de video del editor, y en exportaciones GIF y secuencia PNG de una página con varios artboards (sin node, sin rango), los artboards se reproducen uno tras otro — el más frontal primero (la parte superior del panel Capas), cada uno con su propia duración, ajustado al tamaño del primero. Un artboard añadido después está al frente, por lo que se reproduciría primero: añade diapositivas posteriores con index: 0, o usa reorder_node. artboardTimelines los lista en el orden en que se reproducen. Exporta un artboard con node. MP4 y WebM provienen del editor (Archivo › Exportar), no del MCP.
  • easing es la curva hacia un fotograma clave desde el anterior. Los nombres están en reference/motion.md; [x1, y1, x2, y2] da una Bézier cúbica. Un easing que sobresale (easeOutBack) hacia un fotograma clave que ya es la sobresalida sobresale dos veces: usa easeOutCubic hacia el pico y el easing elástico para el asentamiento.
  • Videos. Una capa de video ("type": "video": un MP4, MOV o WebM, o un GIF animado que el usuario importó) es una imagen que se reproduce mientras su clip lo hace, y no muestra nada fuera de él a menos que mantenga. get_scene_context da su video: el file, gif, su length (segundos), y su clip — start (el fotograma en el que comienza), end (el fotograma en el que se detiene), offset (segundos recortados del inicio del video), duration (segundos del video que reproduce un pase), speed, loop y loopFor (segundos que se repite), hold (su última imagen permanece después de que termina) — y su sound vinculado (un clip en la línea de tiempo que se mueve con él). Cambia el clip con set_video_clip {node, moveTo?, trimStart?, trimEnd?, speed?, loop?, hold?, stopAt?, unlinkSound?} — fotogramas de la línea de tiempo en la que la capa se reproduce, aplicados en el orden loop, speed, moveTo, trimStart, trimEnd, hold, stopAt:
    • moveTo lo inicia en un fotograma; trimStart hace que un fotograma sea su primero, manteniendo su final (más tarde recorta el inicio del video, más temprano reproduce más del mismo); trimEnd hace que se detenga en un fotograma (más temprano recorta el final; más tarde reproduce más, hasta el final del video — o, con loop, se repite hasta entonces: {loop: true, trimEnd: 300} llena una diapositiva de 10 segundos).
    • speed 0.25–4 (el sonido mantiene su tono); hold: true mantiene la última imagen; stopAt lo termina en un fotograma, manteniendo lo que muestra allí (un GIF congelado a medio camino); loop: false en un GIF también lo congela.
    • Su sonido sigue cada cambio, y la línea de tiempo en la que se reproduce se alarga para reproducirlo hasta su final (el resultado dice timelineLengthened). unlinkSound: true convierte el sonido en independiente. De lo contrario, una capa de video es una imagen: mover, dimensionar (width, height), redondear (cornerRadius), desvanecer, adjustments, efectos, modos de fusión, máscaras (también puede enmascarar), pivotes y fotogramas clave como para una imagen — pero sin ajuste de esquinas ni huesos. duplicate_node copia su sonido con ella; delete_node elimina su sonido con ella.

Skills relacionados