Help trying to understand Canvas API

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/stroke#re-stroking_paths I just can't seem to understand this part from the MDN Docs for the life of me.. I feel like it's worded confusingly.
No description
No description
38 Replies
Aoi
Aoi•3mo ago
Yeah these docs can sometimes be hard to understand. So lemme just give a brief on what's going on. I will call the entire grouping of commands as chain. beginPath() All the methods like lineTo, moveTo are chained together. When you do .stroke(), all those things are performed on the canvas at once. If you then start a new line, etc. this also added to the previous chain. If you run a .stroke again, the entire chain will be performed on the canvas including the previous one. .beginPath is used to reset this chain. The Image Step 1 The big line is added to chain, color changed to orange and stroked. Step 2 The second medium line is added to the chain just below the big orange line. The color is changed to green. This is now stroked, which creates two lines. One between the bigger orange line and one below it. Step 3 A new thin line is added to the chain. Color is changed to pink. Now it is stroked, this creates three different lines. Two inside the previous once and one new one
rezabet
rezabet•3mo ago
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// First sub-path
ctx.lineWidth = 26;
ctx.strokeStyle = "orange";
ctx.moveTo(20, 20);
ctx.lineTo(160, 20);
ctx.stroke();

// Second sub-path
ctx.lineWidth = 14;
ctx.strokeStyle = "green";
ctx.moveTo(20, 80);
ctx.lineTo(220, 80);
ctx.stroke();

// Third sub-path
ctx.lineWidth = 4;
ctx.strokeStyle = "pink";
ctx.moveTo(20, 140);
ctx.lineTo(280, 140);
ctx.stroke();
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// First sub-path
ctx.lineWidth = 26;
ctx.strokeStyle = "orange";
ctx.moveTo(20, 20);
ctx.lineTo(160, 20);
ctx.stroke();

// Second sub-path
ctx.lineWidth = 14;
ctx.strokeStyle = "green";
ctx.moveTo(20, 80);
ctx.lineTo(220, 80);
ctx.stroke();

// Third sub-path
ctx.lineWidth = 4;
ctx.strokeStyle = "pink";
ctx.moveTo(20, 140);
ctx.lineTo(280, 140);
ctx.stroke();
I still don't actually get it
rezabet
rezabet•3mo ago
No description
rezabet
rezabet•3mo ago
How does this first line use the other 2 lines when we stroke'ed before calling those other 2 lines:
// Second sub-path
ctx.lineWidth = 14;
ctx.strokeStyle = "green";

// Third sub-path
ctx.lineWidth = 4;
ctx.strokeStyle = "pink";
// Second sub-path
ctx.lineWidth = 14;
ctx.strokeStyle = "green";

// Third sub-path
ctx.lineWidth = 4;
ctx.strokeStyle = "pink";
And why is it called "sub-path" instead of just "path"?
Aoi
Aoi•3mo ago
even if it's stoked already, the previous lines are still in the current path, you need to use beginPath() to reset it
rezabet
rezabet•3mo ago
I don't get what you mean by "previous lines"
rezabet
rezabet•3mo ago
There is nothing previous there
No description
rezabet
rezabet•3mo ago
If that third line had all the colors, then yes, it would make sense for me now But it's not
Aoi
Aoi•3mo ago
The third line won't have all three colors because you already set the lineWidth to 4 and color to pink, Lemme make something on codepen so it's easy to understand
rezabet
rezabet•3mo ago
Okay
Aoi
Aoi•3mo ago
https://codepen.io/Nandesh-S/pen/KKYLzwQ this might help, open the console. it contains all the messages
Aoi
Aoi•3mo ago
also increase the speed if you need
rezabet
rezabet•3mo ago
OHHH I think I get it now
rezabet
rezabet•3mo ago
So from what I understand, whenever we call moveTo and lineTo, we create permanent Path objects and whenever we call stroke, we render into all Path objects?
No description
rezabet
rezabet•3mo ago
Did I get that right and is my wording/terminology accurate? (Please correct me if not, that'd be highly appreciated!)
we create permanent Path objects
I thought everytime we call moveTo/lineTo again, we are dealing with a new Path Also, for every beginPath, should their always be a closePath (once you're done creating your Path)?
Aoi
Aoi•3mo ago
concept is correct, but instead of calling those paths call them subpaths, all the subpath from the last beginPath() to the latest one combine to form a path which get's stroked / filled Ideally you should closePath so the next time you want to draw something, it should start from the last point of the previous path. eg, if you have a function like draw triangle. it should have beginPath and closePath so it's doesn't interfere with anything else.
rezabet
rezabet•3mo ago
Ah okay, so in our case: - subpath + subpath + subpath = path And what is a subpath by definition? Does it mean a "part" of a path? A small piece of it.. that when combined with other subpaths, form a whole path?
Aoi
Aoi•3mo ago
Technically all the line, curve, etc methods will give a subpath, but even I won't be sure on the exact definition,
rezabet
rezabet•3mo ago
I see
Aoi
Aoi•3mo ago
also stuff like strokeStyle and fillStyle are for entire path and not subpath
rezabet
rezabet•3mo ago
Also, if you don't mind, could you explain that wait, await, ..etc parts of your program? Sorry, not familiar with async in JS.. Oh yeah, MDN's docs do say this:
This method [fillRect and strokeRect] draws directly to the canvas without modifying the current path, so any subsequent fill() or stroke() calls will have no effect on it.
Aoi
Aoi•3mo ago
ah, you can ignore them for now. we don't have a wait() function in js like we have in py, etc. If you wanna explose those a bit, you can look for these keywords "Async await", "Promises"
rezabet
rezabet•3mo ago
Appreciate it
Aoi
Aoi•3mo ago
Happy to help :)
rezabet
rezabet•3mo ago
Btw, how come you learnt the Canvas API instead of using a library? Do most people also learn the Canvas API or use a lib?
Aoi
Aoi•3mo ago
So funnily, I started js with canvas. Before I was doing robotics stuff, then canvas really caught my attention and that lead me to start using js and html canvas Canvas is quite rarely used natively nowadays, atleast I havn't seen many projects use it. most stuff like graphing and 3d visualization can be done better with libraries
rezabet
rezabet•3mo ago
3d visualization
Canvas is 2d though I feel like the Canvas API is good for graphs and maps, ..etc 2d ofc ^
Aoi
Aoi•3mo ago
2d is also just a part of the canvas api, there are also web gl related stuff unless we are getting into vr, all the 3d visuallization are just a 2d projections of a 3d object
rezabet
rezabet•3mo ago
Ah I supposed that's true yeah Where did you learn about all this graphics stuff? Do you have any external resources you could refer me to to learn more? Also, how can 3d visualizations "trick" us that good? Cuz it really does look 3d but in reality, it does make sense that it's actually 2d cuz well.. it's a 2d screen
Aoi
Aoi•3mo ago
Just been explore stuff everywhere I could find, one advantage of being self taught. There are a few yt channels like SabastianLague
YouTube
Sebastian Lague
Hello, on this channel I explore how to create stuff out of code. I hope you find some of it interesting!
rezabet
rezabet•3mo ago
Probably some fancy GPU math? 😄 Thanks
Aoi
Aoi•3mo ago
It's actually just a combinations of quite a lot of small things, the more you combine the better the expirience. Like different projection methods, lighting, bloom, different surfaces, shadows..... If you explore the 3d rendering world you will realize quite often we "fake" the effect than actually computing it
rezabet
rezabet•3mo ago
Woahh Okay, that's really cool man Dang
Aoi
Aoi•3mo ago
if you love math, you can try few basics things yourself without much info
rezabet
rezabet•3mo ago
Oh, wdym though? Try what things and without what info?
Aoi
Aoi•3mo ago
you can try projecting points in 3d space on a 2d screen, there is a high you will make it work without learning about a preexisting projection method might require a big of math and trigonometry
rezabet
rezabet•3mo ago
Ah okay, I see Thanks again
Aoi
Aoi•3mo ago
:)