Start · Sprachen · JavaScript · Referenz · PaintWorkletGlobalScope.registerPaint()

PaintWorkletGlobalScope.registerPaint()

Methode

Registriert innerhalb eines Paint-Worklets eine Klasse, die über <code>paint(name)</code> in CSS programmatisch ein Bild zeichnet, z. B. für <code>background-image</code>.

seit JavaScript CSS Painting API Level 1 – Chromium 65+ (Chrome, E Kategorie: webapi

Signatur

PaintWorkletGlobalScope.registerPaint(name, classRef)

Beschreibung

registerPaint() ist Teil der CSS Painting API (Houdini). Die Methode steht nur im globalen Gültigkeitsbereich eines Paint-Worklets zur Verfügung, also im Skript, das per CSS.paintWorklet.addModule() geladen wurde. Sie verknüpft einen frei wählbaren Namen mit einer Klasse. Diese Klasse muss eine Methode paint(ctx, size, properties, args) haben, die der Browser immer dann aufruft, wenn ein Element mit paint(name) neu gezeichnet werden muss.

Wofür braucht man das? Überall dort, wo CSS ein Bild erwartet (background-image, border-image, mask-image, list-style-image …), kann statt einer Datei ein dynamisch gezeichnetes Bild stehen. Typische Anwendungen sind Muster, Verläufe, Platzhalter, Rahmeneffekte oder Hervorhebungen. Die Zeichnung passt sich automatisch an die Größe des Elements an und kann über CSS-Custom-Properties gesteuert werden.

Die Klasse kann über optionale statische Getter weitere Angaben machen:

  • static get inputProperties(): ein Array von CSS-Eigenschaften (auch Custom Properties wie --farbe). Nur diese sind in properties lesbar und lösen bei Änderungen ein Neuzeichnen aus.
  • static get inputArguments(): Syntaxangaben für Argumente, die direkt in paint(name, …) übergeben werden.
  • static get contextOptions(): z. B. { alpha: false } für einen deckenden Zeichenkontext.

Der Zeichenkontext ctx ist ein PaintRenderingContext2D, eine Teilmenge von CanvasRenderingContext2D. Text-Rendering und Bitmap-Funktionen wie getImageData() gibt es dort nicht.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Name des Painters, der in CSS als paint(name) verwendet wird. Darf kein Leerstring sein und pro Worklet nur einmal registriert werden.
$classRef Pflicht class (Konstruktor) Referenz auf eine Klasse mit einer Methode paint(ctx, size, properties, args). Optional mit den statischen Gettern inputProperties, inputArguments und contextOptions.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Bei ungültigen Angaben wird ein TypeError geworfen, bei doppelt vergebenem Namen eine InvalidModificationError-DOMException.

Beispiele

Einfaches Schachbrettmuster registrieren und einbinden

// schachbrett.js – läuft im PaintWorkletGlobalScope
class Schachbrett {
  paint(ctx, size) {
    const feld = 16;
    for (let y = 0; y < size.height / feld; y++) {
      for (let x = 0; x < size.width / feld; x++) {
        ctx.fillStyle = (x + y) % 2 === 0 ? '#ddd' : '#fff';
        ctx.fillRect(x * feld, y * feld, feld, feld);
      }
    }
  }
}
registerPaint('schachbrett', Schachbrett);

// main.js – im Hauptdokument
if ('paintWorklet' in CSS) {
  CSS.paintWorklet.addModule('schachbrett.js');
}

/* CSS:
.box { background-image: paint(schachbrett); }
*/

Über Custom Properties gesteuerte Hervorhebung

// highlight.js
registerPaint('highlight', class {
  static get inputProperties() {
    return ['--highlight-farbe', '--highlight-hoehe'];
  }

  paint(ctx, size, props) {
    const farbe = props.get('--highlight-farbe').toString().trim() || 'yellow';
    const hoehe = parseFloat(props.get('--highlight-hoehe').toString()) || 0.4;
    ctx.fillStyle = farbe;
    // Unteres Drittel des Elements markieren
    ctx.fillRect(0, size.height * (1 - hoehe), size.width, size.height * hoehe);
  }
});

/* CSS:
mark {
  --highlight-farbe: #ffe066;
  --highlight-hoehe: 0.5;
  background: paint(highlight);
}
*/

Animierbare Custom Property mit CSS.registerProperty

// main.js – Property typisieren, damit sie animiert werden kann
CSS.registerProperty({
  name: '--fortschritt',
  syntax: '<number>',
  inherits: false,
  initialValue: '0'
});
await CSS.paintWorklet.addModule('ring.js');

// ring.js
registerPaint('ring', class {
  static get inputProperties() { return ['--fortschritt']; }
  paint(ctx, { width, height }, props) {
    const wert = props.get('--fortschritt').value; // CSSUnitValue
    const r = Math.min(width, height) / 2 - 4;
    ctx.lineWidth = 6;
    ctx.strokeStyle = '#0a7';
    ctx.beginPath();
    ctx.arc(width / 2, height / 2, r, -Math.PI / 2, -Math.PI / 2 + wert * 2 * Math.PI);
    ctx.stroke();
  }
});

/* CSS:
.lader { background: paint(ring); animation: laden 2s infinite; }
@keyframes laden { to { --fortschritt: 1; } }
*/

// Wichtig · Fallstricke

Browser-Kompatibilität: Die Methode wird nur von Chromium-basierten Browsern unterstützt (Chrome, Edge und Opera ab Version 65). Firefox und Safari unterstützen sie derzeit nicht. Prüfe deshalb mit 'paintWorklet' in CSS, ob sie verfügbar ist, und lege in CSS einen Ersatz fest, z. B. background: #eee; background: paint(muster);. Worklets funktionieren nur in sicheren Kontexten (HTTPS oder localhost).

  • registerPaint() gibt es nur im Worklet-Skript. Im Hauptdokument ist die Funktion nicht definiert.
  • Die Painter-Instanz kann jederzeit neu erzeugt werden, und der Browser kann mehrere Worklet-Instanzen parallel betreiben. Speichere deshalb keinen Zustand in der Instanz.
  • Im Worklet gibt es weder DOM noch fetch, Timer oder window. ctx kann keinen Text zeichnen.
  • Nicht registrierte Custom Properties kommen als CSSUnparsedValue an und müssen mit toString() selbst ausgewertet werden. Erst mit CSS.registerProperty() erhältst du typisierte Werte, und die Eigenschaft wird animierbar.
  • Wird derselbe Name ein zweites Mal registriert, führt das zu einer InvalidModificationError.
  • Rechenintensive paint()-Methoden bremsen das Rendering, weil sie bei jeder Größen- oder Property-Änderung aufgerufen werden.