draivin
draivin

Reputation: 58

When a canvas path intersects in a certain way, it is not drawn

When a path is filled on the canvas, depending on the way the path was created, the path intersections are painted with the fill color or left blank.

Here is an example:
http://jsfiddle.net/C3Hbb/

//Works as expected:
ctx.beginPath();

ctx.rect(50, 50, 50, 50);
ctx.rect(25, 50, 50, 50);

ctx.fill();

//Transparent on intersection:
ctx.beginPath();

ctx.rect(25, 150, 50, 50);
ctx.rect(100, 150, -50, 50);

ctx.fill();

I expected both intersections to be drawn the same way since the rectangles that compose them are roughly equivalent, but on the first one, the intersection is painted with the fill color, and on the second one the intersection is transparent.

Why does it behave differently on those two intersections? And is there some way to avoid the 'transparent' intersection behavior?

Upvotes: 2

Views: 442

Answers (2)

Scott Mermelstein
Scott Mermelstein

Reputation: 15397

The simple answer is: don't set the width in your second rectangle to negative. If your line was:

ctx.rect(25, 150, 50, 50);
ctx.rect(50, 150, 50, 50);

or:

ctx.rect(25, 150, 50, 50);
ctx.rect(100, 200, -50, -50);

It would've drawn just fine. Effectively, a single negative dimension tells it to draw the points counterclockwise instead of the standard clockwise. The fill calculations specified by HTML5 canvas.draw both treat the single-negative value polygon as outside of your path.

The spec for HTML 5 canvas fill says:

The fill() method must fill all the subpaths of the intended path using fillStyle, and using the fill rule specified by the optional w parameter. If the optional w parameter isn't specified, or if it is the string "nonzero", this method must fill all subpaths using the non-zero winding rule. If the optional w parameter is the string "evenodd", this method must fill all subpaths using the even-odd rule. Open subpaths must be implicitly closed when being filled (without affecting the actual subpaths).

Note that both the defined "evenodd" and "nonzero" means of determining what is inside says that the negative numbered ones will be outside your path.

Upvotes: 2

Jean Lourenço
Jean Lourenço

Reputation: 715

This is caused by the -50 width you've setted on the second rectangle. You just need to adjust the X:

ctx.rect(25, 150, 50, 50);
ctx.rect(50, 150, 50, 50);

Upvotes: 0

Related Questions