CanvasRenderingContext2D: arcTo() Methode

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

Die CanvasRenderingContext2D.arcTo() Methode der Canvas 2D API fügt dem aktuellen Sub-Pfad einen kreisförmigen Bogen hinzu, indem die angegebenen Kontrollpunkte und der Radius verwendet werden. Der Bogen wird automatisch mit einer geraden Linie an den neuesten Punkt des Pfads angeschlossen, falls erforderlich, zum Beispiel wenn die Startpunkte und die Kontrollpunkte auf einer Linie liegen.

Diese Methode wird häufig verwendet, um abgerundete Ecken zu erstellen.

Hinweis: Sie können unerwartete Ergebnisse erhalten, wenn Sie einen relativ großen Radius verwenden: Die Verbindungslinie des Bogens wird in jede Richtung verlaufen müssen, um den angegebenen Radius zu erreichen.

Syntax

js
arcTo(x1, y1, x2, y2, radius)

Parameter

x1

Die x-Achsen-Koordinate des ersten Kontrollpunktes.

y1

Die y-Achsen-Koordinate des ersten Kontrollpunktes.

x2

Die x-Achsen-Koordinate des zweiten Kontrollpunktes.

y2

Die y-Achsen-Koordinate des zweiten Kontrollpunktes.

radius

Der Radius des Bogens. Muss nicht negativ sein.

Anwendungshinweise

Angenommen, P0 ist der Punkt auf dem Pfad, wenn arcTo() aufgerufen wird, P1 = (x1, y1) und P2 = (x2, y2) sind die ersten und zweiten Kontrollpunkte, und r ist der im Aufruf angegebene radius:

  • Wenn r negativ ist, wird ein IndexSizeError Ausnahme ausgelöst.
  • Wenn r 0 ist, verhält sich arcTo() so, als ob P0, P1 und P2 kollinear sind (auf einer Linie liegen).
  • Im Falle, dass alle Punkte kollinear sind, wird eine Linie von P0 zu P1 gezeichnet, es sei denn, die Punkte P0 und P1 sind gleich (haben die gleichen Koordinaten), in diesem Fall wird nichts gezeichnet.

Diese Bedingungen können im untenstehenden Beispiel Erstellen eines arcTo() Pfads erstellt werden, um die Ergebnisse zu sehen.

Rückgabewert

Keiner (undefined).

Ausnahmen

IndexSizeError DOMException

Wird ausgelöst, wenn radius einen negativen Wert hat.

Beispiele

Funktionsweise von arcTo()

Eine Möglichkeit, arcTo() zu betrachten, besteht darin, sich zwei gerade Segmente vorzustellen: eines vom Startpunkt zu einem ersten Kontrollpunkt und ein weiteres von dort zu einem zweiten Kontrollpunkt. Ohne arcTo() würden diese beiden Segmente eine scharfe Ecke bilden: arcTo() erzeugt einen kreisförmigen Bogen an dieser Ecke und glättet sie. Mit anderen Worten, der Bogen ist tangential zu beiden Segmenten.

HTML

html
<canvas id="canvas"></canvas>

JavaScript

js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// Tangential lines
ctx.beginPath();
ctx.strokeStyle = "gray";
ctx.moveTo(200, 20);
ctx.lineTo(200, 130);
ctx.lineTo(50, 20);
ctx.stroke();

// Arc
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 5;
ctx.moveTo(200, 20);
ctx.arcTo(200, 130, 50, 20, 40);
ctx.stroke();

// Start point
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.arc(200, 20, 5, 0, 2 * Math.PI);
ctx.fill();

// Control points
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(200, 130, 5, 0, 2 * Math.PI); // Control point one
ctx.arc(50, 20, 5, 0, 2 * Math.PI); // Control point two
ctx.fill();

Ergebnis

In diesem Beispiel ist der vom arcTo() erstellte Pfad dick und schwarz. Tangentenlinien sind grau, Kontrollpunkte sind rot, und der Startpunkt ist blau.

Erstellung einer abgerundeten Ecke

Dieses Beispiel erstellt eine abgerundete Ecke mit arcTo(). Dies ist eine der häufigsten Anwendungen der Methode.

HTML

html
<canvas id="canvas"></canvas>

JavaScript

Der Bogen beginnt am Punkt, der durch moveTo() angegeben wird: (230, 20). Er ist so geformt, dass er zu Kontrollpunkten bei (90, 130) und (20, 20) passt und hat einen Radius von 50. Die lineTo() Methode verbindet den Bogen mit (20, 20) mit einer geraden Linie. Beachten Sie, dass der zweite Kontrollpunkt des Bogens und der durch lineTo() angegebene Punkt identisch sind, was zu einer völlig glatten Ecke führt.

js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const p0 = { x: 230, y: 20 };
const p1 = { x: 90, y: 130 };
const p2 = { x: 20, y: 20 };

const labelPoint = (p) => {
  const offset = 10;
  ctx.fillText(`(${p.x},${p.y})`, p.x + offset, p.y + offset);
};

ctx.beginPath();
ctx.lineWidth = 4;
ctx.font = "1em sans-serif";
ctx.moveTo(p0.x, p0.y);
ctx.arcTo(p1.x, p1.y, p2.x, p2.y, 50);
ctx.lineTo(p2.x, p2.y);

labelPoint(p0);
labelPoint(p1);
labelPoint(p2);

ctx.stroke();

Ergebnis

Ergebnis eines großen Radius

Wenn Sie einen relativ großen Radius verwenden, kann der Bogen an einer Stelle erscheinen, die Sie nicht erwartet haben. In diesem Beispiel verläuft die Verbindungslinie des Bogens oberhalb, anstatt unterhalb, der durch moveTo() angegebenen Koordinate. Dies geschieht, weil der Radius zu groß ist, um vollständig unterhalb des Startpunkts zu passen.

HTML

html
<canvas id="canvas"></canvas>

JavaScript

js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.moveTo(180, 90);
ctx.arcTo(180, 130, 110, 130, 130);
ctx.lineTo(110, 130);
ctx.stroke();

Ergebnis

Erstellung eines arcTo() Pfads

Das Demo zeigt die halb-unendlichen Linien und den Kreis mit dem Zentrum C, der tangential zu den Linien bei T1 und T2 verläuft, die zur Bestimmung des vom arcTo() gerenderten Pfades verwendet werden.

Beachten Sie, dass arcTo eine gerade Linie von P0 nach P1 erstellt, wenn alle Punkte auf einer Linie sind. Außerdem wird nichts von arcTo gezeichnet, wenn P0 und P1 die gleichen Koordinaten haben.

Neben der Möglichkeit, den Bogenradius mit dem Schieberegler einzustellen, können der initiale Punkt P0 und die Kontrollpunkte P1 und P2 durch Ziehen mit der Maus bei gedrückter linker Taste bewegt werden. Die numerischen Werte können ebenfalls bearbeitet werden, und die Pfeiltasten können verwendet werden, um ein unterstrichenes Element zu ändern, das im Fokus steht.

Animation des arcTo() Zeichnens

In diesem Beispiel können Sie mit dem Bogenradius spielen, um zu sehen, wie sich der Pfad ändert. Der Pfad wird vom Startpunkt p0 aus unter Verwendung von arcTo() mit den Kontrollpunkten p1 und p2 gezeichnet und einem Radius, der von 0 bis zum maximalen Radius variiert, der mit dem Schieberegler ausgewählt wird. Dann wird ein lineTo() Aufruf den Pfad zu p2 vervollständigen.

HTML

html
<div>
  <label for="radius">Radius: </label>
  <input name="radius" type="range" id="radius" min="0" max="100" value="50" />
  <label for="radius" id="radius-output">50</label>
</div>
<canvas id="canvas"></canvas>

JavaScript

js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const controlOut = document.getElementById("radius-output");
const control = document.getElementById("radius");
control.oninput = () => {
  controlOut.textContent = radius = control.value;
};

const p1 = { x: 100, y: 100 };
const p2 = { x: 150, y: 50 };
const p3 = { x: 200, y: 100 };
let radius = control.value; // match with init control value

function labelPoint(p, offset, i = 0) {
  const { x, y } = offset;
  ctx.beginPath();
  ctx.arc(p.x, p.y, 2, 0, Math.PI * 2);
  ctx.fill();
  ctx.fillText(`${i}:(${p.x}, ${p.y})`, p.x + x, p.y + y);
}

function drawPoints(points) {
  points.forEach((p, i) => {
    labelPoint(p, { x: 0, y: -20 }, `p${i}`);
  });
}

// Draw arc
function drawArc([p0, p1, p2], r) {
  ctx.beginPath();
  ctx.moveTo(p0.x, p0.y);
  ctx.arcTo(p1.x, p1.y, p2.x, p2.y, r);
  ctx.lineTo(p2.x, p2.y);
  ctx.stroke();
}

function loop(t) {
  const angle = (t / 1000) % (2 * Math.PI);
  const rr = Math.abs(Math.cos(angle) * radius);

  ctx.clearRect(0, 0, canvas.width, canvas.height);

  drawArc([p1, p2, p3], rr);
  drawPoints([p1, p2, p3]);
  requestAnimationFrame(loop);
}

loop(0);

Ergebnis

Spezifikationen

Specification
HTML
# dom-context-2d-arcto-dev

Browser-Kompatibilität

Siehe auch