Building a Drawing App in React - Pt 1 | Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone hope you do well so today we're gonna be building a drawing app from scratch and this has been inspired by an app called excel draw which is the one we can see here so excel draw is our virtual whiteboard app and it's got this hand sketched feel to it which is which is really nice so you can kind of select different items free markers etc and you can can basically draw out sort of an unlimited whiteboard as well and you can of course change styles backgrounds etc and it's got a few other features like collaboration with all the people sent and encrypted and translated etc so there's quite a few things going on and this is all open source so I thought it'd be cool to try build a kind of a very simple version of Excel to draw from from scratch just to see how it works sometimes looking at the actual open-source project can be quite intimidating so I thought we could you know break it down and just do for scratching it in a simple way so so this is what we're going to be building today not quite as nice as excited robot we have either lines which we can kind of you can see and rectangles so you can put quick and yes draw those so very very minimal drawing out but you can see how hopefully by building this how it starts to build up into something like like excel draw so this is probably two or three prerequisites that it's probably worth knowing before kind of diving into this and that's a bit about HTML canvas which am Deana got some quite good documentation tutorials but basically HTML exposes a canvas element which you can use and through using some JavaScript and getting references to the canvas and then the context you can start drawing elements on that canvas such as you know we've got the rectangle here which we'll kind of see later on and you can draw lines and you can draw circles or even SVG's etc so might be worth reading up a bit about the documentation there and the second thing is so they called rough Jess so rough GS is built on top of HTML canvas spray gives you a kind of hand-drawn look and feel but we were we're after and it's got a similar API you can see here that we're drawing a rectangle with X Y coordinates width and height etc so it's worth looking into this specifically if you go to the API and do you look for the generator just a slightly different way to do it so it's exactly the same API were rectangles lines etc but we're generating them storing them into a variable and never we're drawing them well later later date so worth looking over those two and the third and final thing worth mentioning is the grid system which is very similar to SPT if you're familiar with it but it's 0/0 the top-left x and y on the horizontal and vertical axis and then yeah as you go on you can see if I'm drawing a point from from here to here we can see that's 10 10 across all the way down $200 that's that's basically the grid system that's how it works so yeah let's let's get started so we start with this hello world up grab see nothing saw it and the first thing we do is just add a canvas so let's start with that canvas we can give it an ID of canvas and we'll just say canvas here so it doesn't need to have anything inside about if the browsers don't support they're going they can fall back to the text aside and just for the meantime we're gonna do is I'm going to give it a background color just so we can see it for for a moment let's go back and cut it blue cool and we can start and we can see this this blue thing at the top left the owner of this that's there the default width and height so we just want at full screen so we can do that by just specifying the width and height on it suppose that what we want is that we want the full screen of the kind of visible part of the browser not that you're not the entire browser right so just just what we see in here and you can get that by your window dot inner width right so our width will give us a full browser you know it gives us just the the window we see so Heights exactly the same thing don't in our height let's do that and there we go so that's the full thing there nope you stick away the color so you just assume that's all there perfect so you got the canvas started and let's just take the example from I guess NDA's website just so you can see it wrong perfect so we're going to do in here react I'm gonna use the use layout effect hook here and I've specifically using this one cuz I think is I think so right one to use when it comes to manipulating Dom elements so you want the dog to be completely ready before you do anything so I think I think that's the right one so I've just pasted it and you can see the green others so again we're getting the canvas by the ID here so that's the same idea here I'm looking at from the document then were specifically asking for the context and this is the rendering context and this is just a standard thing they do pass in 2d there's other options like 3d etc though we're not gonna use it I actually think 3ds web WebGL is something but so we're calling the context and then we're using the context to start filling out some elements right and that's yeah simple as that's all we can I think also do city x dos stroke rect and let's do it 200 200 for 100 so we can see yeah there's a rectangle in the middle perfect so I'm gonna get rid of this and we're gonna keep the rest of that here for now so what we do now is we're gonna import and I've already done this but you want to do is npm import npm install' ross yes because we want to do exactly we're going to do it with with ruff GS so once you've imported that installed that sorry we can go ahead and import rough from yes I think they have some bundled person there so take ruff and from the API that we saw we can do rough canvas is equal to rough dot canvas so we're initializing it and we're passing in the existing cameras that we have cool and then we can do exactly the same thing so rough time they start rectangle let's do 10 10 100 100 save that and we can see that strong it there perfect and the final thing when we do before we get kind of into the actual drawn aspect is use the generator that we see so we've got generator from rough dot generator yes generator and then we can basically replace this with generator so that's generating the rectangle so this cost Rex is equal to that and then we can rough canvas draw now the benefit of this of course is we can draw any shape in here so we don't need to kind of have for this logic to check which one it is but that'll be extracted out I'll swear if we do that we're gonna get the exact same same effect and you may have noticed a slight change there so time and refresh this because it's a hand-drawn look it's gonna be slightly different so actually let's add also online just to see what that looks like 9 10 10 and I'm this actually instead of width and height its y1 y2 so I need 110 on a 10 and then we're gonna draw the line as well cool so that's fine so flood line and rectangle but we don't want them to appear there from the start we want to draw them instead right so what does that mean we need to basically track the mouse events the mouse movements right so we want hey when we click we want to create if we're gonna start with the line right so when we click when I create this line and the x and y are gonna be at the the point of the cursor so let's say here if I click down that's gonna be 10 10 and actually the end coordinates - and whiter also gonna be ten ten right and then as I'm moving my mouse and I'm still clicking down the x2 and y2 are gonna be moving with me right so I should be seeing a line that start off at ten ten and then the end coordinates are just going to keep updating as I move my mouse right and then at some point whenever I let go it's gonna stop updating that the line should basically stay there right so if we think about that for a moment we know we're gonna have to keep a track of the elements right so that's what element itself we know that we have to create element as soon as Suzy quick and need to update as we move and then yeah when we let go of the click on mouse op we're basically we're not doing anything so let's take those and add them and so first thing I'll do is actually I know that we're gonna have to keep track of some sort of elements so I'll do elements here that's going to start off as an interior rivet next thing I want to do is I need the concept of whether I'm drawing or not so as we said we can track that on mood but we don't want to track them move all the time we only want to track it while while we're drawing I'm really drawing while the mouse is down right so let's have a state for drawing said drawing and this is going to be false to start off with and I think that should be enough to get us started right so when we click down on the mouse go to the console here we'll click on the mouse all we want to say is we want to set drawing to true for now perfect and as we move you want to track the x and y coordinates so if we're so let's just say if we're not drawn and just returned Murray care otherwise for now licious cancel that log x and y so client x and client y is what they're called from event right so that's the miss fear mouse coordinates and that's so worth knowing that that's the mouse coordinates relative to their window size so if your canvas is not the same size of your window you have to put on with offsets etc but we're not gonna get into that now because it's the same width it will keep that simple and as soon as we let go and you can set drawing to false because we're no longer dry so what you see now I'm I start to be a function yes so we should see now is nothing as I move my mouse around as soon as I click down yeah you can see that the coordinates of the bond there are sure as soon as I click my mouse up nothing anymore cool and actually another thing that you may have noticed is this is getting a lot darker right every time I click that's gonna bit a bit darker and so the reason for that is this is being rear-ended every time so it's redrawing the line and the rectangle on top of each other on top of each other it just keeps going on top like canvas so what we actually want to do is we want to make sure we clear the canvas everytime we render right so we're clear it then we draw every single item we can do that by call this context and we can do that by doing context dot clear when it's clear right yep basically creating a rectangle we're gonna start off at zero zero and you want to clear the full width and the full height we can get access to those from the canvas and variable so there you go and now as I click it changes which is fine but it's not rewriting that's perfect code so now we've got this what we want to do is we want to actually start creating these elements right so let's say and the handle Mouse down as soon as we start drawing we're create an element so create that's just gonna return an omelette and what does take in we're gonna need an XY coordinate start with and we're also going to need the X 2 and Y 2 so let's just pop them in so we know that the starting point is gonna be Cline X clam wine so you can just pop them in at that and in fact when we first create the element the endpoint is actually gonna be exact same right so when I click here 10/10 it's going to start 10/10 it's gonna finish at 10 10 at that point in time right and then we're gonna continue to update it as we move along right so I'm gonna create this function here pop that into the global state and right now let's do x1 y1 x2 y2 and the element all it is right now is Oakland y1 thanks to watch it that's fine so we're going to keep those coordinates and in fact we also want to create the actual rough rough GS element as well we want to store that because that's what we're gonna ruin that render later on right so let's call that rough element is equal to rough yes you generator dot line it's the same as down here and yeah that's just least ugly this x1 y1 x2 y2 and we're just gonna save the rougher - all right so if trade down that we've created the rough J s element which it's got its own properties etc and then we've just kept the X&Y coordinates so that we can track them and use them easily so once we create them all we need to do is add it to the elements so set elements we're going to take the previous state I'm gonna add that to a new array and then we're gonna add this element oh just great so we're just basically pushing elements into the array that's fine so if we have a quick look at the components here so and look at the state here so it's empty as soon as I click here yeah we can see that we've got first item and it's got X Y coordinates and it's got the rough element there which we don't need to to look into right now cool so that's fine now we want to do is we want to update it as we move around so we've got a handle mouse move and this gives us basically X 2 and Y 2 so we wanna say is let's create an element we somehow need to get x1 and y1 will do it at a moment but we know that client X and client Y is the new and and coordinates right and what we can do is we know that the last element in the elements array so we just create out in the last time and an element array is going to have to have these details so what we can do here is index and then start length minus 1 so we're getting there index of the last element in the array and then we can just get to X 1 and X Y 1 from elements index so we're taking them the last element that we added which is the one we're still working with so we just click down we just create this element and now we're moving the mouse and we're taking that element and we're gonna take the X&Y so they stay the same we don't wanna change them but we do want to change and x and y coordinates and yeah and that's actually fine because inside here it's also go then we create the rough element that's fine and then basically we need to do now is just update the array with this new element instead of the previous element so we can do that by and we'll do is I'll just copy this bit of code here so what we're doing here yeah that's a good point I've renamed this to update element just to explicitly state oh that's the update island so we're making a copy of the existing element just popular in brackets we are taking the index of the last element and we're basically replacing it with the updated element and then we're just updating the elements array so now what we need to do we've done that and we've the element should be creating so less system but we weren't actually rendering the elements that we created so instead of rendering these guys here what we're going to do is we want to go through all the elements for each element and we want to draw basically that element and that element actually takes in element a rough element which you can do and in fact you can just restructure this directly just like that so we're taking the rough element from each element and we're gonna draw it so close that and it will continue to render as we move along there's one last thing for it to do which is in this new layer effect we want this to depend on elements so every time elements has been updated we want to make sure we rerender the elements in the canvas so I go here click down as we move around it's gonna keep me rendering and you can see that's a bit kind of fuzzy those because this is we running a new hand drawn out each time as soon as I let go that won't change another one well cool so now we can draw a few lines perfect and that's pretty much the block of the code the really cool thing here is because we're kind of getting away this create element if we want to draw a rectangle we can just replace this with rectangle and of course instead of X Y coordinates to the end this one takes in the width so we just need to do x2 minus x1 and y2 minus y1 and all of a sudden we're drawing rectangles so you can kind of see how you can start to build up all the different and different shapes so one way to do just to get to the final bit it's on a copy of a code in here so I'm gonna write this in a div let's go down here so this is all gonna be in a div now and I'm gonna paste in another div and all this does is this is the inputs so just got a couple of radio buttons here a couple of labels I've made this position fixed so just stays at the top left without affecting the size of the canvas and this is basically gonna check for a state called a piece of State called element type and she's gonna say if it's line then you know this all this is the radio button that's checked it's a rectangle this is the radio button is checked so it's just gonna change our participate called element type which is just going to have a string inside of it so let's just dive in so element type and set element type and that's just gonna be like I said starting off with life and the final part is on milestone when we create the element we'll pass in the element type right so I'm gonna pass that in certain laws same down here which one to create and up here what we can do is we can basically say if element type is equal to line then generate a line and that's gonna just be XY coordinates just like a drill and for now because we know that let's just call this one type and you're passing it through here so if type is equal to line then join it line otherwise generate a rectangle simple as that so now I wonder what line clicked that's gonna draw the line that's exactly what we expect as soon as we hit rectangle so we drawn the rectangle and that's it so you can see how this starts to build up with different objects you're on arrow if you want like the free tools circles etc there you know start getting a bit more and maths I need a few more equations etc to it to sort out but the very simple building blocks of drawing elements is there so if you enjoyed this and you want to dive more into the other elements or if you want to dive into how rough GS works or you know the peer-to-peer functionality you know let me know in the comments below happy to do more videos and those because this was really enjoyable but yeah I love how simple this is that's you know less than a hundred lines of code I mean there are decent enough drawing apps so yeah thank you very much for watching hope hope you enjoyed it and see you in the next one
Info
Channel: Redhwan Nacef
Views: 13,859
Rating: undefined out of 5
Keywords: excalidraw, drawing app, build a drawing app, virtual whiteboard, react, reactjs, react tutorial, Software engineer, software developer, how to, how to code, coding, programming, testing, java, javascript, learn to code, learn coding, learn programming, software, technology, computer science, YouTube, Redhwan Nacef
Id: 6arkndScw7A
Channel Id: undefined
Length: 22min 25sec (1345 seconds)
Published: Tue Jun 23 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.