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

CanvasRenderingContext2D.clip()

Methode

Macht den aktuellen oder einen übergebenen <code>Path2D</code>-Pfad zur Abschneideregion: Danach wird nur noch innerhalb dieser Fläche gezeichnet.

seit JavaScript Baseline: alle Browser (Path2D-Variante seit ca. 2 Kategorie: webapi

Signatur

CanvasRenderingContext2D.prototype.clip(path?, fillRule?)

Beschreibung

clip() verwandelt den aktuellen Pfad des Kontexts – oder einen übergebenen Path2D-Pfad – in eine Abschneideregion (engl. clipping region). Alle nachfolgenden Zeichenoperationen (fill(), stroke(), drawImage(), fillText() …) wirken nur noch auf Pixel innerhalb dieser Region; alles außerhalb bleibt unverändert.

Typische Einsatzfälle sind runde Avatare aus rechteckigen Bildern, Masken für Text oder Bilder, das Begrenzen von Diagramm-Inhalten auf einen Plotbereich oder Spotlight-/Taschenlampen-Effekte in Spielen.

Wichtig: Eine neue Abschneideregion wird mit der bestehenden geschnitten (Schnittmenge) – sie kann also nur kleiner werden. Es gibt keine Methode, um eine Abschneideregion direkt zu entfernen. Deshalb klammert man clip() praktisch immer mit save() und restore() ein: restore() stellt die vorherige Region wieder her, da sie Teil des Zeichenzustands ist.

Mit dem Parameter fillRule legt man fest, wie bei sich überschneidenden oder verschachtelten Teilpfaden „innen“ bestimmt wird – "nonzero" (Standard) oder "evenodd", womit sich z. B. Löcher (Ringformen) erzeugen lassen.

Parameter

Name Typ Default Beschreibung
$path Path2D Optionaler Path2D-Pfad, der als Abschneideregion dienen soll. Fehlt er, wird der aktuelle Pfad des Kontexts verwendet.
$fillRule "nonzero" | "evenodd" "nonzero" Füllregel, die bestimmt, ob ein Punkt innerhalb des Pfads liegt. "evenodd" eignet sich für Formen mit Löchern.

Beispiele

Runder Avatar aus einem rechteckigen Bild

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

const img = new Image();
img.src = 'avatar.jpg';
img.addEventListener('load', () => {
  const size = 128;
  ctx.save();
  ctx.beginPath();
  ctx.arc(size / 2, size / 2, size / 2, 0, Math.PI * 2);
  ctx.clip(); // nur noch innerhalb des Kreises zeichnen
  ctx.drawImage(img, 0, 0, size, size);
  ctx.restore(); // Abschneideregion wieder aufheben

  // Rahmen außerhalb der Clip-Region zeichnen
  ctx.beginPath();
  ctx.arc(size / 2, size / 2, size / 2 - 1, 0, Math.PI * 2);
  ctx.strokeStyle = '#333';
  ctx.stroke();
});

Diagramminhalt auf den Plotbereich begrenzen (Path2D)

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

const plotArea = new Path2D();
plotArea.rect(40, 20, 300, 200);

ctx.save();
ctx.clip(plotArea);

// Die Linie ragt rechts über den Plotbereich hinaus – wird aber abgeschnitten
ctx.beginPath();
ctx.moveTo(40, 200);
ctx.lineTo(200, 60);
ctx.lineTo(420, 120);
ctx.strokeStyle = 'crimson';
ctx.lineWidth = 3;
ctx.stroke();

ctx.restore();
ctx.strokeRect(40, 20, 300, 200); // Achsenrahmen

Ringförmige Maske mit fillRule "evenodd"

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

const ring = new Path2D();
ring.arc(150, 150, 100, 0, Math.PI * 2); // äußerer Kreis
ring.arc(150, 150, 50, 0, Math.PI * 2);  // innerer Kreis = Loch

ctx.save();
ctx.clip(ring, 'evenodd');

const gradient = ctx.createLinearGradient(0, 0, 300, 300);
gradient.addColorStop(0, 'gold');
gradient.addColorStop(1, 'purple');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 300, 300);

ctx.restore();

// Wichtig · Fallstricke

  • Kein „unclip“: Eine Abschneideregion lässt sich nicht direkt entfernen. Immer vorher save() und danach restore() aufrufen – sonst sind alle späteren Zeichnungen dauerhaft beschnitten.
  • Verschachtelte Aufrufe schneiden sich: Mehrere clip()-Aufrufe ergeben die Schnittmenge der Regionen, niemals eine Vereinigung.
  • beginPath() nicht vergessen: Ohne beginPath() fließen ältere Teilpfade mit in die Abschneideregion ein. Nach clip() bleibt der aktuelle Pfad bestehen, d. h. ein anschließendes stroke() zeichnet ihn – ebenfalls beschnitten, weshalb nur die innere Hälfte der Linie sichtbar ist.
  • clearRect() wird ebenfalls durch die Abschneideregion begrenzt – zum vollständigen Löschen vorher restore() aufrufen oder die Canvas-Größe neu setzen.
  • Kanten der Abschneideregion werden je nach Browser unterschiedlich geglättet (Antialiasing); bei harten Pixelkanten ggf. auf ganzzahlige Koordinaten achten.
  • Kompatibilität: clip() ohne Argumente funktioniert in allen Browsern; die Varianten mit Path2D und fillRule in allen modernen Browsern (nicht im Internet Explorer). Auch in OffscreenCanvasRenderingContext2D verfügbar.