Start · Sprachen · JavaScript · Referenz · CSS.paintWorklet

CSS.paintWorklet

Eigenschaft

Statische, schreibgeschützte Eigenschaft, die das <code>Worklet</code> der CSS Painting API liefert, mit dem man Bilder für CSS-Eigenschaften per Skript zeichnen kann.

seit JavaScript Chromium 65+ (Chrome, Edge, Opera); nicht in Firef Kategorie: webapi

Signatur

CSS.paintWorklet

Beschreibung

CSS.paintWorklet gibt das Paint-Worklet der CSS Painting API zurück, die zu CSS Houdini gehört. Mit CSS.paintWorklet.addModule(url) lädt man ein Skript, das über registerPaint(name, klasse) einen eigenen „Painter“ anmeldet. Danach kann man ihn in CSS überall dort mit paint(name) verwenden, wo ein Bild (<image>) erwartet wird, zum Beispiel bei background-image, border-image oder mask-image.

Die paint()-Methode der registrierten Klasse bekommt einen eingeschränkten 2D-Kontext (PaintRenderingContext2D), die Größe des Elements und die Werte der CSS-Eigenschaften, die in static get inputProperties() angegeben sind. So entstehen auflösungsunabhängige Muster, Hintergründe oder Rahmen, die sich automatisch an Größe und Custom Properties anpassen und neu gezeichnet werden, wenn sich diese ändern. Zusätzliche DOM-Knoten oder Canvas-Elemente braucht man dafür nicht.

Das Worklet-Skript läuft in einem eigenen PaintWorkletGlobalScope. Dort gibt es keinen Zugriff auf window, document, Netzwerk-APIs oder Timer. Der Browser kann mehrere Instanzen anlegen und sie jederzeit verwerfen, deshalb sollte paint() keinen Zustand speichern und nur von den übergebenen Eingaben abhängen.

Rückgabewert

Typ
Worklet
Beschreibung
Das Worklet-Objekt für Paint-Worklets. Seine wichtigste Methode ist addModule(moduleURL, options?), die ein Promise<void> zurückgibt.

Beispiele

Paint-Worklet laden, mit Feature-Erkennung

// main.js
if ('paintWorklet' in CSS) {
  CSS.paintWorklet.addModule('/worklets/checkerboard.js')
    .then(() => console.log('Paint-Worklet geladen'))
    .catch((err) => console.error('Laden fehlgeschlagen:', err));
} else {
  // Fallback: statisches Hintergrundbild verwenden
  document.documentElement.classList.add('no-paint-api');
}
Paint-Worklet geladen

Worklet-Modul: Schachbrettmuster mit Custom Property

// /worklets/checkerboard.js (läuft im PaintWorkletGlobalScope)
class Checkerboard {
  static get inputProperties() {
    return ['--checker-size', '--checker-color'];
  }

  paint(ctx, size, props) {
    const cell = parseInt(props.get('--checker-size').toString(), 10) || 16;
    ctx.fillStyle = props.get('--checker-color').toString().trim() || '#ccc';
    for (let y = 0; y < size.height / cell; y++) {
      for (let x = 0; x < size.width / cell; x++) {
        if ((x + y) % 2 === 0) ctx.fillRect(x * cell, y * cell, cell, cell);
      }
    }
  }
}

registerPaint('checkerboard', Checkerboard);

Einsatz in CSS und Steuerung per JavaScript

// CSS (z. B. in styles.css):
// .card {
//   --checker-size: 20;
//   --checker-color: #e0e7ff;
//   background-image: url('fallback.png');
//   background-image: paint(checkerboard);
// }

const start = async () => {
  await CSS.paintWorklet.addModule('/worklets/checkerboard.js');
  const card = document.querySelector('.card');
  // Wenn sich die Custom Property ändert, wird automatisch neu gezeichnet
  card.addEventListener('click', () => {
    card.style.setProperty('--checker-size', '40');
  });
};

start();

Modul aus einem Blob laden (ohne eigene Datei)

const code = `
  registerPaint('diagonal', class {
    paint(ctx, { width, height }) {
      ctx.strokeStyle = 'tomato';
      ctx.lineWidth = 4;
      ctx.beginPath();
      ctx.moveTo(0, height);
      ctx.lineTo(width, 0);
      ctx.stroke();
    }
  });
`;
const url = URL.createObjectURL(new Blob([code], { type: 'text/javascript' }));
await CSS.paintWorklet.addModule(url);
document.body.style.backgroundImage = 'paint(diagonal)';

// Wichtig · Fallstricke

  • Browser-Unterstützung: Nur Chromium-basierte Browser (Chrome, Edge, Opera, ab etwa Version 65). Firefox und Safari unterstützen die API nicht. Prüfe deshalb immer mit 'paintWorklet' in CSS und gib in CSS vorher einen Fallback an, etwa eine zweite background-image-Deklaration vor paint().
  • Sicherer Kontext: Worklets gibt es nur über HTTPS oder localhost. Das Modul wird nach CORS-Regeln geladen, fremde Ursprünge brauchen also passende Header. Bei einer strengen CSP müssen script-src bzw. worker-src die Worklet-URL (oder blob:) erlauben.
  • Eingeschränkter Kontext: PaintRenderingContext2D hat keine Text-Methoden (fillText usw.) und kein getImageData. Im Worklet gibt es weder DOM noch fetch noch setTimeout.
  • Kein Zustand: Der Browser kann Painter-Instanzen beliebig anlegen und verwerfen. Werte, die in Instanzvariablen zwischen paint()-Aufrufen gespeichert werden, sind nicht verlässlich.
  • Wert der Eigenschaften: Nicht registrierte Custom Properties kommen als CSSUnparsedValue an. Für typisierte Werte (z. B. CSSUnitValue) und flüssige Animationen registriert man sie mit CSS.registerProperty() oder @property.
  • addModule() mit derselben URL lädt das Modul nicht erneut. Wird ein Name doppelt mit registerPaint registriert, löst das einen Fehler aus.