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

CanvasRenderingContext2D.arcTo()

Methode

Fügt dem aktuellen Sub-Pfad einen Kreisbogen mit dem angegebenen Radius hinzu, der tangential an zwei Linien anliegt, die durch zwei Kontrollpunkte bestimmt sind.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

CanvasRenderingContext2D.prototype.arcTo(x1, y1, x2, y2, radius)

Beschreibung

arcTo() erzeugt einen Kreisbogen, der tangential an zwei gedachte Geraden anschließt: Die erste führt vom aktuellen Punkt des Pfades zum ersten Kontrollpunkt (x1, y1), die zweite vom ersten zum zweiten Kontrollpunkt (x2, y2). Der Bogen liegt in der „Ecke“ am ersten Kontrollpunkt und wird mit dem angegebenen radius abgerundet.

Die Methode eignet sich vor allem für abgerundete Ecken, etwa bei Rechtecken, Sprechblasen, Buttons oder Polygonen mit weichen Übergängen. Anders als bei arc() gibt man hier keinen Mittelpunkt und keine Winkel an, sondern beschreibt die Ecke direkt über Punkte. Das macht die Methode für Pfade aus Linienzügen deutlich intuitiver.

Liegt der aktuelle Punkt nicht am Anfang des Bogens, zieht arcTo() automatisch eine gerade Linie vom aktuellen Punkt bis zum Tangentenpunkt. Nach dem Aufruf ist der aktuelle Punkt das Ende des Bogens, nicht (x2, y2). Wer bis zum zweiten Kontrollpunkt weiterzeichnen will, muss also zusätzlich lineTo(x2, y2) aufrufen.

Die Methode zeichnet nichts sichtbar. Der Pfad erscheint erst mit stroke() oder fill().

Parameter

Name Typ Default Beschreibung
$x1 Pflicht number x-Koordinate des ersten Kontrollpunkts (die Ecke, die abgerundet wird).
$y1 Pflicht number y-Koordinate des ersten Kontrollpunkts.
$x2 Pflicht number x-Koordinate des zweiten Kontrollpunkts. Er legt die Richtung der zweiten Tangente fest.
$y2 Pflicht number y-Koordinate des zweiten Kontrollpunkts.
$radius Pflicht number Radius des Bogens. Er muss ≥ 0 sein, sonst wird ein IndexSizeError geworfen.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Die Methode verändert den aktuellen Pfad.

Beispiele

Einfache abgerundete Ecke

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

ctx.beginPath();
ctx.moveTo(20, 20);            // Startpunkt
ctx.arcTo(150, 20, 150, 150, 40); // Ecke bei (150|20) mit Radius 40
ctx.lineTo(150, 150);          // bis zum zweiten Kontrollpunkt weiterzeichnen
ctx.lineWidth = 4;
ctx.stroke();

Wiederverwendbare Funktion für abgerundete Rechtecke

const roundedRect = (ctx, x, y, w, h, r) => {
  // Radius auf die halbe Seitenlänge begrenzen
  const radius = Math.min(r, w / 2, h / 2);
  ctx.beginPath();
  ctx.moveTo(x + radius, y);
  ctx.arcTo(x + w, y, x + w, y + h, radius);
  ctx.arcTo(x + w, y + h, x, y + h, radius);
  ctx.arcTo(x, y + h, x, y, radius);
  ctx.arcTo(x, y, x + w, y, radius);
  ctx.closePath();
};

const ctx = document.querySelector('canvas').getContext('2d');
roundedRect(ctx, 30, 30, 200, 100, 16);
ctx.fillStyle = '#3b82f6';
ctx.fill();
ctx.strokeStyle = '#1e3a8a';
ctx.stroke();

Sprechblase mit Spitze

const ctx = document.querySelector('canvas').getContext('2d');
const [x, y, w, h, r] = [40, 40, 220, 110, 20];

ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.arcTo(x + w, y + h, x, y + h, r);
// Spitze der Sprechblase an der Unterkante
ctx.lineTo(x + 80, y + h);
ctx.lineTo(x + 50, y + h + 30);
ctx.lineTo(x + 55, y + h);
ctx.arcTo(x, y + h, x, y, r);
ctx.arcTo(x, y, x + w, y, r);
ctx.closePath();

ctx.fillStyle = '#fff';
ctx.fill();
ctx.lineWidth = 2;
ctx.stroke();

ctx.fillStyle = '#111';
ctx.font = '18px sans-serif';
ctx.fillText('Hallo Canvas!', x + 30, y + 60);

// Wichtig · Fallstricke

  • Ein negativer Radius wirft einen IndexSizeError (DOMException). Mit radius = 0 entsteht eine scharfe Ecke, also praktisch nur ein lineTo(x1, y1).
  • Gibt es noch keinen aktuellen Punkt (kein moveTo() nach beginPath()), wird implizit moveTo(x1, y1) ausgeführt.
  • Liegen aktueller Punkt, (x1, y1) und (x2, y2) auf einer Geraden, oder fällt der aktuelle Punkt mit (x1, y1) zusammen, wird nur eine gerade Linie bis (x1, y1) gezogen.
  • Ist der Radius größer als die halbe Seitenlänge, ragen die Tangentenpunkte über die Kanten hinaus. Das Ergebnis sieht dann verzerrt aus. Deshalb sollte man den Radius vorher begrenzen, z. B. mit Math.min(r, w / 2, h / 2).
  • Nach dem Aufruf liegt der aktuelle Punkt am Ende des Bogens und nicht bei (x2, y2).
  • Für einfache abgerundete Rechtecke gibt es in modernen Browsern auch ctx.roundRect() (Chrome 99+, Firefox 112+, Safari 16+). arcTo() funktioniert dagegen in allen Browsern und auch in Path2D und OffscreenCanvasRenderingContext2D.