Start · Sprachen · JavaScript · Referenz · HTMLCanvasElement: contextrestored

HTMLCanvasElement: contextrestored

Ereignis

Wird am <code>&lt;canvas&gt;</code> ausgelöst, wenn der Browser einen verlorenen <code>CanvasRenderingContext2D</code> wiederhergestellt hat. Danach muss der Inhalt neu gezeichnet werden.

seit JavaScript Chromium 99+ (Chrome, Edge, Opera); in Firefox und Kategorie: webapi

Signatur

canvas.addEventListener("contextrestored", handler)

Beschreibung

Das Ereignis contextrestored gehört zum Lebenszyklus eines 2D-Zeichenkontexts. Der Browser kann den Speicher eines CanvasRenderingContext2D freigeben, zum Beispiel wenn die GPU zurückgesetzt wird, der Grafiktreiber abstürzt oder im Hintergrund zu wenig Speicher frei ist. Dann feuert er zuerst contextlost. Sobald ein neuer Speicher bereitsteht, folgt contextrestored.

Wichtig ist: Nach der Wiederherstellung ist der Kontext leer und auf die Standardwerte zurückgesetzt. Die Pixel, Transformationen, fillStyle, lineWidth, Clipping-Bereiche und der Zustandsstapel von save()/restore() sind weg. Deshalb nutzt man das Ereignis, um die ganze Szene aus dem eigenen Anwendungszustand neu zu zeichnen. Das Objekt des Kontexts selbst bleibt dasselbe. Man muss getContext("2d") also nicht noch einmal aufrufen.

Man kann den Handler mit addEventListener("contextrestored", …) oder über die Eigenschaft canvas.oncontextrestored registrieren. Das Ereignis ist ein einfaches Event. Es steigt nicht im DOM auf (kein Bubbling) und lässt sich nicht abbrechen. Dasselbe Ereignis gibt es auch bei OffscreenCanvas.

Für WebGL-Kontexte gilt das nicht. Dort heißen die passenden Ereignisse webglcontextlost und webglcontextrestored.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "contextrestored".
$handler Pflicht (event: Event) => void Die Rückruffunktion. Sie bekommt ein einfaches Event-Objekt. Sein target ist das betroffene HTMLCanvasElement.
$options boolean | AddEventListenerOptions false Optionen wie once, signal oder capture für addEventListener.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Rückgabewert des Handlers wird nicht beachtet.

Beispiele

Szene nach der Wiederherstellung neu zeichnen

const canvas = document.querySelector("#chart");
const ctx = canvas.getContext("2d");

// Der Anwendungszustand liegt außerhalb des Canvas
const bars = [40, 90, 65, 120];

const draw = () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = "#3b82f6"; // Stil muss neu gesetzt werden
  bars.forEach((h, i) => {
    ctx.fillRect(10 + i * 40, canvas.height - h, 30, h);
  });
};

canvas.addEventListener("contextlost", () => {
  console.warn("2D-Kontext verloren – Zeichnen pausiert");
});

canvas.addEventListener("contextrestored", () => {
  console.log("2D-Kontext wiederhergestellt – zeichne neu");
  draw();
});

draw();
2D-Kontext verloren – Zeichnen pausiert 2D-Kontext wiederhergestellt – zeichne neu

Animationsschleife pausieren und fortsetzen (on-Property)

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
let frameId = null;
let x = 0;

const loop = () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = "tomato";
  ctx.fillRect(x, 50, 40, 40);
  x = (x + 2) % canvas.width;
  frameId = requestAnimationFrame(loop);
};

canvas.oncontextlost = () => {
  cancelAnimationFrame(frameId);
  frameId = null;
};

canvas.oncontextrestored = () => {
  if (frameId === null) loop();
};

loop();

Handler mit AbortController wieder entfernen

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const controller = new AbortController();

const onRestored = () => {
  console.log("Verloren?", ctx.isContextLost());
  ctx.fillText("Wiederhergestellt", 10, 20);
};

canvas.addEventListener("contextrestored", onRestored, {
  signal: controller.signal,
});

// Später, z. B. beim Abbauen der Komponente:
controller.abort();
// alternativ: canvas.removeEventListener("contextrestored", onRestored);
Verloren? false

// Wichtig · Fallstricke

  • Der Zustand geht verloren: Nach contextrestored hat der Kontext wieder die Standardwerte. Transformationen, Stile, Schriften und Clip-Bereiche müssen neu gesetzt werden. Halten Sie die Szene deshalb immer im eigenen Anwendungszustand fest, damit Sie sie neu zeichnen können.
  • Die Wiederherstellung lässt sich verhindern: Wenn im Handler für contextlost event.preventDefault() aufgerufen wird, stellt der Browser den Kontext nicht wieder her. Dann feuert auch kein contextrestored.
  • Solange der Kontext verloren ist, haben Zeichenbefehle keine Wirkung. Das können Sie mit ctx.isContextLost() prüfen.
  • Einen Kontextverlust bei 2D-Canvas kann man kaum künstlich herbeiführen. Anders als bei WebGL mit WEBGL_lose_context gibt es dafür keine offizielle Test-API. Legen Sie den Code zum Neuzeichnen deshalb als eigene Funktion an, die Sie auch sonst aufrufen und testen können.
  • Browser-Unterstützung: Chromium-basierte Browser unterstützen das Ereignis ab Version 99. In Firefox und Safari ist die Unterstützung (Stand zuletzt geprüft) fehlend oder unvollständig. Dann feuert das Ereignis nie. Der Code sollte deshalb auch ohne das Ereignis funktionieren.
  • Für WebGL verwenden Sie stattdessen webglcontextlost und webglcontextrestored.