Eine 2D-Rendermaschine nach Art von PixiJS. Bau einen Szenengraph aus Formen und lass ihn über eines von drei Backends zeichnen (Canvas2D, WebGL oder WebGPU), zur Laufzeit gewählt.
Die Maschine ist geschichtet: Application (Lebenszyklus und Zeichenschleife), darunter Renderer (das Backend), darunter ein Szenengraph von Container (einer Gruppe) bis Graphics (etwas Zeichenbarem). Du hängst Knoten an app.stage, und der Renderer zeichnet sie.
Nur für den Browser.ranuts/visual braucht ein echtes HTMLCanvasElement und einen GPU- oder Canvas-Kontext. In Node läuft es nicht.
Eine Anwendung erzeugen, ein gefülltes und umrandetes Rechteck sowie einen Kreis zeichnen und die Zeichenschleife starten.
import { Application, Graphics, RENDERER_TYPE } from 'ranuts/visual';const view = document.querySelector('canvas');// Application.create ist asynchron: Das WebGPU-Backend richtet sein Gerät// asynchron ein, und das muss vor dem ersten Zeichnen fertig sein.const app = await Application.create({ view, prefer: RENDERER_TYPE.CANVAS, // CANVAS | WEB_GL | WEB_GPU backgroundColor: '#1e1e1e',});// Ein Rechteck: rote Füllung und eine 4px breite blaue Kontur.const rect = new Graphics();rect.beginFill('#ff0000');rect.lineStyle(4, '#0000ff');rect.drawRect(20, 20, 160, 100);rect.endFill();// Ein Kreis.const circle = new Graphics();circle.beginFill('#00cc88', 0.8);circle.drawCircle(300, 120, 60);circle.endFill();// Zeichenbares an die stage hängen – den Vorfahren von allem, was gezeichnet wird.app.stage.addChild(rect);app.stage.addChild(circle);// Die requestAnimationFrame-Schleife starten (oder app.render() für ein einzelnes Bild aufrufen).app.start();
Der Einstiegspunkt der Maschine. Ihm gehören das Canvas, der Renderer und die Wurzel des Szenengraphs (stage).
Nimm lieber die asynchrone Fabrik Application.create(...) als new Application(...): Das WebGPU-Backend richtet sein Gerät asynchron ein, und das muss vor dem ersten Zeichnen fertig sein. Canvas und WebGL lösen sofort auf, die Fabrik ist also für alle Backends sicher und einheitlich.
Ein Gruppenknoten – der Begriff „Gruppe“ des Szenengraphs. Er hält Kinder und den Zustand der Transformation, zeichnet selbst aber nichts; Zeichenbares wie Graphics erweitert ihn. Nimm einen Container, um Teilbäume zu bauen, die sich gemeinsam bewegen, skalieren und drehen.
Etwas Zeichenbares, das Container erweitert. Setz eine Füllung, einen Linienstil oder beides und ruf dann eine Formmethode auf. Die meisten Methoden geben this zurück, Aufrufe lassen sich also verketten.
Das Backend wird über IApplicationOptions.prefer gewählt (ein RENDERER_TYPE); lässt du es weg, wird Canvas genommen.
CANVAS zeichnet unmittelbar über die Canvas2D-API (fillRect, arc, ctx.stroke(), …).
WEB_GL und WEB_GPU teilen sich eine BatchRenderer-Strecke: Formen werden in Dreiecke zerlegt, in einen einzigen verschränkten Vertexpuffer gepackt und mit einem Aufruf gezeichnet.
Alle drei nehmen jede CSS-Farbe an: hexadezimal (#rgb oder #rrggbb), benannte Farben, rgb() und hsl() werden gleichermaßen aufgelöst.
Die Geometrie der Kontur unterscheidet sich je nach Backend – mit Absicht. Linienenden und -verbindungen zeichnet auf dem Canvas-Backend das native ctx.stroke() des Browsers, auf WebGL und WebGPU dagegen eine eigene Zerlegung in Dreiecke. Pixelgleich sind die beiden nicht.