Signatur
Beschreibung
PaintRenderingContext2D ist der Zeichenkontext, den der Browser als erstes Argument an die Methode paint(ctx, size, properties, args) einer Klasse übergibt, die mit registerPaint() in einem Paint Worklet registriert wurde. Das Ergebnis erscheint überall dort, wo in CSS die Funktion paint(name) verwendet wird, etwa in background-image, border-image oder mask-image.
Die Schnittstelle ist eine Teilmenge von CanvasRenderingContext2D. Verfügbar sind unter anderem Zustandsverwaltung (save(), restore()), Transformationen (translate(), rotate(), scale(), setTransform()), Stile und Verläufe (fillStyle, strokeStyle, createLinearGradient(), createRadialGradient(), createPattern()), Rechtecke (fillRect(), clearRect()), Pfade (beginPath(), arc(), lineTo(), bezierCurveTo(), fill(), stroke(), clip()), Linienstile, Schatten, Compositing (globalAlpha, globalCompositeOperation) und drawImage().
Nicht verfügbar sind Textfunktionen (fillText(), measureText(), font), Pixelzugriff (getImageData(), putImageData(), createImageData()) sowie die Eigenschaft canvas. Das verhindert, dass Worklets Pixeldaten auslesen oder Informationen nach außen weitergeben, und erlaubt dem Browser, das Zeichnen außerhalb des Hauptthreads auszuführen.
Man verwendet den Kontext für dekorative, auflösungsunabhängige Effekte, die sich über CSS-Custom-Properties steuern lassen: Muster, Rahmen, Verläufe oder animierbare Hintergründe, ohne zusätzliche DOM-Elemente oder Bilddateien.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $ctx Pflicht | PaintRenderingContext2D | Erstes Argument von paint(): der Zeichenkontext. Man erzeugt ihn nicht selbst, der Browser stellt ihn bereit. |
|
| $size Pflicht | PaintSize | Zweites Argument von paint(): Objekt mit width und height der zu bemalenden Fläche in CSS-Pixeln. |
|
| $properties Pflicht | StylePropertyMapReadOnly | Drittes Argument: die über static get inputProperties() angeforderten CSS-Eigenschaften, lesbar mit properties.get('--name'). |
|
| $args | Array<CSSUnparsedValue> | [] | Viertes Argument: Argumente aus paint(name, …) in CSS, sofern static get inputArguments() definiert ist (nur hinter Flag unterstützt). |
Beispiele
Einfaches Schachbrettmuster als Hintergrund
// checkerboard.js – läuft im Paint Worklet
class CheckerboardPainter {
paint(ctx, size) {
const tile = 16;
const colors = ['#e0e0e0', '#9e9e9e'];
for (let y = 0; y < size.height / tile; y++) {
for (let x = 0; x < size.width / tile; x++) {
ctx.fillStyle = colors[(x + y) % 2];
ctx.fillRect(x * tile, y * tile, tile, tile);
}
}
}
}
registerPaint('checkerboard', CheckerboardPainter);
// main.js – im Hauptdokument
if ('paintWorklet' in CSS) {
CSS.paintWorklet.addModule('checkerboard.js');
}
/* CSS:
.box { background-image: paint(checkerboard); }
*/
Über Custom Properties steuerbarer Kreis
// dot.js
registerPaint('dot', class {
static get inputProperties() {
return ['--dot-color', '--dot-size'];
}
paint(ctx, { width, height }, props) {
const color = props.get('--dot-color').toString().trim() || 'tomato';
const radius = parseFloat(props.get('--dot-size').toString()) || 20;
ctx.beginPath();
ctx.arc(width / 2, height / 2, radius, 0, Math.PI * 2);
ctx.fillStyle = color;
ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
ctx.shadowBlur = 8;
ctx.fill();
}
});
/* CSS:
.badge {
--dot-color: steelblue;
--dot-size: 30;
background-image: paint(dot);
}
*/
Verlauf mit Transformation und Zustandsverwaltung
// stripes.js
registerPaint('stripes', class {
paint(ctx, size) {
const grad = ctx.createLinearGradient(0, 0, size.width, 0);
grad.addColorStop(0, '#ff6b6b');
grad.addColorStop(1, '#4ecdc4');
ctx.fillStyle = grad;
ctx.fillRect(0, 0, size.width, size.height);
ctx.save();
ctx.globalAlpha = 0.2;
ctx.fillStyle = '#fff';
ctx.rotate(-Math.PI / 4);
for (let i = -size.height; i < size.width + size.height; i += 20) {
ctx.fillRect(i, -size.height, 8, size.width + size.height * 2);
}
ctx.restore();
// Feature-Test: Text gibt es hier nicht
console.log(typeof ctx.fillText); // Ausgabe in der Worklet-Konsole
}
});
// Wichtig · Fallstricke
- Browser-Kompatibilität: Die CSS Painting API wird nur von Chromium-basierten Browsern unterstützt (Chrome, Edge, Opera). Firefox und Safari unterstützen sie nicht. Vorher mit
'paintWorklet' in CSSprüfen und in CSS einen Fallback setzen, z. B. zuerstbackground-image: linear-gradient(…)und danachbackground-image: paint(name). - Eingeschränkter Funktionsumfang: Es gibt kein
fillText(),getImageData(),putImageData()und keine Eigenschaftcanvas. Code aus Canvas-Projekten lässt sich deshalb nicht immer eins zu eins übernehmen. - Kein Zustand zwischen Aufrufen: Der Browser kann
paint()jederzeit und in mehreren Worklet-Instanzen aufrufen. Deshalb keine Daten in Instanzfeldern ablegen, von denen die Ausgabe abhängt. Das Zeichnen muss deterministisch sein. - Sichere Umgebung:
addModule()funktioniert nur in einem sicheren Kontext (HTTPS oderlocalhost). Im Worklet gibt es weder DOM,fetchnoch Timer. - Transparenz: Mit
registerPaint(name, class, { alpha: false })bzw.static get contextOptions() { return { alpha: false }; }ist der Kontext undurchsichtig. Das kann schneller sein, macht aber durchscheinende Bereiche unmöglich. - Leistung: Bei jeder Größenänderung und jeder Änderung der beobachteten Eigenschaften wird neu gezeichnet. Aufwendige Schleifen daher kurz halten, besonders wenn Custom Properties animiert werden.