Start · Sprachen · JavaScript · Referenz · CanvasRenderingContext2D.restore()

CanvasRenderingContext2D.restore()

Methode

Stellt den zuletzt mit <code>save()</code> gesicherten Zeichenzustand wieder her, indem der oberste Eintrag vom Zustands-Stack des Canvas entfernt wird.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

CanvasRenderingContext2D.prototype.restore()

Beschreibung

restore() ist das Gegenstück zu save(). Der 2D-Kontext verwaltet intern einen Stapel (Stack) von Zeichenzuständen. Jeder Aufruf von save() legt den aktuellen Zustand oben auf den Stapel. restore() nimmt den obersten Eintrag wieder herunter und setzt alle gespeicherten Einstellungen auf diese Werte zurück.

Zum gespeicherten Zustand gehören unter anderem:

  • die aktuelle Transformationsmatrix (translate(), rotate(), scale(), setTransform())
  • der aktuelle Clipping-Bereich (clip())
  • die Strichmuster-Liste (setLineDash())
  • Eigenschaften wie fillStyle, strokeStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled und filter

Nicht Teil des Zustands sind der aktuelle Pfad und die bereits gezeichneten Pixel. restore() macht also keine Zeichenoperation rückgängig, sondern setzt nur die Einstellungen zurück, die für künftige Operationen gelten.

Typischerweise umschließt man mit save()/restore() einen abgegrenzten Zeichenblock, etwa ein gedrehtes Element, eine Beschneidung oder einen Schatteneffekt. So bleibt der übrige Code unbeeinflusst und man muss nicht jede Eigenschaft einzeln zurücksetzen.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined).

Beispiele

Grundprinzip: Farbe temporär ändern

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

ctx.fillStyle = 'steelblue';
ctx.save();              // Zustand mit Blau sichern

ctx.fillStyle = 'crimson';
ctx.fillRect(10, 10, 80, 80);  // rotes Quadrat

ctx.restore();           // zurück zu Blau
ctx.fillRect(110, 10, 80, 80); // blaues Quadrat

console.log(ctx.fillStyle);
#4682b4

Gedrehtes Element zeichnen, ohne die Transformation zu vererben

const ctx = document.querySelector('canvas').getContext('2d');

const drawRotatedBox = (x, y, size, angleDeg) => {
  ctx.save();
  ctx.translate(x + size / 2, y + size / 2); // Ursprung in die Mitte
  ctx.rotate((angleDeg * Math.PI) / 180);
  ctx.fillStyle = 'orange';
  ctx.fillRect(-size / 2, -size / 2, size, size);
  ctx.restore(); // Transformation und Farbe wieder zurücksetzen
};

drawRotatedBox(20, 20, 60, 45);
drawRotatedBox(120, 20, 60, 15);

// Die Matrix ist wieder die Einheitsmatrix
console.log(ctx.getTransform().isIdentity);
true

Verschachtelte Zustände und Clipping aufheben

const ctx = document.querySelector('canvas').getContext('2d');

ctx.save();                        // Ebene 1
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI * 2);
ctx.clip();                        // nur innerhalb des Kreises zeichnen

ctx.save();                        // Ebene 2
ctx.globalAlpha = 0.5;
ctx.fillStyle = 'green';
ctx.fillRect(0, 0, 200, 200);      // halbtransparent, im Kreis beschnitten
ctx.restore();                     // globalAlpha wieder 1, Clip bleibt

ctx.strokeStyle = 'black';
ctx.strokeRect(60, 60, 80, 80);    // weiterhin beschnitten
ctx.restore();                     // Clipping aufgehoben

ctx.fillStyle = 'purple';
ctx.fillRect(160, 160, 40, 40);    // vollständig sichtbar
console.log(ctx.globalAlpha);
1

// Wichtig · Fallstricke

  • Leerer Stapel: Wird restore() ohne vorheriges save() aufgerufen, passiert einfach nichts. Es gibt keinen Fehler. Dadurch fallen unausgeglichene Aufrufe leicht nicht auf, deshalb sollten save() und restore() immer paarweise stehen.
  • Pfad wird nicht gesichert: Der aktuelle Pfad bleibt nach restore() erhalten. Vor neuen Formen deshalb weiterhin beginPath() aufrufen.
  • Clipping lässt sich nur so aufheben: Einen mit clip() gesetzten Bereich kann man nicht direkt entfernen. Nur restore() zu einem vorher gesicherten Zustand (oder reset()) hebt ihn auf.
  • Leistung: In Animationsschleifen mit sehr vielen Objekten verursachen save()/restore() einen messbaren Mehraufwand. Wer nur die Transformation zurücksetzen muss, ist mit setTransform(1, 0, 0, 1, 0, 0) oft schneller.
  • Fehler in der Zeichenlogik: Wirft der Code zwischen save() und restore() eine Ausnahme, bleibt der Stapel unausgeglichen. Mit try { … } finally { ctx.restore(); } lässt sich das absichern.
  • Die Methode steht auch in OffscreenCanvasRenderingContext2D zur Verfügung, also auch in Web Workern. Browser-Unterstützung: alle modernen Browser, auch sehr alte Versionen.