Start · Sprachen · JavaScript · Referenz · OffscreenCanvas: contextlost

OffscreenCanvas: contextlost

Ereignis

Wird an einem <code>OffscreenCanvas</code> ausgelöst, wenn der Browser feststellt, dass dessen <code>OffscreenCanvasRenderingContext2D</code> verloren gegangen ist.

seit JavaScript Eingeschränkt verfügbar: Chromium 99+ (Chrome, Edg Kategorie: webapi

Signatur

offscreenCanvas.addEventListener("contextlost", handler)

Beschreibung

Das contextlost-Ereignis tritt auf, wenn der 2D-Zeichenkontext eines OffscreenCanvas verloren geht. Ursache sind meist Probleme mit der GPU-Beschleunigung, zum Beispiel ein abgestürzter oder zurückgesetzter Grafiktreiber, zu wenig Grafikspeicher oder ein Browser, der Ressourcen im Hintergrund freigibt. Danach sind Inhalt und Zustand des Kontexts (Transformationen, Stile, Pfade) weg, und Zeichenbefehle haben keine Wirkung mehr.

Du kannst das Ereignis mit addEventListener("contextlost", handler) oder über die Eigenschaft offscreenCanvas.oncontextlost abonnieren. Das funktioniert im Hauptthread und in Web Workern gleich. Weil OffscreenCanvas oft in Workern für Rendering im Hintergrund dient, sollte der Listener in der Regel direkt dort registriert werden. Übergeben wird ein einfaches Event-Objekt ohne zusätzliche Eigenschaften.

Das Ereignis ist abbrechbar. Ruft der Handler nichts auf, versucht der Browser, den Kontext später wiederherzustellen. Gelingt das, folgt das Ereignis contextrestored. Mit event.preventDefault() verhinderst du diese Wiederherstellung. Der Kontext bleibt dann dauerhaft verloren. Achtung: Bei WebGL (webglcontextlost) ist das genau umgekehrt.

Typische Aufgaben im Handler: die Render-Schleife anhalten, den Zustand merken, der für das Neuzeichnen nötig ist, und bei contextrestored alles neu zeichnen. Mit ctx.isContextLost() kannst du den Zustand jederzeit prüfen.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "contextlost".
$handler Pflicht (event: Event) => void Wird mit einem einfachen Event aufgerufen (cancelable: true, bubbles: false). Mit event.preventDefault() unterbindest du die automatische Wiederherstellung.
$options boolean | AddEventListenerOptions false Optionen wie once, signal oder passive. Achtung: Mit passive: true wird preventDefault() ignoriert.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein Event-Objekt.

Beispiele

Render-Schleife im Worker pausieren und nach Wiederherstellung neu zeichnen

// worker.js – erhält das OffscreenCanvas vom Hauptthread
let canvas, ctx, frameId = null;
const state = { x: 0 };

const draw = () => {
  ctx.fillStyle = '#222';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = 'tomato';
  ctx.fillRect(state.x, 40, 50, 50);
  state.x = (state.x + 2) % canvas.width;
  frameId = requestAnimationFrame(draw);
};

self.onmessage = ({ data }) => {
  canvas = data.canvas;
  ctx = canvas.getContext('2d');

  canvas.addEventListener('contextlost', () => {
    console.warn('2D-Kontext verloren – Rendering pausiert');
    cancelAnimationFrame(frameId);
  });

  canvas.addEventListener('contextrestored', () => {
    console.log('Kontext wiederhergestellt – zeichne neu');
    draw(); // Stile und Inhalt müssen komplett neu gesetzt werden
  });

  draw();
};

// main.js
// const offscreen = document.querySelector('canvas').transferControlToOffscreen();
// new Worker('worker.js').postMessage({ canvas: offscreen }, [offscreen]);
2D-Kontext verloren – Rendering pausiert Kontext wiederhergestellt – zeichne neu

Handler über die Eigenschaft oncontextlost setzen

const canvas = new OffscreenCanvas(300, 150);
const ctx = canvas.getContext('2d');

canvas.oncontextlost = (event) => {
  console.log('Verloren:', event.type, 'abbrechbar:', event.cancelable);
  console.log('isContextLost():', ctx.isContextLost());
};

// Handler wieder entfernen
// canvas.oncontextlost = null;
Verloren: contextlost abbrechbar: true isContextLost(): true

Wiederherstellung verhindern und Listener wieder entfernen

const canvas = new OffscreenCanvas(512, 512);
const ctx = canvas.getContext('2d');

const onLost = (event) => {
  // Kein automatischer Wiederaufbau – stattdessen neues Canvas anlegen
  event.preventDefault();
  console.log('Kontext aufgegeben, lege neues Canvas an');
  canvas.removeEventListener('contextlost', onLost);
};

canvas.addEventListener('contextlost', onLost);
Kontext aufgegeben, lege neues Canvas an

// Wichtig · Fallstricke

  • preventDefault() wirkt umgekehrt zu WebGL: Beim 2D-Kontext verhindert preventDefault() die Wiederherstellung. Bei webglcontextlost ist es dagegen die Voraussetzung für eine Wiederherstellung.
  • Gilt nur für den 2D-Kontext: WebGL-Kontexte auf einem OffscreenCanvas lösen stattdessen webglcontextlost und webglcontextrestored aus.
  • Zustand geht verloren: Nach der Wiederherstellung ist das Canvas leer und alle Kontext-Einstellungen (fillStyle, font, Transformationen) stehen wieder auf ihren Standardwerten. Die Anwendung muss alles neu zeichnen.
  • Kaum gezielt auslösbar: Anders als bei WebGL (WEBGL_lose_context) gibt es keine Standard-API, um einen Kontextverlust beim 2D-Kontext zu simulieren. Teste solche Fälle zum Beispiel über die Browser-Flags oder Entwicklertools von Chromium.
  • Kompatibilität: Nur in Chromium-Browsern verfügbar (ab Version 99). Prüfe die Unterstützung mit 'oncontextlost' in OffscreenCanvas.prototype und sieh eine Ersatzlösung vor, etwa regelmäßige Prüfungen mit ctx.isContextLost().
  • Das Ereignis wird im Thread ausgelöst, dem das Canvas gehört. Nach transferControlToOffscreen() ist das der Worker, nicht der Hauptthread.