Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polygon with a hole in the middle with HTML5's canvas

Using the <canvas> tag I need to be able to draw a hole in a polygon.

Right now I have something very simple that uses beginPath() then does lineTo() for each point. It is then filled with fill().

I cannot see any way to have a filled polygon with a unfilled middle though, like a donut. I'm not making a donut but it is suitable for this example.

Is there something I am missing? I would rather not draw it fully filled then have to redraw the middle.

like image 217
Nick Avatar asked Nov 29 '12 04:11

Nick


People also ask

What are the different shapes in canvas?

Unlike SVG, <canvas> only supports two primitive shapes: rectangles and paths (lists of points connected by lines).

Which method in Canvas is used to create a rectangle?

To draw the rectangle onto a canvas, you can use the fill() or stroke() methods. Note: To both create and render a rectangle in one step, use the fillRect() or strokeRect() methods.

How do you fill a canvas shape?

To fill an HTML5 Canvas shape with a solid color, we can set the fillStyle property to a color string such as blue, a hex value such as #0000FF, or an RGB value such as rgb(0,0,255), and then we can use the fill() method to fill the shape.


1 Answers

You can use evenodd fill rule: fill('evenodd')

Even-odd rule

// properties
// - outer square
var outerLength = 200;
// - inner length
var innerLength = outerLength / 2;

// cnavas
var canvas = document.getElementById('canvas');
var width = canvas.width = document.body.clientWidth;
var height = canvas.height = document.body.clientHeight;
var context = canvas.getContext('2d');

// path
// - outer square
context.rect(
  (width - outerLength) / 2,
  (height - outerLength) / 2,
  outerLength,
  outerLength
);
// - inner square
var x0 = (width - innerLength) / 2;
var y0 = (height - innerLength) / 2;
context.moveTo(x0, y0);
context.rect(
  x0,
  y0,
  innerLength,
  innerLength
);

// draw
// - stroke
context.lineWidth = 10;
context.stroke();
// - fill
context.fillStyle = 'red';
context.fill('evenodd');
html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
}
<canvas id="canvas"><canvas>
like image 125
Yas Avatar answered Jan 05 '23 04:01

Yas