Есть ли способ изменить CanvasRenderingContext2D.arc, чтобы он отображался как пирог? - PullRequest
0 голосов
/ 15 мая 2019

Я экспериментировал с HTML Canvas в течение нескольких недель и использую .arc для создания кругов, но когда круг неполный, он не выглядит как кусок пирога. Вместо этого он использует кратчайшее возможное расстояние от одного конца до другого и заполняет остальные! Есть ли способ показать его как кусочки пирога? Вот пример использования .arc:

<html>
<head>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(100, 75, 50, 0, 2) //supposedly radians for 2
ctx.stroke();
ctx.fillStyle = "black";
ctx.fill();
</head>
<body>
<canvas id="canvas" width="1000" height="600"></canvas>
</body>
</html>

1 Ответ

0 голосов
/ 17 мая 2019

Так что получается, что .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() -.

В первом случае указатель переходит с вашей центральной позиции на дугу.Во втором случае он фактически создает линию от вашего центра к дуге.Но в любом случае оба способа в большинстве случаев дадут один и тот же конечный результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...