Canvas de Pixerate
El canvas es un grafo xyflow (React Flow / SvelteFlow): un array de nodos y aristas.
Un nodo es { id, type, position: { x, y }, width?, height?, parentId?, zIndex?, data }; las aristas son
{ id, source, target, label? }. Todo lo que una característica de diseño conoce vive en node.data, por lo que
sobrevive a copiar, pegar y JSON:
data.label/data.name: contenido de texto y nombre de capa.data.shape: un nodo de forma ({ kind: rect | ellipse | polygon | star | path, fill, stroke, strokeWidth, ... }).data.layout: un marco de diseño automático (modehorizontal / vertical / cuadrícula,gap,padding,alignMain,alignCross,sizing); sus hijos son los nodos cuyoparentIdes el marco, en el orden del array de nodos.data.childLayout: el tamaño de un hijo (fijo / ajustable / relleno) y sus restricciones.data.component(un componente principal),data.componentSet(un conjunto de variantes),data.instance({ componentId, properties }) ydata.componentOverrides.data.locked,data.animation(pistas de fotogramas clave),data.tokenBindings(tokens de diseño).
Las posiciones están en unidades de canvas (flujo); la posición de un hijo es relativa a su padre. Los ids de los nodos
provienen de get_editor_state; los ids de componentes y conjuntos provienen de list_components. Las herramientas que toman ids o
id por defecto toman la selección actual si los omites, así que pasa ids explícitamente a menos que
acabes de seleccionar con canvas_select. Consulta pixerate-agent-tools para el espacio de nombres, el agrupamiento con run_commands
y los códigos de error.
Habilidades de flujo de trabajo
Para estos trabajos, carga también la habilidad de flujo de trabajo: contiene el método, las comprobaciones entre pasos y los errores comunes, y utiliza las herramientas siguientes.
pixerate-canvas-design-system-components: componentes, instancias, conjuntos de variantes y sobrescrituras.pixerate-canvas-layout: alinear, distribuir, ordenar y bloquear.
Método de trabajo
- Lee.
get_editor_stateconincludeDocument: falsedevuelvecanvas.nodesycanvas.edges. Para un sistema de diseño, llama también alist_components, y ainspect_instanceantes de cambiar una instancia. - Planifica primero la estructura: qué marcos, qué componentes reutilizables y variantes, qué escala de espaciado. Construye el componente principal una vez, luego coloca las instancias; no copies nodos manualmente.
- Escribe. Usa las herramientas específicas para ediciones del grafo (
canvas_add_node,canvas_connect,canvas_update_node) y componentes (create_component,create_instance, ...). Usarun_commandsconatomic: truepara comandos de disposición, forma y animación, y siempre que varios pasos deban ser un solo paso de deshacer (un parámetro"$0.ids[0]"usa un id que devolvió un paso anterior). - Ordena.
canvas_layoutpara grafos;canvas.align*/canvas.distribute*para diseños; orden de capas concanvas.bringToFronty similares; bloquea fondos terminados concanvas.lock. - Mira.
view_editor(viewport por defecto, JPEG, 1024 px) una vez que un lote esté terminado; usascope: "canvas"para todo el dibujo. Corrige solapamientos, desalineaciones y texto recortado, luego muestra al usuario concanvas_selectocanvas_highlight.
Trabajando junto al usuario (él está construyendo y tú añades sin que te lo pida): sugiere en lugar de
editar. propose_nodes muestra fantasmas que el usuario acepta o descarta, y nada llega al canvas
ni a su historial hasta entonces. Mantén cada propuesta pequeña y sobre una sola idea (un pie de foto, la siguiente tarjeta en
una serie, un conector faltante), dale un title y un rationale de una frase, y ancla la propuesta al
nodo que complementa con nearNodeId. Nunca aceptes tus propias propuestas a menos que el usuario te lo haya
pedido. Retira las obsoletas con reject_proposal: cuando el usuario cambia aquello sobre lo que se basa una propuesta,
list_proposals la muestra bajo missing.
Buenas prácticas
-
Pensamiento de sistema de diseño. Cualquier cosa que aparezca dos veces debería ser un componente: construye uno principal,
combine_as_variantspara estados y tamaños (State=Default,State=Hover,Size=Small), luegocreate_instanceen todas partes. Cambia el principal para cambiar cada instancia; usa sobrescrituras solo para contenido de uso por instancia (texto de etiqueta, un cambio de icono). Nombra las propiedades y valores de las variantes de forma coherente (propiedad en mayúscula inicial, valores cortos) y mantén las combinaciones únicas. -
Nombra las capas que deben sobrevivir a un cambio de variante con un
data.nameestable. La coincidencia recurre adata.label, que para texto es su contenido y difiere entre variantes. -
Usa propiedades de componente, no desvincular. Cambia variantes y establece propiedades de texto o booleanas con
set_instance_properties;swap_instancepara otro componente. Desvincula solo cuando la instancia deba dejar de seguir a su principal. -
Escala de espaciado. Elige una unidad base (4 u 8) y usa múltiplos para espacios y relleno. Coloca filas y pilas en marcos de diseño automático (
data.layout) en lugar de posicionar hijos manualmente, para que se reajusten cuando el contenido cambie. -
Alineación y distribución. Alinea respecto a un borde común o centro, luego distribuye con espacios iguales; un diseño se ve ordenado cuando los bordes están alineados. Bloquea un nodo que quieras como ancla: los nodos bloqueados nunca se mueven pero siguen contando para los límites de selección.
-
Capas. Fondos atrás, contenido encima, superposiciones arriba. Usa los comandos de reordenación; establecen
zIndexpor grupo de hermanos y nunca reordenan el array. -
Diseño de grafos. Distribuye los flujos en una dirección (
LRpara canalizaciones,TBpara jerarquías), mantén las aristas cortas, etiqueta las aristas solo cuando la relación no sea obvia. -
Movimiento. Usa ease-out (o
ease-out-backpara un pequeño rebasamiento) para elementos que llegan, ease-in para los que se van, ease-in-out para movimientos entre dos lugares de reposo, ylinearsolo para movimiento continuo como rotaciones. Mantén las transiciones de UI entre 150 y 400 ms y las entradas por debajo de unos 600 ms; escalona elementos relacionados entre 30 y 80 ms condelayen lugar de mover todo a la vez. Animaopacity,x,y,scaleyrotation; las interpolaciones de color se realizan en OKLab. -
Trazos con pincel. Usa un pincel cuando el usuario quiera un aspecto dibujado a mano (boceto, tinta, lápiz, rotulador); mantén trazos simples para diagramas y UI. Envía puntos cada 2 a 8 unidades de canvas a lo largo de una curva, y da forma a la línea con un perfil de
pressurecorto (extremos cónicos:[0.2, 0.9, 1, 0.9, 0.2]) en lugar de muchos puntos de diferentes grosores. Omitewidthpara usar el tamaño propio del preset (canvas.listBrusheslo da); pásalo solo para hacer la marca más fina o más gruesa. -
Carácter del pincel. Cada preset dibuja con su propio carácter: carboncillo y pastel son anchos y granulosos (atrapan el grano del papel), al igual que la tiza y la cera; el lápiz es fino y ligeramente granulado; tinta, rotulador, pincel, bolígrafo, gel y rotulador fino son limpios (el rotulador fino mantiene un solo grosor), el aerógrafo es una pulverización suave. El grano y la vibración se seedan por trazo, por lo que un trazo siempre se ve igual, y los trazos vecinos comparten una misma hoja de papel. Elige el pincel por el aspecto, luego el color; para un boceto, usa uno o dos pinceles en lugar de todos. Un pincel con un color por defecto (azul bolígrafo, amarillo rotulador, tiza) pinta en ese color cuando no pasas ningún
color; pasacolorpara usar otro. Los valores por defecto claro/oscuro (tiza) se resuelven según el esquema de color del canvas (canvas.setColorScheme; el host normalmente coincide con su tema). -
Configurando el bolígrafo para la persona, no dibujando.
canvas.selectBrushelige el pincel que la persona usa para dibujar manualmente, como lo haría el selector de pinceles: toma el color por defecto del pincel a menos que la persona haya bloqueado el suyo (canvas.setColorLocked, "Mantener mi color") o paseskeepColour. Un valor por defecto tomado así sigue el esquema hasta que se establezca otro color. Respeta un bloqueo que la persona haya establecido; no lo desbloquees para cambiar su color. Estos son estado del editor, no pasos de deshacer, y no afectan acanvas.drawFreehand, que toma su propiobrushycolor. -
Anota con gestos, no con puntos. Para marcar trabajo como un diseñador marca una impresión, usa los comandos gestuales (
canvas.circle,canvas.underline,canvas.arrow,canvas.bracket,canvas.strike,canvas.cross,canvas.check) con ids de nodos ({ "nodeId": "..." }) o cuadros, en lugar de calcular puntos paracanvas.drawFreehand. Una llamada dibuja una marca dibujada a mano. Una anotación ayuda cuando estás señalando algo en el canvas mientras hablas de ello: rodea lo seleccionado, subraya la línea que importa, dibuja una flecha desde una muestra hasta donde se usa, encierra entre corchetes un grupo que estás describiendo, tacha o cruza una opción rechazada, marca una aprobada. Omítelo cuando no se haga referencia a nada en el canvas y mantenlo en unas pocas marcas por punto: una página cubierta de marcas no dice nada. -
Estilo de gesto. Usa un color para una pasada de revisión (un bolígrafo rojo o azul fuerte se lee como marcado sobre la mayoría de los diseños), el rotulador solo para círculos y subrayados, y el mismo
brush(markeroink-pen) para cada marca de una pasada si quieres que parezcan dibujadas a mano. Las marcas se seedan por su petición, así que pedir de nuevo dibuja la misma marca; pasa otroseedpara una versión diferente. Pon una nota al margen (un nodo de texto) junto a un corchete o en la cola de una flecha cuando la marca necesite palabras.
Referencia de herramientas
Lectura
| Herramienta | Úsala para |
|---|---|
get_editor_state | Leer el grafo del canvas (canvas.nodes, canvas.edges) y, por defecto, también el documento de la indicación. Pasa includeDocument: false en una tarea solo de canvas para mantener el resultado pequeño, includeCanvas: false solo para la indicación. Llámala primero y de nuevo después de ediciones hechas por el usuario. |
view_editor | Obtener una imagen del editor: scope viewport (por defecto) o canvas (los límites de todo el dibujo), format jpeg (por defecto) o png, maxEdge en píxeles (por defecto 1024). Úsala después de un lote para juzgar solapamiento, equilibrio y legibilidad; los cursores del agente se omiten. |
capture_view | Capturar parte del canvas para comprobar un resultado: region viewport (por defecto, como en pantalla), content (todos los nodos), selection, nodes (con ids de get_editor_state) o rect (unidades de canvas); padding (por defecto 16), maxEdge (por defecto 1024), format png (por defecto) o jpeg. El resultado da el rect y la scale capturados, por lo que el píxel de la imagen (px, py) es el punto del canvas (rect.x + px / scale, rect.y + py / scale). Prefiere nodes para inspeccionar lo que acabas de añadir con todo detalle. Los cuadros de selección y los cursores del agente se omiten a menos que uses includeOverlays. |
list_components | Listar componentes principales (id, nombre, valores de variante, número de instancias) y conjuntos de componentes con sus opciones de variante. Llámala antes de create_instance, swap_instance o cualquier herramienta de variante para obtener ids y los nombres y valores exactos de las propiedades. |
inspect_instance | Describir una instancia (o una capa dentro de ella; por defecto el primer nodo seleccionado): su componente principal, variante, valores de propiedades del componente con tipos y sobrescrituras por capa. Llámala antes de set_instance_properties o reset_overrides para usar los nombres de propiedad y grupos de sobrescritura correctos. |
Escritura: grafo
| Herramienta | Úsala para |
|---|---|
canvas_add_node | Añadir un nodo: node (id opcional y debe no estar usado, type registrado por el host, data, position, width, height, parentId para un marco). Omite position para colocarlo automáticamente sin solapamientos junto a nearNodeId en el side (por defecto right), lo que también conecta una arista desde ese nodo, o junto al último nodo. Devuelve el id del nuevo nodo y de la arista. |
canvas_connect | Añadir una arista desde source hasta target (dos nodos existentes diferentes), con una label opcional. Devuelve el id de la arista. |
canvas_update_node | Fusionar campos en data de un nodo (por ejemplo { "label": "Checkout" }). Trata la fusión como superficial: pasa objetos anidados como shape o layout completos. No mueve ni redimensiona nodos. |
canvas_remove_nodes | Eliminar nodos y sus aristas; cada id debe existir. Destructivo: confirma con el usuario antes de eliminar contenido que él haya creado. |
canvas_layout | Organizar el grafo automáticamente: direction LR (por defecto), TB, RL o BT. incremental (por defecto true) mantiene los nodos que ya tienen una posición; pasa false para reorganizar todo. Los nodos exactamente en (0, 0) se cuentan como no colocados. |
canvas_select | Reemplazar la selección (una lista vacía la limpia). Úsala para mostrar al usuario un resultado y para apuntar comandos que actúan sobre la selección. |
canvas_highlight | Hacer parpadear nodos para señalárselos al usuario: color (por defecto #3b82f6), durationMs (por defecto 2000, máximo 60000). No cambia nada. |
Expandir y contraer
Los hosts con nodos expandibles (una tarea que se abre en subtareas, una barra de Gantt en sus pasos) añaden estos. Expandir muestra los nodos hijos y mueve los nodos circundantes para hacer espacio; contraer elimina los hijos y devuelve los nodos movidos a su sitio. Es un cambio de vista, no una edición: no es un paso de deshacer y no se guarda con el documento. El host decide cuáles son los hijos.
| Herramienta | Úsala para |
|---|---|
list_explodable_nodes | Listar los nodos que se pueden expandir (id, label, exploded, collapsing), los ids exploded y collapsing ahora, si varios pueden estar abiertos a la vez (multiple), y la razón readOnly si expandir está deshabilitado. Llámala primero: es la única fuente de ids expandibles. |
explode_node | Expandir node (un id de list_explodable_nodes). A menos que multiple, el nodo expandido antes se contrae (vuelve en collapsed). Expandir un nodo ya expandido no cambia nada (changed: false). Devuelve los ids ahora exploded. Luego usa get_editor_state o capture_view para leer o ver los hijos. |
collapse_node | Contraer un node expandido. Devuelve los ids aún exploded y los que aún están collapsing (sus hijos se van cuando termina la animación de contracción). Falla cuando el nodo no está expandido. |
Propuestas (sugerir, no editar)
Los hosts que permiten a los agentes sugerir adiciones añaden estas. Una propuesta son nuevos nodos y aristas mostrados como fantasmas
(no arrastrables, seleccionables ni guardados). Aceptarlos los añade como un solo paso de deshacer, registrado como hecho por
quien lo propuso (agent:<id>); rechazarlos deja el canvas y su historial intactos.
|
… [truncado para traducción]