Skip to content

visual

Um motor de desenho 2D ao estilo do PixiJS. Monte um grafo de cena com formas e desenhe-o por um de três motores de fundo (Canvas2D, WebGL ou WebGPU), escolhido em tempo de execução.

O motor é feito em camadas: Application (ciclo de vida e laço de desenho), abaixo o Renderer (o motor de fundo), e então um grafo de cena que vai de Container (um grupo) até Graphics (algo desenhável). Você acrescenta nós ao app.stage e o renderizador os desenha.

Só navegador. O ranuts/visual precisa de um HTMLCanvasElement de verdade e de um contexto de GPU ou de Canvas. No Node ele não roda.

Importar

js
import { Application, Graphics, Container } from 'ranuts/visual';

Primeiros passos

Crie uma aplicação, desenhe um retângulo com preenchimento e contorno mais um círculo, e ponha o laço de desenho para rodar.

js
import { Application, Graphics, RENDERER_TYPE } from 'ranuts/visual';

const view = document.querySelector('canvas');

// Application.create é assíncrono: o motor de fundo do WebGPU inicializa o dispositivo
// de forma assíncrona e isso precisa terminar antes do primeiro desenho.
const app = await Application.create({
  view,
  prefer: RENDERER_TYPE.CANVAS, // CANVAS | WEB_GL | WEB_GPU
  backgroundColor: '#1e1e1e',
});

// Um retângulo: preenchimento vermelho e contorno azul de 4px.
const rect = new Graphics();
rect.beginFill('#ff0000');
rect.lineStyle(4, '#0000ff');
rect.drawRect(20, 20, 160, 100);
rect.endFill();

// Um círculo.
const circle = new Graphics();
circle.beginFill('#00cc88', 0.8);
circle.drawCircle(300, 120, 60);
circle.endFill();

// Acrescente os desenháveis ao stage, o ancestral de tudo o que é desenhado.
app.stage.addChild(rect);
app.stage.addChild(circle);

// Põe o laço do requestAnimationFrame para rodar (ou chame app.render() para um quadro só).
app.start();

API

Application

O ponto de entrada do motor. Ele é dono do canvas, do renderizador e da raiz do grafo de cena (stage).

Prefira a fábrica assíncrona Application.create(...) ao new Application(...): o motor de fundo do WebGPU inicializa o dispositivo de forma assíncrona e isso precisa terminar antes do primeiro desenho. Canvas e WebGL resolvem na hora, então a fábrica é segura e uniforme para os três.

Application.create(options)

static async. Constrói uma Application e espera a inicialização assíncrona do renderizador.

Parâmetros
ParâmetroDescriçãoTipoPadrão
optionsOpções de configuração da aplicaçãoIApplicationOptionsObrigatório
Devolve
ValorDescriçãoTipo
Promise<Application>A aplicação já inicializadaPromise<Application>

Properties

PropriedadeDescriçãoTipo
stageA raiz do grafo de cena. Acrescente aqui todo nó que você quer ver desenhado.Container
viewO elemento canvas em que se desenha.HTMLCanvasElement
eventSystemA distribuição de ponteiro e de eventos, presa ao canvas e ao stage.EventSystem

Methods

MétodoDescriçãoDevolve
render()Desenha um único quadro do stage.void
start()Põe para rodar o laço de desenho do requestAnimationFrame.void
stop()Para o laço de desenho que o start() pôs a rodar.void

IApplicationOptions

CampoDescriçãoTipoPadrão
preferQual motor de fundo usar. Se for omitido, recai no Canvas.RENDERER_TYPERENDERER_TYPE.CANVAS
viewO canvas de destino. Se for omitido, cria-se um <canvas> solto.HTMLCanvasElementum canvas novo
backgroundColorO fundo do canvas. Aceita qualquer string de cor CSS.string
backgroundAlphaOpacidade do fundo, de 0 a 1.number
debugEscreve no console qual motor de fundo foi escolhido.booleanfalse

Container

Um nó de agrupamento, a ideia de «grupo» do grafo de cena. Guarda filhos e o estado de transformação, mas ele mesmo não desenha nada; desenháveis como o Graphics o estendem. Acrescente um Container para montar subárvores que se movem, escalam e giram juntas.

Methods

MétodoDescriçãoDevolve
addChild(child)Acrescenta um filho (Container) ao fim. Se ele já tinha pai, troca o pai.void
removeChild(child)Tira um filho de children.void
sortChildren()Reordena children por zIndex (só quando é preciso).void
containsPoint(p)Verifica se um Point cai dentro do hitArea deste nó.boolean

Propriedades de transformação e exibição

Elas moram no nó base comum (Vertex) e estão disponíveis em qualquer Container ou Graphics.

PropriedadeDescriçãoTipo
childrenOs nós filhos (array só de leitura).Container[]
parentO nó pai, se estiver preso.Container | undefined
x / yA posição, no sistema de coordenadas do pai.number
positionO ponto de posição ({ x, y }).ObservablePoint
scaleO ponto de escala ({ x, y }).ObservablePoint
pivotO ponto de pivô para giro e escala.ObservablePoint
skewO ponto de inclinação.ObservablePoint
rotationGiro em radianos.number
angleGiro em graus (anda junto com rotation).number
alphaOpacidade do nó, de 0 a 1 (vai se multiplicando árvore abaixo).number
visibleCom false, o nó e sua subárvore são pulados.boolean
zIndexA ordem de desenho entre irmãos.number
hitAreaForma opcional usada nos testes de acerto.Shape | null
cursorO jeito do cursor quando ele aponta para o nó.Cursor
structureVersionVersão da estrutura da cena (só na raiz); guia o rastreio do que mudou.number

Graphics

Um desenhável que estende o Container. Defina um preenchimento, um estilo de linha ou ambos, e depois chame um método de forma. Quase todos os métodos devolvem this, então as chamadas encadeiam.

Estilo

MétodoDescriçãoDevolve
beginFill(color?, alpha?)Começa a preencher com color (string CSS, padrão '#000000') e alpha (padrão 1).Graphics
endFill()Para de preencher.Graphics
lineStyle(width, color?, alpha?)Define o contorno: width px, color (padrão '#000000'), alpha (padrão 1).Graphics
lineStyle(options)Define o contorno a partir de um objeto ILineStyleOptions.Graphics
resetLineStyle()Devolve o contorno atual aos valores padrão.void

Formas

MétodoDescriçãoDevolve
drawRect(x, y, width, height)Retângulo.Graphics
drawRoundedRect(x, y, width, height, radius)Retângulo de cantos arredondados.Graphics
drawCircle(x, y, radius)Círculo com centro em (x, y).Graphics
drawEllipse(x, y, radiusX, radiusY)Elipse com centro em (x, y).Graphics
drawPolygon(points)Polígono fechado a partir de um array plano [x0, y0, x1, y1, …].Graphics

Traçados

MétodoDescriçãoDevolve
moveTo(x, y)Começa um subtraçado novo em (x, y).Graphics
lineTo(x, y)Linha reta até (x, y).Graphics
quadraticCurveTo(cpX, cpY, toX, toY)Curva de Bézier quadrática (partida em segmentos).Graphics
bezierCurveTo(cpX, cpY, cpX2, cpY2, toX, toY)Curva de Bézier cúbica (partida em segmentos).Graphics
arc(cx, cy, radius, startAngle, endAngle, anticlockwise?)Arco de circunferência.Graphics
arcTo(x1, y1, x2, y2, radius)Arco tangente às duas retas que passam pelos pontos de controle.Graphics
closePath()Fecha o subtraçado atual.Graphics
clear()Apaga toda a geometria e devolve os estilos ao estado inicial.Graphics
containsPoint(p)Verifica se um Point cai dentro da geometria desenhada.boolean

IFillStyleOptions

CampoDescriçãoTipoPadrão
colorCor de preenchimento (qualquer cor CSS).string'#ffffff'
alphaOpacidade do preenchimento, de 0 a 1.number1
visibleSe o preenchimento é desenhado.booleanfalse

ILineStyleOptions

Estende IFillStyleOptions e acrescenta:

CampoDescriçãoTipoPadrão
widthEspessura do contorno, em px.number0
capO acabamento das pontas da linha.LINE_CAPLINE_CAP.BUTT
joinA junção entre linhas.LINE_JOINLINE_JOIN.MITER

Enumerações

RENDERER_TYPE

Escolhe o motor de fundo de desenho por meio de IApplicationOptions.prefer.

MembroValorDescrição
CANVAS'canvas'Motor de fundo Canvas2D (o padrão).
WEB_GL'webgl'Motor de fundo WebGL.
WEB_GPU'webgpu'Motor de fundo WebGPU.

SHAPE_TYPE

Os tipos de forma que os métodos de desenho do Graphics produzem.

MembroValor
RECTANGLE'rectangle'
POLYGON'polygon'
CIRCLE'circle'
ELLIPSE'ellipse'
ROUNDED_RECTANGLE'rounded rectangle'

LINE_CAP

MembroValor
BUTT'butt'
ROUND'round'
SQUARE'square'

LINE_JOIN

MembroValor
MITER'miter'
BEVEL'bevel'
ROUND'round'

Constantes

ConstanteValorDescrição
MAX_VERTEX_COUNT65536Número máximo de vértices que cada buffer de lote aceita.
BYTES_PER_VERTEX12Bytes por vértice (2 Float32 de posição e 4 Uint8 de cor).

Motores de fundo

O motor de fundo é escolhido por IApplicationOptions.prefer (um RENDERER_TYPE); se for omitido, usa-se o Canvas.

  • O CANVAS desenha direto pela API do Canvas2D (fillRect, arc, ctx.stroke(), …).
  • O WEB_GL e o WEB_GPU compartilham a mesma esteira BatchRenderer: as formas são partidas em triângulos, empacotadas num único buffer de vértices intercalado e desenhadas numa chamada só.

Os três aceitam qualquer cor CSS: hexadecimal (#rgb ou #rrggbb), cores com nome, rgb() e hsl() são todas resolvidas do mesmo jeito.

A geometria do contorno muda conforme o motor de fundo, e isso é de propósito. No Canvas, as pontas e as junções de linha são desenhadas pelo ctx.stroke() nativo do navegador; no WebGL e no WebGPU, por uma triangulação própria. Os dois não coincidem pixel a pixel.

Publicado sob a licença MIT.