Clip und unClip

April 2023

Ein Rechteck und drei Kreise

Ctx2d.strokeStyle = '#00cc00';
Ctx2d.lineWidth = 5;

Ctx2d.rect(40, 20, 100, 80);
Ctx2d.fillStyle = 'blue';
Ctx2d.fill();

Ctx2d.beginPath()
Ctx2d.arc(40, 20, 15, 0, 2 * Math.PI, false);
Ctx2d.stroke();

Ctx2d.beginPath();
Ctx2d.arc(40, 100, 15, 0, 2 * Math.PI, false);
Ctx2d.stroke();

Ctx2d.beginPath();
Ctx2d.arc(150, 60, 36, 0, 2 * Math.PI, false);
Ctx2d.stroke();
Hier wird zuerst ein blaues Rechteck gezeichnet und danach 3 Kreise. Alle Figuren sind ein eigener Pfad.

Clip-Bereich aktivieren

Es ist möglich, dass Darstellungen maskiert werden können. Das heißt, ein Bereich begrenzt die Abbildung nachfolgender Darstellungen ein. Die Methode clip() des Zeichenkontextes sorgt dafür, dass der Pfad, zu dem clip() gehört, die Maske bildet (clip region). Wir setzen clip() an das Ende des ersten Pfads.
Ctx2d.strokeStyle = '#00cc00';
Ctx2d.lineWidth = 5;

Ctx2d.rect(40, 20, 100, 80);
Ctx2d.fillStyle = 'blue';
Ctx2d.fill();
Ctx2d.clip();

Ctx2d.beginPath()
Ctx2d.arc(40, 20, 15, 0, 2 * Math.PI, false);
Ctx2d.stroke();

Ctx2d.beginPath();
Ctx2d.arc(40, 100, 15, 0, 2 * Math.PI, false);
Ctx2d.stroke();

Ctx2d.beginPath();
Ctx2d.arc(150, 60, 36, 0, 2 * Math.PI, false);
Ctx2d.stroke();
Jetzt wird deutlich, was gemeint ist. Das blaue Rechteck wird zur Clip-Region und alle nachfolgenden Darstellungen sind nur innerhalb dieser Region (Maske) sichtbar.
Die Clip-Region kann ein beliebig geschlossener Pfad sein. Es sind vielfältigere Masken möglich als nur ein Rechteck wie in unseren Versuchen.

Clip-Region rücksetzen

Schön und gut, was aber, wenn wir in nach dem Aufbau einer Maske normal weiterzeichnen wollen, also auch außerhalb des Clip-Bereichs? Leider gibt es eine Methode wie unclip() nicht, aber es gibt eine Lösung.
Die Methode save() speichert fast alle Einstellungen des Zeichenkontextes. An späterer Stelle kann man mit restore() die Einstellungen zurückholen.
Wir nehmen uns vor, dass der letzte Kreis nicht mehr geclipt werden soll. Daher platzieren wir save() an einer Stelle, an der es noch keine Clip-Region gab.
Ctx2d.strokeStyle = '#00cc00';
Ctx2d.lineWidth = 5;
Ctx2d.save();

Ctx2d.rect(40, 20, 100, 80);
Ctx2d.fillStyle = 'blue';
Ctx2d.fill();
Ctx2d.clip();

Ctx2d.beginPath()
Ctx2d.arc(40, 20, 15, 0, 2 * Math.PI, false);
Ctx2d.stroke();

Ctx2d.beginPath();
Ctx2d.arc(40, 100, 15, 0, 2 * Math.PI, false);
Ctx2d.stroke();

Ctx2d.restore();
Ctx2d.beginPath();
Ctx2d.arc(150, 60, 36, 0, 2 * Math.PI, false);
Ctx2d.stroke();
Mit restore() holen wir die früheren Einstellungen zurück und überschreiben damit die aktuellen Einstellungen, auch die Clip-Region. Und so können wir nach einer maskierten Darstellung auf der ganzen Canvas weiterzeichnen.