Так что получается, что .arc()
буквально создает угловой путь из предоставленных вами координат x и y.Что вам нужно сделать, это:
- переместите «указатель рисования» туда, куда вы хотите поместить круг
- сделайте «путь» из той позиции, которая является центром вашегоокружность
- нарисуйте реальную круговую дугу
- вернитесь к своему кругу, чтобы закрыть этот путь.
Следующий код иллюстрирует рабочий пример этого:
const WIDTH = 100;
const HEIGHT = 100;
const RADIUS = 50;
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = WIDTH;
canvas.height = HEIGHT;
document.body.appendChild(canvas);
// identify center of your circle for learning purposes
// let's use the center of the canvas:
const [dx, dy] = [WIDTH / 2, HEIGHT / 2];
context.fillStyle = 'orange';
context.fillRect(dx, dy, 5, 5);
// clean / begin your paths
context.beginPath();
// move to (and start your path to) your position:
context.moveTo(dx, dy);
// create a circle using the dx,dy as the center of the circle:
const startAngleInRadians = 0;
const endAngleInRadians = Math.PI * 0.5;
const goAntiClockwise = false;
context.arc(dx, dy, RADIUS, startAngleInRadians, endAngleInRadians, goAntiClockwise);
// move back to your position (not required if you only draw 1 pie since your paths dont change):
context.moveTo(dx, dy);
// let's fill our pie with a pink color!:
context.fillStyle = '#FF00FF55';
context.fill();
Чтобы проиллюстрировать, что на самом деле происходит, я сделал простую анимацию холста:
const WIDTH = 200;
const HEIGHT = 200;
const RADIUS = 50;
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const [dx, dy] = [0, 0];
canvas.width = WIDTH;
canvas.height = HEIGHT;
document.body.appendChild(canvas);
context.strokeStyle = 'red';
function sleep(timeout) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, timeout);
});
}
async function showHowItWorks() {
// move from arc center to the arc start position:
for (let i=0; i<RADIUS; i++) {
context.beginPath();
context.moveTo(dx, dy);
context.lineTo(dx + i, dy);
context.stroke();
await sleep(50);
}
// draw the arc from start position to arc end:
const angle = Math.PI * 0.5;
for (let i=0; i<angle; i+=0.05) {
context.beginPath();
context.arc(dx, dy, RADIUS, 0, i, false);
context.stroke();
await sleep(50);
}
// move from arc end back to the arc center:
for (let i=50; i>=0; i--) {
context.moveTo(dx, dy + RADIUS);
context.lineTo(dx, dy + i);
context.stroke();
await sleep(50);
}
}
showHowItWorks();
Конечно, есть некоторые недостатки: я не уверен, что команда .arc()
перемещает «указатель рисования», как .moveTo()
- или рисует из позициик дугообразному .lineTo()
-.
В первом случае указатель переходит с вашей центральной позиции на дугу.Во втором случае он фактически создает линию от вашего центра к дуге.Но в любом случае оба способа в большинстве случаев дадут один и тот же конечный результат.