Un motor de dibujo 2D al estilo de PixiJS. Construye un grafo de escena con formas y lo dibuja a través de uno de tres motores traseros (Canvas2D, WebGL o WebGPU), elegido en tiempo de ejecución.
El motor está por capas: Application (ciclo de vida y bucle de dibujado), debajo Renderer (el motor trasero), y luego un grafo de escena que va de Container (un grupo) a Graphics (algo dibujable). Tú añades nodos a app.stage y el renderizador los pinta.
Solo navegador.ranuts/visual necesita un HTMLCanvasElement real y un contexto de GPU o de Canvas. En Node no puede correr.
Crea una aplicación, dibuja un rectángulo con relleno y contorno más un círculo, y arranca el bucle de dibujado.
import { Application, Graphics, RENDERER_TYPE } from 'ranuts/visual';const view = document.querySelector('canvas');// Application.create es asíncrona: el motor trasero de WebGPU inicializa su dispositivo// de forma asíncrona y tiene que terminar antes del primer dibujado.const app = await Application.create({ view, prefer: RENDERER_TYPE.CANVAS, // CANVAS | WEB_GL | WEB_GPU backgroundColor: '#1e1e1e',});// Un rectángulo: relleno rojo y contorno azul de 4px.const rect = new Graphics();rect.beginFill('#ff0000');rect.lineStyle(4, '#0000ff');rect.drawRect(20, 20, 160, 100);rect.endFill();// Un círculo.const circle = new Graphics();circle.beginFill('#00cc88', 0.8);circle.drawCircle(300, 120, 60);circle.endFill();// Añade los dibujables al stage, el antepasado de todo lo que se pinta.app.stage.addChild(rect);app.stage.addChild(circle);// Arranca el bucle de requestAnimationFrame (o llama a app.render() para un solo fotograma).app.start();
El punto de entrada del motor. Es dueño del canvas, del renderizador y de la raíz del grafo de escena (stage).
Usa la fábrica asíncrona Application.create(...) antes que new Application(...): el motor trasero de WebGPU inicializa su dispositivo de forma asíncrona y eso tiene que terminar antes del primer dibujado. Canvas y WebGL resuelven al instante, así que la fábrica es segura y uniforme para los tres.
Un nodo de agrupación, la idea de «grupo» del grafo de escena. Guarda hijos y el estado de transformación, pero él mismo no pinta nada; los dibujables como Graphics lo extienden. Añade un Container para armar subárboles que se muevan, escalen y roten juntos.
Un dibujable que extiende Container. Fija un relleno, un estilo de línea o ambos, y luego llama a un método de forma. Casi todos los métodos devuelven this, así que las llamadas se encadenan.
El motor trasero se elige con IApplicationOptions.prefer (un RENDERER_TYPE); si se omite, se usa Canvas.
CANVAS dibuja directamente con la API de Canvas2D (fillRect, arc, ctx.stroke(), …).
WEB_GL y WEB_GPU comparten una misma tubería BatchRenderer: las formas se trocean en triángulos, se empaquetan en un único búfer de vértices entrelazado y se dibujan de una sola llamada.
Los tres aceptan cualquier color CSS: hexadecimal (#rgb o #rrggbb), colores con nombre, rgb() y hsl() se resuelven todos igual.
La geometría del contorno cambia según el motor trasero, y es a propósito. En Canvas, los remates y las uniones de línea los dibuja el ctx.stroke() nativo del navegador; en WebGL y WebGPU, una triangulación propia. Los dos no coinciden píxel a píxel.