CanvasRenderingContext2D: метод arcTo()
Базовая линия Широко доступна
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна во всех браузерах с июля 2015 года.
Метод CanvasRenderingContext2D.arcTo() API Canvas 2D добавляет дугу окружности к текущей подтраектории, используя заданные точки управления и радиус. Дуга автоматически подключается к последней точке траектории прямой линией, если это необходимо, например, если начальная точка и точки управления находятся на одной прямой.
Этот метод обычно используется для создания закруглённых углов.
Примечание: При использовании относительно большого радиуса вы можете получить неожиданные результаты: соединительная линия дуги будет направлена в нужном направлении, чтобы соответствовать заданному радиусу.
Синтаксис
arcTo(x1, y1, x2, y2, radius)
Параметры
x1-
Координата x первой точки управления.
y1-
Координата y первой точки управления.
x2-
Координата x второй точки управления.
y2-
Координата y второй точки управления.
radius-
Радиус дуги. Должен быть неотрицательным.
Примечания по использованию
Предположим, что P0 — это точка на траектории, когда вызывается arcTo(), P1 = (x1, y1) и P2 = (x2, y2) — это первая и вторая точки управления соответственно, а r — это radius заданный в вызове:
- Если r отрицательно, возникает
IndexSizeErrorисключение. - Если r равно 0,
arcTo()ведёт себя так, как если бы P0, P1 и P2 были коллинеарны (на одной прямой). - В случае, когда все точки коллинеарны, рисуется линия от P0 до P1, если только точки P0 и P1 не совпадают, в этом случае ничего не рисуется.
Эти условия могут быть созданы в примере Создание траектории с помощью arcTo() ниже, чтобы увидеть результаты.
Возвращаемое значение
None (undefined).
Исключения
-
IndexSizeErrorDOMException -
Выбрасывается, если
radiusимеет отрицательное значение.
Примеры
Как работает arcTo()
Один из способов понять arcTo() — представить две прямые: одну от начальной точки до первой точки управления, а другую — от этой точки до второй точки управления. Без arcTo(), эти две отрезки образовали бы острый угол: arcTo() создаёт дугу окружности в этом углу и сглаживает его. Другими словами, дуга касается обеих отрезков.
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();
Результат
В этом примере траектория, созданная с помощью arcTo() — толстая и чёрная. Касательные линии серые, точки управления красные, а начальная точка — синяя.
Создание закруглённого угла
В этом примере создается угол с закругленными углами с помощью arcTo(). Это одно из наиболее распространённых применений метода.
HTML
<canvas id="canvas"></canvas>
JavaScript
Дуга начинается в точке, указанной moveTo(): (230, 20). Она формируется, чтобы соответствовать контрольным точкам в (90, 130) и (20, 20), и имеет радиус 50. Метод lineTo() соединяет дугу с (20, 20) прямой линией. Обратите внимание, что вторая контрольная точка дуги и точка, указанная lineTo(), совпадают, что создаёт полностью плавный угол.
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();
Результат
Результат с большим радиусом
Если вы используете относительно большой радиус, дуга может появиться в неожиданном месте. В этом примере соединяющая линия дуги проходит над, а не под, координатой, указанной moveTo(). Это происходит потому, что радиус слишком велик для того, чтобы дуга полностью поместилась под начальной точкой.
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();
Результат
Создание пути arcTo()
Демонстрация показывает полубесконечные линии и окружность с центром C, касающиеся линий в T1 и T2, используемых для определения пути, отрисованного с помощью arcTo().
Обратите внимание, что arcTo создаст прямую линию от P0 до P1, когда все точки находятся на одной линии. Кроме того, ничего не рисуется arcTo если P0 и P1 имеют одинаковые координаты.
Помимо возможности задать радиус дуги с помощью ползунка, начальную точку P0 и контрольные точки P1 и P2 можно переместить, удерживая нажатой левую кнопку мыши. Также можно редактировать числовые значения, а стрелки на клавиатуре можно использовать для изменения подчёркнутого элемента, который находится в фокусе.
Анимация отрисовки arcTo()
В этом примере вы можете поэкспериментировать с радиусом дуги, чтобы увидеть, как изменяется путь. Путь рисуется от начальной точки p0 с помощью arcTo() с контрольными точками p1 и p2 и радиусом, изменяющимся от 0 до максимального радиуса, выбранного ползунком. Затем вызов lineTo() завершает путь до p2.
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");
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);
Результат
Спецификации
| Спецификация |
|---|
| HTML # dom-context-2d-arcto-dev |
Совместимость с браузерами
| Рабочие столы | Мобильные устройства | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | |
arcTo |
1 | 12 | 1.5 | 11.6 | 2 | 18 | 4 | 12 | 1 | 1.0 | 4.4 |
См. также
- Интерфейс, определяющий этот метод:
CanvasRenderingContext2D
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arcTo