Signatur
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
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]);
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;
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);
// Wichtig · Fallstricke
- preventDefault() wirkt umgekehrt zu WebGL: Beim 2D-Kontext verhindert
preventDefault()die Wiederherstellung. Beiwebglcontextlostist es dagegen die Voraussetzung für eine Wiederherstellung. - Gilt nur für den 2D-Kontext: WebGL-Kontexte auf einem
OffscreenCanvaslösen stattdessenwebglcontextlostundwebglcontextrestoredaus. - 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.prototypeund sieh eine Ersatzlösung vor, etwa regelmäßige Prüfungen mitctx.isContextLost(). - Das Ereignis wird im Thread ausgelöst, dem das Canvas gehört. Nach
transferControlToOffscreen()ist das der Worker, nicht der Hauptthread.