Canvas 2D tutorial needs to discuss how shapes actually work and fix issues #38156
Labels
Content:WebAPI
Web API docs
help wanted
If you know something about this topic, we would love your help!
MDN URL
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes
What specific section or headline is this issue about?
The Grid and Drawing Rectangles
What information was incorrect, unhelpful, or incomplete?
The article does not explain how the canvas API really works. Further, it has some false information, possibly because that explanation is missing.
For example: The article shows this code
It then explains it like this
This last part
Is false.
What really happens is,
ctx.strokeRect(50, 50, 50, 50);
makes a rectangle from 4 lines from unit 50,50 that is 50 units wide and 50 units tall. It then expands each line 0.5 units in both direction perpendicular to the line (0.5 because the default lineWidth is 1.0). This ends up with a frame that is 1 unit thick that stats at 49.5,49.5 and is 51x51 units wide the buttom right is at 50.5, 50.5. In then fills in each pixel inside the frame in proportion to how much of that pixel is inside the frame. That's why the frame in the example is actually 2 pixels wide and is gray instead of black.The article would benefit from first explaning that the canvas 2D API doesn't use pixels as units.
Maybe diagrams like this would help
First off. given code like this
I suspect many people, when they first encounter the API, assume the units are pixels like this
Draw from pixel 2,2 10 pixels wide, 6 pixels high.
They are not pixels though, they are grid units specifying a rectangle like this
Draw from 2,2 10 units wide, 6 units high
The pixels inside that rectangle are filled with
'red'
(the fillStyle color) based on how much of each pixel the rectangle touches is inside the rectangle. In the case above, every pixel the rectangle touches is 100% inside the rectangle and so you the result most people expectBut, move the rectangle over half a pixel
Suddenly some pixels are only half covered by the rectangle. The corner pixels are only 25% inside the rectangle so you get this (*)
You can see the pixels on the edge which were only 50% covered by the rectangle are only 50% red. The outer corners which are only 25% inside and so are 25% red. (*)
The next thing to understand is how
strokeRect
(andstroke
) work.Starting with the original rectangle with this code
First, again, that code defines this rectangle
That outline gets expanded to be
lineWidth
thick, purpendicular to each line (the 4 lines that make the rectangle). Like thisThen, just like before, the pixels the resulting shape touches are colored in proportion to how much they are inside the shape. The result is this
You can see the shape covered the inner and outer edge pixels by 50% so they are 50% red. The outer corners are only covered 25% so they get 25% red. The inner corners are covered 75% so they get 75% red. (*)
This is why the current document saying
Is wrong. That is not what happens.
It would be good to make this clear I think. It would also be good to point out that things like translate/rotate/scale effect these shapes and therefore affect how much of each pixel is covered.
Note: I'm not sure even "grid coordnates" is the best term. You just specifying "coordinates". those coordinate are transformed by the current transform. Then, whatever pixels are touched by the shape your drawing are colored in proportion to how much of the pixel is inside the shape.
(*) Note: AFAIK the spec is not clear on exactly how things are drawn. The results shown in the diagrams match Firefox Nightly 137 on an M1 Mac. Chrome and Safari each do things differently. For example in the stroke example, Chrome renders the same pixels but all of them are 50% red including the inner and outer corners.
And of course, further, the
lineCap
,lineWidth
, andmiterLimit
settings affect how the lines are expanded into a shape before the shape is used to color pixels based on how much the shape covers them.What did you expect to see?
Correct information and a clearer or more precise explanation
Do you have any supporting links, references, or citations?
https://html.spec.whatwg.org/multipage/canvas.html#2dcontext
https://jsgist.org/?src=f851375146e7b56b3f8495c2d3c8a80d
Do you have anything more you want to share?
No response
MDN metadata
Page report details
en-us/web/api/canvas_api/tutorial/drawing_shapes
The text was updated successfully, but these errors were encountered: