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 Juli 2015.
Die CanvasRenderingContext2D.arcTo() Methode der Canvas 2D API fügt dem aktuellen Sub-Pfad einen Kreisbogen hinzu, unter Verwendung der angegebenen Kontrollpunkte und des Radius.
Der Bogen wird bei Bedarf automatisch mit einer geraden Linie an den neuesten Punkt des Pfades angeschlossen, zum Beispiel, wenn der Startpunkt und die Kontrollpunkte auf einer Linie liegen.
Diese Methode wird häufig verwendet, um abgerundete Ecken zu erzeugen.
Hinweis: Sie könnten unerwartete Ergebnisse erzielen, wenn Sie einen relativ großen Radius verwenden: Die Verbindungslinie des Bogens wird in jede Richtung verlaufen, die erforderlich ist, um den angegebenen Radius zu erreichen.
Syntax
arcTo(x1, y1, x2, y2, radius)
Parameter
x1-
Die x-Achsen-Koordinate des ersten Kontrollpunkts.
y1-
Die y-Achsen-Koordinate des ersten Kontrollpunkts.
x2-
Die x-Achsen-Koordinate des zweiten Kontrollpunkts.
y2-
Die y-Achsen-Koordinate des zweiten Kontrollpunkts.
radius-
Der Radius des Bogens. Muss nicht negativ sein.
Verwendungshinweise
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 in dem Aufruf angegebene radius:
- Wenn r negativ ist, wird ein
IndexSizeErrorAusnahme ausgelöst. - Wenn r 0 ist, verhält sich
arcTo()so, als wären P0, P1 und P2 kollinear (in einer Linie). - Im Falle aller Punkte, die kollinear sind, wird eine Linie von P0 zu P1 gezeichnet, es sei denn, die Punkte P0 und P1 fallen zusammen (haben die gleichen Koordinaten), in diesem Fall wird nichts gezeichnet.
Diese Bedingungen können im untenstehenden Konstruktionsbeispiel eines arcTo() Pfads erstellt werden, um die Ergebnisse zu sehen.
Rückgabewert
Keiner (undefined).
Ausnahmen
IndexSizeErrorDOMException-
Wird ausgelöst, wenn
radiusein negativer Wert ist.
Beispiele
>Wie arcTo() funktioniert
Eine Möglichkeit, arcTo() zu betrachten, ist 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 Kreisbogen an dieser Ecke und glättet ihn aus. Mit anderen Worten, der Bogen ist tangential zu beiden Segmenten.
HTML
<canvas id="canvas"></canvas>
JavaScript
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 durch arcTo() erzeugte Pfad dick und schwarz. Tangentenlinien sind grau, Kontrollpunkte sind rot, und der Startpunkt ist blau.
Eine abgerundete Ecke erstellen
Dieses Beispiel erzeugt eine abgerundete Ecke mit arcTo(). Dies ist eine der häufigsten Verwendungen der Methode.
HTML
<canvas id="canvas"></canvas>
JavaScript
Der Bogen beginnt an dem Punkt, der durch moveTo() angegeben wird: (230, 20). Er ist geformt, um die Kontrollpunkte bei (90, 130) und (20, 20) zu passen 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 Punkt, der durch lineTo() angegeben wird, derselbe sind, was eine vollständig glatte Ecke erzeugt.
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 den Bogen vollständig unterhalb des Startpunkts zu platzieren.
HTML
<canvas id="canvas"></canvas>
JavaScript
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
Konstruktion eines arcTo() Pfads
Die Demo zeigt die halb-unendlichen Linien und den Kreis mit Mittelpunkt C tangential zu den Linien bei T1 und T2, die verwendet werden, um den durch arcTo() dargestellten Pfad zu bestimmen.
Beachten Sie, dass arcTo eine gerade Linie von P0 zu P1 erzeugen wird, wenn alle Punkte in einer Linie sind. Zusätzlich wird durch arcTo nichts gezeichnet, wenn P0 und P1 die gleichen Koordinaten haben.
Neben der Möglichkeit, den Bogenradius mit dem Schieberegler einzustellen, können der Anfangspunkt P0 und die Kontrollpunkte P1 und P2 durch Ziehen mit der gedrückten linken Maustaste bewegt werden. Die numerischen Werte können ebenfalls bearbeitet werden, und die Pfeiltasten können verwendet werden, um ein fokussiertes Element mit Unterstrich zu ändern.
Animation der arcTo() Zeichnung
Für dieses Beispiel können Sie mit dem Bögenradius spielen, um zu sehen, wie sich der Pfad ändert. Der Pfad wird vom Startpunkt p0 mit arcTo() unter Verwendung der Kontrollpunkte p1 und p2 und einem Radius gezeichnet, der von 0 bis zur maximal mit dem Schieberegler gewählten Radius variiert. Dann wird ein lineTo() Aufruf den Pfad zu p2 vervollständigen.
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
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const controlOut = document.getElementById("radius-output");
const control = document.getElementById("radius");
let radius = control.value; // match with init control value
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 };
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
- Das Interface, das diese Methode definiert:
CanvasRenderingContext2D