Explain Codes LogoExplain Codes Logo

How to draw an oval in html5 canvas?

html
responsive-design
canvas
drawing
Anton ShumikhinbyAnton Shumikhin·Sep 2, 2024
TLDR

To quickly draw an oval in HTML5 canvas, you can use the ellipse method:

const ctx = document.getElementById('myCanvas').getContext('2d'); ctx.beginPath(); ctx.ellipse(100, 75, 50, 35, 0, 0, 2 * Math.PI); // "It's a kind of magic" - Queen ctx.stroke();

This renders an oval at the coordinates (100, 75) with a horizontal radius of 50 and a vertical radius of 35.

Alternative methods

There's more than one way to skin a cat... or in our case, draw an oval. Here's some alternatives when ellipse is not universally supported or you need more precise control over your shape.

Bezier curves - Now you're drawing with power

Bezier curves give you more control over the ellipse drawing:

ctx.beginPath(); ctx.moveTo(50, 75); // Chroma Key Green (Start here) ctx.bezierCurveTo(50, 45, 150, 45, 150, 75); // Two Red Bulls (Control lines) ctx.bezierCurveTo(150, 105, 50, 105, 50, 75); // And a large soda (End here) ctx.stroke(); // Voilà! There's the oval

Quadratic curves - Because math is cool

The quadraticCurveTo() method is another valid approach:

ctx.beginPath(); ctx.moveTo(50, 75); ctx.quadraticCurveTo(100, 0, 150, 75); // "They see me rollin', they hatin'" - Chamillionaire ctx.quadraticCurveTo(100, 150, 50, 75); ctx.stroke(); // Another oval? You're spoiling us!

Circle scaling - The Beauty and The Beast method

A non-uniform scaling transformation can also turn a circle into an oval:

ctx.save(); // "Hold my beer!" - Anyone who's about to do something shocking ctx.scale(2, 1); ctx.beginPath(); ctx.arc(50, 75, 50, 0, 2 * Math.PI); ctx.restore(); ctx.stroke(); // Great, now we can relax!

The save() and restore() functions help maintain the canvas state during the transformation process.

Advanced transformations

Here we will handle common pitfalls, like undesired skewing, and we'll also learn how to draw part of an oval.

Scaling circles into ovals

The scale() transformation will turn a boring circle into an exciting oval:

ctx.beginPath(); ctx.arc(100, 100, 50, 0, 2 * Math.PI); ctx.scale(2, 1); // "You spin me right round, baby right round" - Dead Or Alive ctx.stroke(); ctx.setTransform(1, 0, 0, 1, 0, 0); // Reset to not mess up other drawings

Adding rotation to ovals - Spin to win

Include the rotation parameter to make your oval dance:

ctx.beginPath(); ctx.ellipse(100, 75, 50, 35, Math.PI / 4, 0, 2 * Math.PI); // "Just dance, gonna be okay" - Gaga ctx.stroke();

Provide insights with partial ovals

Sometimes, less is more. Drawing just part of an oval can make data more understandable:

ctx.beginPath(); ctx.ellipse(100, 75, 50, 35, 0, 0, Math.PI); // "We're up all night to get lucky" - Daft Punk ctx.stroke();