0

I am trying to create an arc function for CanvasRenderingContext2D that will allow the user to specify a horizontal and vertical radius (x and y radius). This is what I have so far:

function arc(x, y, w, h, start, stop) {
  ctx.save();
  ctx.translate(x, y);
  if (w !== h) {
    const m = w < h ? w : h;
    if(m === w) {
      ctx.scale(1, Math.min(w, h) / Math.max(w, h));
    } else {
    ctx.scale(Math.min(w, h) / Math.max(w, h), 1);
    }
  }
  ctx.beginPath();
  ctx.arc(0, 0, Math.min(w, h) / 2, start, stop);
  ctx.restore();
  ctx.fill();
  ctx.stroke();
}

I would for the arc to have the same width and height as specified by the function arguments.

Polar
  • 11
  • 1
  • 2
  • You can use `ctx.ellipse` which takes a x, and y radius. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse for full usage details. – Blindman67 Aug 06 '22 at 21:55

2 Answers2

0

I have found a solution. Apologies for answering my own question.

function arc(x, y, w, h, start, stop) {
          ctx.save();
          ctx.translate(x, y);
            if (w !== h) {
              if(w > h) {
                ctx.scale(Math.max(w, h) / Math.min(w, h), 1);
              } else {
                ctx.scale(1, Math.max(w, h) / Math.min(w, h));
              }
            }
            ctx.beginPath();
            ctx.arc(0, 0, Math.min(w, h) / 2, start, stop);
            ctx.restore();
          ctx.fill();
          ctx.stroke();
        }

Essentially, I just change which direction I scale depending on which side is bigger.

Polar
  • 11
  • 1
  • 2
0

There is an ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise) method.

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.lineWidth = 3;
ctx.strokeStyle = "red";
ctx.fillStyle = "green";
arc(150, 80, 130, 80, Math.PI, Math.PI * 2.35);

function arc(x, y, w, h, start, stop) {
  ctx.beginPath();
  // We divide w and h by 2
  // because OP's version didn't took them as radii.
  ctx.ellipse(x, y, w/2, h/2, 0, start, stop);
  ctx.fill();
  ctx.stroke();
}
<canvas></canvas>
Kaiido
  • 123,334
  • 13
  • 219
  • 285