Canvas Pixerate
O canvas é um grafo xyflow (React Flow / SvelteFlow): um array de nós e arestas.
Um nó é { id, type, position: { x, y }, width?, height?, parentId?, zIndex?, data }; arestas são
{ id, source, target, label? }. Tudo que um recurso de design conhece vive em node.data, então
sobrevive a cópia, colagem e JSON:
data.label/data.name: conteúdo de texto e nome da camada.data.shape: um nó de forma ({ kind: rect | ellipse | polygon | star | path, fill, stroke, strokeWidth, ... }).data.layout: um quadro de layout automático (modehorizontal / vertical / grade,gap,padding,alignMain,alignCross,sizing); seus filhos são os nós cujoparentIdé o quadro, na ordem do array de nós.data.childLayout: dimensionamento do filho (fixo / ajustar / preencher) e restrições.data.component(um componente principal),data.componentSet(um conjunto de variantes),data.instance({ componentId, properties }) edata.componentOverrides.data.locked,data.animation(trackes de keyframe),data.tokenBindings(tokens de design).
As posições estão em unidades do canvas (fluxo); a posição de um filho é relativa ao seu pai. IDs de nós vêm
de get_editor_state; IDs de componentes e conjuntos vêm de list_components. Ferramentas que aceitam ids ou
id usam como padrão a seleção atual quando você os omite, então passe IDs explicitamente a menos que
você acabou de selecionar com canvas_select. Veja pixerate-agent-tools para namespacing, run_commands
para loteamento e códigos de erro.
Habilidades de fluxo de trabalho
Para esses trabalhos, carregue também a habilidade de fluxo de trabalho: ela contém o método, as verificações entre etapas e as armadilhas, e usa as ferramentas abaixo.
pixerate-canvas-design-system-components: componentes, instâncias, conjuntos de variantes e substituições.pixerate-canvas-layout: alinhar, distribuir, ordenar e bloquear.
Método de trabalho
- Leia.
get_editor_statecomincludeDocument: falseretornacanvas.nodesecanvas.edges. Para um sistema de design, chame tambémlist_componentseinspect_instanceantes de alterar uma instância. - Planeje a estrutura primeiro: quais quadros, quais componentes reutilizáveis e variantes, qual escala de espaçamento. Construa o componente principal uma vez, depois coloque instâncias; não copie nós manualmente.
- Escreva. Use as ferramentas dedicadas para edições do grafo (
canvas_add_node,canvas_connect,canvas_update_node) e componentes (create_component,create_instance, ...). Userun_commandscomatomic: truepara comandos de arranjo, forma e animação, e sempre que várias etapas devem ser um único passo de desfazer (um parâmetro"$0.ids[0]"usa um ID que uma etapa anterior retornou). - Organize.
canvas_layoutpara grafos;canvas.align*/canvas.distribute*para designs; ordem de camadas comcanvas.bringToFronte similares; bloqueie fundos finalizados comcanvas.lock. - Veja.
view_editor(viewport padrão, JPEG, 1024 px) após um lote; usescope: "canvas"para o desenho inteiro. Corrija sobreposições, desalinhamentos e texto cortado, depois mostre ao usuário comcanvas_selectoucanvas_highlight.
Trabalhando junto com o usuário (ele está construindo e você adiciona sem ser solicitado): sugira em vez de
editar. propose_nodes mostra fantasmas que o usuário aceita ou descarta, e nada atinge o canvas
ou seu histórico até então. Mantenha cada proposta pequena e sobre uma ideia (uma legenda, o próximo cartão em
uma série, um conector faltando), dê a ela um title e uma rationale de uma frase, e ancora-a ao
nó que complementa com nearNodeId. Nunca aceite suas próprias propostas a menos que o usuário tenha pedido.
Retire as obsoletas com reject_proposal: quando o usuário altera algo no qual uma proposta se baseia,
list_proposals mostra-a sob missing.
Melhores práticas
-
Pensamento de sistema de design. Qualquer coisa que aparece duas vezes deve ser um componente: construa um principal,
combine_as_variantspara estados e tamanhos (State=Default,State=Hover,Size=Small), depoiscreate_instanceem todos os lugares. Altere o principal para alterar todas as instâncias; use substituições apenas para conteúdo por uso (texto do rótulo, troca de ícone). Nomeie as propriedades e valores de variantes de forma consistente (propriedade em Title Case, valores curtos) e mantenha as combinações únicas. -
Nomeie camadas que devem sobreviver a uma troca de variante com um
data.nameestável. A correspondência recai emdata.label, que para texto é seu conteúdo e difere entre variantes. -
Use propriedades de componente, não desanexar. Alterne variantes e defina propriedades de texto ou booleanas com
set_instance_properties;swap_instancepara outro componente. Desanexe apenas quando a instância deve deixar de seguir seu principal. -
Escala de espaçamento. Escolha uma unidade base (4 ou 8) e use múltiplos para lacunas e preenchimento. Coloque linhas e pilhas em quadros de layout automático (
data.layout) em vez de posicionar filhos manualmente, para que eles sejam reajustados quando o conteúdo mudar. -
Alinhamento e distribuição. Alinhe a uma borda ou centro compartilhado, depois distribua com lacunas iguais; um design parece ordenado quando as bordas se alinham. Bloqueie um nó que você quer como âncora: nós bloqueados nunca se movem, mas ainda contam para os limites da seleção.
-
Camadas. Fundos atrás, conteúdo acima, sobreposições no topo. Use os comandos de reempilhamento; eles definem
zIndexpor grupo de irmãos e nunca reordenam o array. -
Layout de grafo. Disponha fluxos em uma direção (
LRpara pipelines,TBpara hierarquias), mantenha as arestas curtas, rotule arestas apenas quando o relacionamento não for óbvio. -
Movimento. Use ease-out (ou
ease-out-backpara um pequeno overshoot) para coisas chegando, ease-in para coisas saindo, ease-in-out para movimentos entre dois lugares de descanso, elinearapenas para movimento contínuo como rotação. Mantenha as transições de UI entre 150 e 400 ms e entradas abaixo de cerca de 600 ms; escalone elementos relacionados por 30 a 80 ms comdelayem vez de mover tudo de uma vez. Animaopacity,x,y,scaleerotation; tweens de cor interpolam em OKLab. -
Traços com pincel. Use um pincel quando o usuário quiser uma aparência feita à mão (esboço, tinta, lápis, marcador); mantenha traços simples para diagramas e UI. Envie pontos a cada 2 a 8 unidades do canvas ao longo de uma curva, e molde a linha com um perfil curto de
pressure(pontas cônicas:[0.2, 0.9, 1, 0.9, 0.2]) em vez de muitos pontos de larguras diferentes. Deixewidthde fora para usar o tamanho próprio do preset (canvas.listBrushesfornece); passe-o apenas para tornar a marca mais fina ou mais ousada. -
Caráter do pincel. Cada preset desenha com seu próprio caráter: carvão e pastel são largos e granulados (eles pegam a textura do papel), assim como giz pastel; lápis é fino e levemente granulado; tinta, marcador, caneta de pincel, caneta esferográfica, caneta gel e caneta fine line são limpos (a fine line mantém uma largura), o aerógrafo é um spray suave. O grão e a oscilação são semeados por traço, então um traço sempre parece o mesmo, e traços vizinhos compartilham uma folha de papel. Escolha o pincel pela aparência, depois a cor; para um esboço, use um ou dois pincéis em vez de todos eles. Um pincel com uma cor padrão (azul esferográfica, amarelo marcador, giz) pinta nessa cor quando você não passa
color; passecolorpara usar outra. Os padrões claro/escuro (giz) são resolvidos de acordo com o esquema de cores do canvas (canvas.setColorScheme; o host geralmente corresponde ao seu tema). -
Configurando a caneta para a pessoa, não desenhando.
canvas.selectBrushescolhe o pincel que a pessoa desenha manualmente, como o seletor de pincéis faz: ele pega a cor padrão do pincel a menos que eles tenham travado a sua (canvas.setColorLocked, "Manter minha cor") ou você passekeepColour. Uma cor padrão obtida dessa forma segue o esquema até que outra cor seja definida. Respeite um bloqueio que a pessoa definiu; não o desbloqueie para mudar a cor dela. Estes são estado do editor, não passos de desfazer, e não afetamcanvas.drawFreehand, que recebe seu própriobrushecolor. -
Anote com gestos, não pontos. Para marcar trabalho como um designer marca uma impressão, use comandos de gesto (
canvas.circle,canvas.underline,canvas.arrow,canvas.bracket,canvas.strike,canvas.cross,canvas.check) com IDs de nós ({ "nodeId": "..." }) ou caixas, em vez de calcular pontos paracanvas.drawFreehand. Uma chamada desenha uma marca feita à mão. Uma anotação ajuda quando você está apontando para algo no canvas enquanto fala sobre isso: circule a escolha, sublinhe a linha que importa, desenhe uma seta de uma amostra para onde é usada, coloque colchetes em um grupo que você está descrevendo, risque ou cruze uma opção rejeitada, marque uma aprovada. Pule quando nada no canvas está sendo referido e mantenha algumas marcas por ponto: uma página coberta de marcas não diz nada. -
Estilo do gesto. Use uma cor para uma passagem de revisão (uma caneta vermelha ou azul forte lê como marcação sobre a maioria dos designs), o marcador apenas para círculos e sublinhados, e o mesmo
brush(markerouink-pen) para cada marca de uma passagem se você quiser que pareçam feitos à mão. As marcas são semeadas por sua solicitação, então pedir novamente desenha a mesma marca; passe outroseedpara uma aparência diferente. Coloque uma nota marginal (um nó de texto) ao lado de um colchete ou na cauda de uma seta quando a marca precisar de palavras.
Referência de ferramentas
Leitura
| Ferramenta | Use para |
|---|---|
get_editor_state | Ler o grafo do canvas (canvas.nodes, canvas.edges) e, por padrão, o documento do prompt também. Passe includeDocument: false em uma tarefa apenas de canvas para manter o resultado pequeno, includeCanvas: false para apenas o prompt. Chame-a primeiro e novamente após edições feitas pelo usuário. |
view_editor | Obter uma imagem do editor: scope viewport (padrão) ou canvas (os limites de todo o desenho), format jpeg (padrão) ou png, maxEdge em pixels (padrão 1024). Use após um lote para julgar sobreposição, equilíbrio e legibilidade; cursores de agente são omitidos. |
capture_view | Capturar parte do canvas para verificar um resultado: region viewport (padrão, como na tela), content (todo nó), selection, nodes (com ids de get_editor_state) ou rect (unidades do canvas); padding (padrão 16), maxEdge (padrão 1024), format png (padrão) ou jpeg. O resultado fornece o rect e scale capturados, então o pixel da imagem (px, py) é o ponto do canvas (rect.x + px / scale, rect.y + py / scale). Prefira nodes para inspecionar o que você acabou de adicionar com detalhes completos. Caixas de seleção e cursores de agente são omitidos a menos que includeOverlays. |
list_components | Listar componentes principais (id, nome, valores de variante, contagem de instâncias) e conjuntos de componentes com suas opções de variante. Chame antes de create_instance, swap_instance ou qualquer ferramenta de variante para obter IDs e os nomes e valores exatos das propriedades. |
inspect_instance | Descrever uma instância (ou uma camada dentro dela; padrão o primeiro nó selecionado): seu principal, variante, valores de propriedade do componente com tipos e substituições por camada. Chame antes de set_instance_properties ou reset_overrides para usar os nomes de propriedade e grupos de substituição corretos. |
Escrita: grafo
| Ferramenta | Use para |
|---|---|
canvas_add_node | Adicionar um nó: node (id opcional e deve ser não utilizado, type registrado pelo host, data, position, width, height, parentId para um quadro). Deixe position de fora para auto-posicioná-lo sem sobreposições ao lado de nearNodeId em side (padrão right), o que também conecta uma aresta a partir desse nó, ou ao lado do último nó. Retorna o novo id do nó e id da aresta. |
canvas_connect | Adicionar uma aresta de source para target (dois nós existentes diferentes), com um label opcional. Retorna o id da aresta. |
canvas_update_node | Fundir campos em data de um nó (por exemplo, { "label": "Checkout" }). Trate a fusão como superficial: passe objetos aninhados como shape ou layout por inteiro. Não move ou redimensiona nós. |
canvas_remove_nodes | Excluir nós e suas arestas; cada id deve existir. Destrutivo: confirme com o usuário antes de remover conteúdo que ele criou. |
canvas_layout | Organizar o grafo automaticamente: direction LR (padrão), TB, RL ou BT. incremental (padrão true) mantém nós que já têm uma posição; passe false para reorganizar tudo. Nós exatamente em (0, 0) são considerados não posicionados. |
canvas_select | Substituir a seleção (uma lista vazia a limpa). Use para mostrar ao usuário um resultado e para direcionar comandos que agem na seleção. |
canvas_highlight | Piscar nós para apontar o usuário para eles: color (padrão #3b82f6), durationMs (padrão 2000, máximo 60000). Não altera nada. |
Expandir e recolher
Hosts com nós expansíveis (uma tarefa que abre em subtarefas, uma barra de Gantt em suas etapas) adicionam estes. Expandir mostra os nós filhos do nó e move os nós ao redor para abrir espaço; recolher remove os filhos e coloca os nós movidos de volta. É uma mudança de visualização, não uma edição: não é um passo de desfazer e não é salvo com o documento. O host decide quais são os filhos.
| Ferramenta | Use para |
|---|---|
list_explodable_nodes | Listar os nós que podem expandir (id, label, exploded, collapsing), os ids exploded e collapsing agora, se vários podem estar abertos ao mesmo tempo (multiple), e o motivo readOnly se a expansão estiver desativada. Chame primeiro: é a única fonte de ids expansíveis. |
explode_node | Expandir node (um id de list_explodable_nodes). A menos que multiple, o nó expandido antes é recolhido (ele volta em collapsed). Expandir um nó já expandido não altera nada (changed: false). Retorna os ids agora exploded. Em seguida, use get_editor_state ou capture_view para ler ou ver os filhos. |
collapse_node | Recolher um node expandido. Retorna os ids ainda exploded e aqueles ainda collapsing (seus filhos saem quando a animação de recolhimento termina). Falha quando o nó não está expandido. |
Propostas (sugira, não edite)
Hosts que permitem que agentes sugiram adições adicionam estes. Uma proposta são novos nós e arestas mostrados como fantasmas
(não arrastáveis, selecionáveis ou salvos). Aceitar adiciona como um passo de desfazer, registrado como feito por
quem propôs (agent:<id>); rejeitar deixa o canvas e seu histórico intocados.
| ... |