Signatur
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 inpropertieslesbar und lösen bei Änderungen ein Neuzeichnen aus.static get inputArguments(): Syntaxangaben für Argumente, die direkt inpaint(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
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 oderwindow.ctxkann keinen Text zeichnen. - Nicht registrierte Custom Properties kommen als
CSSUnparsedValuean und müssen mittoString()selbst ausgewertet werden. Erst mitCSS.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.