Quick post today – I thought I would share some tips on drawing rotated partial circles (e.g. quarter-circles, or slices) with HTML Canvas and JavaScript. It is actually slightly harder than one might think, as there are some “gotchas”.
Things to Note
Here are the two things that I ran into that made me pause when trying to do this:
- The Canvas Web API uses radians for angle measurement, not degrees.
- If you are new working with Canvas, this might be easy to miss, as the function arguments are often just named things like
angle
orstartAngle
, not indicating units unless you read through the docs
- If you are new working with Canvas, this might be easy to miss, as the function arguments are often just named things like
- If you are trying to create a filled segment of a circle (a.k.a. a slice), you need to start an explicit path before drawing your arc, and you need to make sure to set the starting point at the arc origin, even though you also pass that origin to the
.arc()
method.- Use
ctx.beginPath()
method to start the path - Use
ctx.moveTo()
method to move “cursor” / starting point, and explicitly start sub-path - Technically, I believe you could just use
moveTo()
withoutbeginPath()
, sincemoveTo()
starts a new sub-path automatically
- Use
Wrapper Function – Quarter Circles
Putting these important pieces together, I created a simle wrapper function that I can call whenever I want to draw a quarter circle:
const drawQuarterCircle = (origin, radius, startAngleDeg = 0) => {
const startAngle = startAngleDeg * (Math.PI / 180);
const endAngle = startAngle + Math.PI * 0.5;
ctx.beginPath();
ctx.moveTo(origin.x, origin.y);
// Draw actual arc
ctx.arc(origin.x, origin.y, radius, startAngle, endAngle, false);
ctx.fill();
}
startAngleDeg
is in normal degrees, to make conceptualizing what you are drawing a little easier.startAngleDeg
is also what controls the rotation of the rendered quarter circle. See demo below for a clear use-case
And here is an embedded demo, showing how to use it to draw rotated quarter circles:
Arbitrary Partial Circles
To draw arbitrary slices of a circle, you can adapt the above code; startAngle
and endAngle
are the arguments of the .arc()
method that you want to use to control the slice of the circle that gets rendered.
Importance of Setting The First Point on the Path
Just for fun, here is what happens if you forget to explicitly set the first point of your path as the origin point of the arc:
As you can see, without the first point on the path being the origin of the arc (or center point), the .fill()
method only fills the area between the two end points of the arc itself, drawing a direct line across the curve.