Signatur
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,imageSmoothingEnabledundfilter
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
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);
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);
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);
// Wichtig · Fallstricke
- Leerer Stapel: Wird
restore()ohne vorherigessave()aufgerufen, passiert einfach nichts. Es gibt keinen Fehler. Dadurch fallen unausgeglichene Aufrufe leicht nicht auf, deshalb solltensave()undrestore()immer paarweise stehen. - Pfad wird nicht gesichert: Der aktuelle Pfad bleibt nach
restore()erhalten. Vor neuen Formen deshalb weiterhinbeginPath()aufrufen. - Clipping lässt sich nur so aufheben: Einen mit
clip()gesetzten Bereich kann man nicht direkt entfernen. Nurrestore()zu einem vorher gesicherten Zustand (oderreset()) hebt ihn auf. - Leistung: In Animationsschleifen mit sehr vielen Objekten verursachen
save()/restore()einen messbaren Mehraufwand. Wer nur die Transformation zurücksetzen muss, ist mitsetTransform(1, 0, 0, 1, 0, 0)oft schneller. - Fehler in der Zeichenlogik: Wirft der Code zwischen
save()undrestore()eine Ausnahme, bleibt der Stapel unausgeglichen. Mittry { … } finally { ctx.restore(); }lässt sich das absichern. - Die Methode steht auch in
OffscreenCanvasRenderingContext2Dzur Verfügung, also auch in Web Workern. Browser-Unterstützung: alle modernen Browser, auch sehr alte Versionen.