Explain Codes LogoExplain Codes Logo

How to draw a rounded rectangle using HTML Canvas?

html
responsive-design
canvas
javascript
Nikita BarsukovbyNikita Barsukov·Oct 5, 2024
TLDR

To craft a rounded rectangle using an HTML canvas, utilize the following code snippet:

function drawRoundedRect(ctx, x, y, width, height, radius) { ctx.beginPath(); ctx.moveTo(x + radius, y); ctx.arcTo(x + width, y, x + width, y + height, radius); ctx.arcTo(x + width, y + height, x, y + height, radius); ctx.arcTo(x, y + height, x, y, radius); ctx.arcTo(x, y, x + width, y, radius); ctx.closePath(); ctx.stroke(); // To stroke the shape. Use ctx.fill() to fill it like it stole your lunch money! } // Given 150x100 rectangle with 20px rounded corners: drawRoundedRect(document.getElementById('myCanvas').getContext('2d'), 20, 20, 150, 100, 20);

Adjust x, y, width, height, and radius values to fit your requirements.

Taking it to the next level

The above answer gets you up and running. Yet, calling it a day at this stage would be like ordering a pizza and ignoring the extra toppings. Let's look at how we can add some flavor to our rectangular pie!

Handling the corners your way

Perhaps having different corner curvatures is something you fancy. It's as simple as modifying the drawRoundedRect function to accept an array of radii:

function drawRoundedRectFlex(ctx, x, y, width, height, radii) { if (!Array.isArray(radii)) { radii = [radii, radii, radii, radii]; // If one, make it four! } ctx.beginPath(); ctx.moveTo(x + radii[0], y); // ... other corners go here ... ctx.closePath(); ctx.stroke(); // Or ctx.fill() for colored corners! }

Love thy neighbors (browsers)

Before going Picasso on your canvas, do check if the browser speaks your language. arcTo and roundRect compatibility differ like JavaScript frameworks. If not, polyfills are here to save the day:

if (CanvasRenderingContext2D.prototype.arcTo) { // All hail arcTo! } else { // Time for a polyfill or fallback strategy }

Chaining ain't just for jewelry

To enhance readability and compactness, return ctx from the drawing function for method chaining:

function drawRoundedRectChain(ctx, ...) { // ... drawing code ... return ctx; // Now you can chain methods. One ring to rule them all! }

Handling awkwardness (i.e., disproportionate corners)

Don't let disproportionate corners cramp your style. Make radii adjust in relation to the rectangle size:

const maxRadius = Math.min(width, height) / 2; radius = Math.min(radius, maxRadius); // Radius, meet size. // ... Beat it, round corners! ...

Mix it up with methods

Only Siths deal in absolutes, so don't limit yourself to arcTo method. Combine lineTo(), arc(), and quadraticCurveTo() for a veritable potpourri of corner styles:

// Combo for a custom corner style. Awesome sauce! ctx.lineTo(x + width, y); ctx.quadraticCurveTo(x + width, y, x + width, y + cornerRadius); // ... Continue with the rest of the corners ...

Making Shapes, The Advanced Way

CanvasRenderingContext2D isn't a one-trick pony. Dive into advanced shapes and patterns, and make Mona Lisa proud!

UI Integration: Making it all work

Align these rectangles with your UI elements to provide a smooth user experience. Rounded rectangles should harmonize with your UI and NOT steal the show!