[Music] in this video we will go from drawing a single circle on html canvas to this advanced particle effect let me take you from beginner to advanced today if you want to become a canvas pro this year and take your front end web development skills to the next level then join me for this crash course we will do it all from basic canvas drawings to advanced particle systems like this in one video welcome to another episode of my vanilla javascript and html canvas animation what is my intro too long okay let's start coding click like please [Music] let's create a project folder and inside i create three blank files index.html to hold all html markup style css so we can position the canvas and script.js file where we write all javascript functionality in index html i just create a basic web page markup i give it some title i create html5 canvas element with an id of canvas 1. in head of the document i link star css file and before the closing body tag i link script js javascript needs to come last to make sure it sees the canvas so that's it for index html you can see we used special canvas tag that was introduced with html version 5. it is a special kind of tag which creates a field canvas that we can use to draw interactive graphics with javascript by default canvas is transparent so you can layer multiple canvas elements on top of each other if you want layering might be useful for certain projects like games or when you want svg filters to apply only to certain specific elements but more on that in advanced tutorials let's stick to the basics today let's position the canvas and make sure it covers the entire page by adding a little bit of css i targeted using id i gave it so canvas 1 i set its position to absolute and background to black width will be hundred percent height will be hundred percent top zero and left zero to remove margins that some browsers add by default that's it for html and css today everything else will be handled with plain vanilla javascript let's open script.js file and learn how to draw on canvas with code i will go over the basics so that we all understand what's going on and where are all these methods coming from and then we build up on it step by step and try some coding experiments let's see what comes out of that today this tutorial is for canvas beginners who already know a little bit of javascript i want you to get a deep understanding of how to draw anything on canvas and then we can take it to the next level and create this advanced interactive animated particle system in script.js i create a constant variable i call canvas i want this variable to hold a reference to the actual html canvas attack we wrote in index.html once we grab a hold of it with javascript we can start drawing my custom converse variable will be equal to document.getelementbyid and i pass it id i gave it in index html on line 10 canvas one i create another constant variable i call for example ctx shortcut for context and i set it equal to canvas variable from line one that holds a reference to the actual canvas element dot get context and i pass it to d instead of 2d we could also pass it webgl here but that's for another video if i console log canvas variable from line 1 you can see it literally holds a reference to the actual canvas html tag from index.html file that's why i can online 2 take that canvas variable and call getcontext2d on it getcontext will only work if called on a variable that refers to canvas element like we're doing here right now when called correctly like we are doing here on line 2 getcontext returns a reference to built-in canvas 2d drawing api object and as you can see on line 2 i am storing that object in my custom ctx variable if i console.log ctx we should be able to see that object it's called canvasrenderingcontext2d if i open it its properties are global canvas settings such as fill style which is set to black color by default we can also see font global alpha stroke style and many more we can tweak any of these properties to create different effects today we will use some of them since this entire object is now held in my custom ctx variable i can access them like this for example ctx dot fill style equals white other than general canvas settings we also have prototype here and if i open it we see all different canvas drawing methods some of them might be familiar to you for example here we have arc method that can be used to draw a circle fill rect to draw a rectangle and many more again to access them with javascript we would call ctx variable from line 2 dot arc javascript will first look for this method on the actual canvas rendering context to the object but it won't find it there so thanks to javascript principle called inheritance it will then go look for it on the object's prototype and it will find it right here we can see many other drawing methods here very commonly used ones are for example begin path clear rect fill rect fill text and so on so to start drawing on canvas with javascript i take ctx variable from line 2 which now holds all canvas settings and drawing methods i access a global canvas fill style setting like this ctx dot fill style and i set it to white for example because my canvas background is black now i want to draw a rectangle so i call ctx fill rect method canvas settings are here drawing methods are on prototype here and fillrect is being called from this place it expects four arguments starting x and y coordinates from the top left corner of canvas so i pass it 10 horizontal x and 10 vertical y position and then it expects width and height of that rectangle so we can do with 50 pixels and height 50 pixels how about height 150 pixels i can play with any of these values to change size or position of my rectangle one problem we will always face with canvas projects is that when you resize browser window it stretches and distorts the canvas and our drawings first let's complete the canvas setup on line 3 i set canvas width to window in a width to make sure canvas covers the entire browser window horizontally i also set canvas height to window in a height to make sure canvas goes all the way from top to bottom vertically now we get correct scaling when page loads but notice that when i resize browser window it stretches my rectangle to fix that i will call add event listener on browser window it expects two arguments what type of event we want to listen for and callback function with code that will run whenever that event occurs line 3 and 4 where we set canvas with and height to match with and height of browser window will run only once on the initial page load i copy them and i paste them inside my resize event listener to make sure canvas gets resized to my browser window whenever user decides to resize it that works but you can see resizing canvas like this also deletes all our drawings so my white rectangle is gone lines 11 and 12 where i draw a white rectangle only run once on initial page load so i will copy them and paste them inside my resize event listener doing this every time resize event occurs canvas width and height is automatically adjusted and my white rectangle is a drawn again if i try to resize browser window now everything works and stretching is gone we know how to use fill rect to draw a rectangle particles in the effect we are building today will be circles and drawing a circle on canvas is slightly different let's draw one circle one particle now i delete all this code and to draw a circle i take ctx variable from line 2 and i call built-in arc method it expects at least 5 arguments x and y-coordinate radius of the circle so let's try 50 pixels start angle will be 0 and end angle will be marked by times two this value is in radians and it converts to 360 degrees so full circle i don't see any circle on canvas why is it let's try to set fill style to red because we know it is set to black by default still i see nothing it's because arc is not only used to draw a circle you can also use it to create a curved line or a semicircle with shapes on canvas you can just call the method and javascript knows what to do like we did with fill rectangle but with lines on canvas to actually draw them we need to call ctx dot begin path first think of this as telling javascript that you want to place your paint brush on canvas and start the drawing we have to do this because single shape can be made of multiple lines so begin path lets javascript know we are starting a new shape that is not connected to the previous lines if there are any so here i call begin path here i create a circular path at coordinates 100 100 with radius 50. this path will not start the drawing from the top left corner like rectangle did it will take x and y coordinates as a center point radius value here will be used as distance of the curved line from that center point start angle will determine where along the circle path i want to start drawing from so i start at the zero radians and end angle will be marked by times two which is the entire circle now i call ctx fill which will fill the path with color we can also outline the shape with stroke so on line 12 i set stroke style to write and on line 15 instead of calling phil i call stroke these are all built in canvas drawing methods that sit on that prototype object we looked at in the beginning to create nice things on canvas we need to understand at least these basic ones so feel free to experiment with it change colors sizes coordinates and watch what happens as i said all these methods are stored in our custom ctx variable from line 2 which contains a reference to built-in canvas rendering context to the object if i control ctx you see some global canvas settings we already used like line width fill style stroke style this is where all these settings are coming from i can play with colors and line width and change our circle like this if i want i can also position this circle somewhere else on canvas here on line 13 by changing its x and y coordinates this is going really well thank you so much for spending your free time with me hope you're having fun understanding all these fundamentals is really important once we are confident with these basics we can bring it to the next level and discover the true power of creative coding just follow along and let me show you click like please let's try to make it interactive what if i want to draw this circle every time i click somewhere on canvas let's create a custom javascript object i will call it for example mouse this object will just store mouse x and y coordinates so that they are globally available all around my program and i can use them for all different kinds of effects let's start with a very simple example before we start taking it to the next level so this mouse object will contain x and y properties initially i will set them to null then i call build in add event listener function on canvas element here on line 15. event will be mouse click and callback function will take one argument called event this event object contains all different details about the click event that just occurred such as x and y coordinates of the click and more now i take mousex property from line 12 and i make it equal to event dot x every time click event occurs i want it to take x and y coordinates of the click and i assign them to my custom mouse object doing this will make these coordinates available not only within my event listener callback function but also all around my code base i'm putting this information from inside the event listener and making it globally available if i consolidate this event object we can see all the information it contains you don't have to call it event you can refer to it as e or any other variable will work as well javascript knows that argument passed to callback function on event listener refers to this built-in event object that contains the details about event we are listening for if i click on canvas in console you can see this mouse event object it contains a lot of information about the click event that just occurred what we are interested in are these x and y coordinates event.x is referring to this x property here if i click again somewhere on canvas code on line 15 gets triggered again and we can see that all the values here have been updated coordinates start from 0 0 in the top left corner of canvas so if i click somewhere close to the corner i should get values close to 0 like this on line 17 i do the same thing for mouse.y property from line 13. code to draw my blue circle between lines 20 and 24 runs only once on the first page load as javascript reads my file line by line let's make it into a reusable function so that we can call this code easily again and draw multiple circles i create a custom function i call for example draw circle and i take all this code and put it inside this is called function declaration we wrote the function but javascript will not run the code it is only kept in memory it doesn't run until it's cold i call it like this and the code will run once on the first page load i can adjust values inside my arc method what if i call draw circle from inside click event listener now if i keep clicking it will just draw the same circle on top of each other at the same coordinates on line 24 inside canvas arc method i can replace x argument with mouse.x from line 16 and y with mouse.y now i get a new circle whenever i click on canvas let's add event listener for mouse move event this code gets triggered every time a mouse moves over the canvas i put the draw circle function inside i also have to update mouse x and mouse y every time a mouse move event occurs and again i pass event as argument here and this is how you create a very simple paint brush on canvas we can draw shapes now there is a circle in top left corner why is that is it because initial mouse coordinates i set to now convert to zero zero it seems so let's try hundred hundred okay then so initially i set them to undefined because i want blank canvas before we start interacting with it what's happening now i am moving mouse over canvas and mouse move event listener online 21 is updating mouse x and mouse y coordinates in my custom mouse object on line 11 and then draw circle is being called over and over creating a path of blue circles i think this is how paint brush tool in photoshop works as well on a very basic level we could for example put a different drawing code inside draw circle function on line 27 we could draw a square there instead of a circle or a star or even an image will work doing that would give us differently shaped paint brushes and we can make this into a drawing application but today we are building something even better and we are learning about html canvas and vanilla javascript in the process hope you're getting some value from this tutorial if you do click the like please on line 34 i create a custom function i call for example animate this function will be called over and over create an animation loop so whatever drawing code we put inside can move and can become interactive at the start of every animation loop i will clear old paint from canvas so that we can only see the current frame built in canvas clear rectangle method expects four arguments to determine what part of canvas we want to clear from old paint i want to clear the entire canvas so from coordinates 0 0 to canvas with canvas height then i use built-in function called requestanimationframe this function is very simple all it does it just calls function we pass it as an argument it calls it only once i pass it animate the name of its parent function from line 34. doing this will create a loop because animate function will start run all the code inside and then request animation frame will call it again so it will run over and over to kick off the animation loop i will call my animate function like this to actually see anything on canvas i need to put some drawing code inside in there i put my draw circle in you can see animation loop is running and because clear rect clears all old paint on line 35 we can only see the new circle that is being drawn over and over under the current mouse position if i comment it out we will see the trails again i'm actually drawing it from within mouse move event listener as well so it's been drawn twice i remove draw circle from mouse move event and i also remove it from click event now the circle is being drawn only from inside my animation loop on line 34. if i uncomment clear rect we can only see the current frame so this is how you draw one circle on canvas animate it and make it interactive what if i want to create a lot of randomized circles that move around canvas and interact with mouse in different ways i will create a set of javascript objects each will have its own x and y coordinates and its own size property i will then take these coordinates and size values and i will draw circles on canvas to create many similar objects we can use javascript classes this is a new syntax introduced with es6 version of javascript let's declare it and learn how to use it it's not difficult i use keyword class and the name of my class will be particle with capital p each particle will be one circle javascript class is a blueprint where we define properties and behavior of our objects and then every time we call this class it will create one new particle object for us properties of these objects are defined inside the blueprint in mandatory constructor method that every class needs to have behavior of these objects will be defined with class methods method is simply a function on an object i will show you in a minute let's first declare properties for our particles inside constructor i want particles to appear under mouse and start flowing from there in random directions this dot x equals mouse dot x all i'm saying here is that starting horizontal x coordinate of this new particle object constructor is creating right now is equal to mouse.x property from line 21. this dot y equals to mouse.y starting vertical y coordinate of each particle will be mouse.y position from line 22. each particle will also have its size property i want particles to be different sizes at the point where each particle is created here it will be assigned a random size let's say between 1 and 6 pixels if you are a beginner it might be hard to read this line as a random number between 1 and 6. you can run this in console and see what values it gives you math at random is quite simple if you get used to the syntax each particle will move at slightly different speed per frame i want particles to be able to move in all directions from the mouse so i will have horizontal speed property called speed x and vertical speed property called speed y these speeds added together will create a vector of movement direction and speed if i let speed x to be only positive numbers particles would only move to the right from the current mouse position i want them to be able to move left and right so in plus or minus direction on the horizontal x-axis speed x will be a random number between plus one and minus one i do the same for vertical speed y property i want particles to be able to move down and also up in plus and minus directions on vertical y axis these speed x and speed y values will be randomly assigned to each particle at the point where constructor creates it let's say i have particle with speed x1 and speed y0 it will just move to the right from mouse if it's speed x 1 and speed y 1 it will move to the bottom right speed x minus 1 speed y minus 1 will move the particle to the top left direction from the current mouse position since speed x and speed y values can be positive and negative numbers each particle will move in different direction away from the mouse we will have particles going to all sides so these are the properties for all particle objects coordinates size and speed now we give them some behavior using javascript methods as i said method is simply a function on an object we will have update method that will change x and y coordinates based on speed x and speed y values making particles move in all directions we will also have draw method that will take this dot x this dot y and this dot size of each particle and it will pass it to canvas arc method we used before and draw a circle at these coordinates of this size representing each particle this will then be called from inside animation loop updating and drawing particles over and over will create movement on canvas let me show you how in update method i take this.x from 934 and for every loop i will increase it by this.speedx from line 37. this can be a positive or negative number negative numbers will make particles move to the left positive numbers will make particles move to the right along horizontal x-axis at the same time i will be updating vertical y-coordinate from line 35 by speed y value from line 38. each particle will have a different direction of movement away from current mouse position and different speed this is how you create a simple 2d movement vector on canvas you will see it better when we animate it in a minute we will also have a custom method i call for example draw its job is to simply take values like coordinates and size from constructor and draw a circle on canvas representing that particle we already wrote that code to draw a blue circle on line 26 inside custom draw circle function i take that code and put it inside my draw method i also delete the original draw circle function declaration and i remove it from animate so now we have our particle class that will be used as a blueprint every time we call it using the new keyword constructor will create a new blank particle object and assign it properties and randomize values as defined in a blueprint between lines 26 and 31. each of these particle objects will also have access to update method that will update its x and y coordinates to move it and draw a method that will take these updated coordinates and draw a circle representing our particle there on line 40 i don't want particles to be drawn at mouse x and mouse y coordinates anymore i want them to be drawn at this dot x and this dot y coordinates from lines 27 and 28 these coordinates will also start at mouse x and mouse y position but because of our update method they will immediately start moving away from it on line 40 i replace mouse x mouse y with this dot x this dot y so we have a way of creating a lot of similar particle objects with our particle class let's write a function that will call this class many times and create a set of particles for us i will call that function for example init but you can call it whatever you want inside there will be a for loop that will run for example 100 times because i want to create 100 particles at first 100 blue circles inside that for loop i will need some kind of data structure to hold our particle objects created by particle class let's go all the way up to line 5 and here i create a global variable called particles array and i set it equal to an empty array with a set of square brackets like this whenever our for loop runs it will use particle class to add one new particle object into this array down here on line 48 i take my particles array i just created and i call built-in push method on it push method will take whatever we pass to it as an argument and it will push it to the end of the array i pass it new particle new is a special reserved keyword in javascript and if you follow it with a class name like i just did here it will find that class somewhere in our javascript file and trigger its constructor method constructor here online 27 will create one new blank object and it will assign it values and properties based on the blueprint specified between lines 28 and 32. it will give that new particle x and y coordinates size and speed this new particle object will also have access to update method from line 34 and the draw method from line 38. this for loop will run 100 times fill in our particles array with hundred randomized particle objects when i say randomized they will have randomized size and speed so i just declared init on line 46 i also need to call it to actually run its code at this point it's good to check if everything works i can't look particles array which now contains hundred particle objects and it does but i can see that x and y properties on my particles are undefined it is because here on lines 28 and 29 inside particle class constructor i set the initial x and y of newly created particles to mouse x and mouse y but when these particles are created on line 46 on the first page load mouse x and mouse y is still undefined because i haven't moved mouse over canvas yet let's comment these lines out for a moment and let me show you something instead of setting the initial x and y to the current mouse position i can set this dot x on each new particle to be a random number between zero and canvas width and this dot y to be between zero and canvas height this will spread new particles randomly all over the canvas in console i can see that my hundred particle objects inside particles array now have values for x and y coordinates so we are creating 100 particle objects and placing them inside particles array now i would like to cycle through this array and trigger update and draw methods for each individual particle making them move around and draw them i create a custom function called handle particles to do this for me i create another for loop here this time my for loop will cycle through all particle objects inside particles array since i filled it with hundred objects particles array length is hundred each individual object in that array was created with particle class constructor on line 26 which means they have access to update and draw methods we gave them i want to trigger update and draw for each particle as i cycle through the array i do that by saying particles array i dot update and particles array i dot draw like this as the for loop runs i is at first 0 so update and draw will be triggered for object with index 0 in my array then i increased to 1 and update and draw will be triggered for object with index 1 this will run all the way to 100 as i variable increases because my particles array contains 100 objects its length is 100 i take this custom handle particles function i just created and i call it online 64 inside animate this will make javascript run through the entire particles array over and over for every frame of animation it will trigger update and draw on every single of my 100 particle objects this will make the move on canvas like this we have created a simple particle system this is a solid codebase and from here we can take it in thousand different directions there are so many different effects we can make from this code going from here i will show you how to build a really beautiful one right now but before we go ahead if you want you can make a copy of this codebase and save it in a different folder so later you can use it for your own creative coding experiments i'm about to show you how to do really cool things with color movement and how to create our first very simple algorithm click the like please all our particles are the same size because here on line 43 we are using hard-coded value of 50 as circle radius let's instead use this dot size property from line 32 to draw randomized sizes let's make them bigger maybe a random number between 1 and 16. how about we make the particles shrink as they move around on line 39 inside update method i say if this dot size from line 32 is more than 0.2 decrease this dot size by 0.1 for every animation frame now they start big and shrink down i had to create this if statement checking if particles are larger than 0.2 before i reduce their size because if i allow this value to go below 0 and then i would pass this dot size with negative number to canvas arc method i would get an error you can't draw a circle with negative radius that would break our code now i would like the particles that shrink below certain size to be removed from my particles array on line 60 inside my custom handle particles function inside this for loop that cycles through every single particle object i will check if particle's size property is less or equal to 0.3 for example if they are this small i will remove them by calling build in splice method on particles array like this when i started with javascript splice method always confused me because it can be used to add remove or to replace one or multiple elements in the array today we will just use it to remove one element which is very simple i will just pass it to arguments the first one is the index of element we want to delete since this if statement is only entered for elements smaller than 0.3 i just take index of current element that passed this if statement check and delete count will be 1. i just want to delete one element at this index from particles array every time we delete one element from an array in a for loop like this since this element can be somewhere in the middle we need to adjust index by -1 otherwise the next element will be skipped and we would get blinking particles every time we remove something because their update and draw was skipped for one cycle this is something we will discuss in more advanced videos you don't have to worry about it right now to check if particles are being correctly removed i can console lock particlesarray.length actually let's console it here on line 62 and i can see length of my array is going down as particles shrink and get removed one by one all the way to zero i want to change how my animation works i want new particles to appear under mouse and fly away from it inside particle class constructor i comment out lines 30 and 31 and i uncomment lines 28 and 29. now each particle's initial position will be under the mouse my init function runs on the first page load and it creates 100 particles let's remove it i actually want to create particles in a different way whenever i click somewhere on canvas i want to create a set of particles there like a small particle file work on line 19 inside click event listener every time click event is triggered i will take particles array and i push new particle to it same as we did before in init function that works what if i want to create more than one particle whenever i click i can create a for loop here and let's run it 10 times to create 10 individual particles nice that looks interesting let's change color to white here on line 45 i also want to create a trail of particles whenever mouse moves over canvas i can take for loop from line 19 and i can copy it inside mousemove event listener here on line 27. now this is starting to look interesting click like please if you are learning new things today i can make the trail smaller by changing this value on line 27. i can also make it much bigger but keep in mind that at a certain point it might be lagging on weaker computers if you draw too many particles if you want your particles to leave trails as they move easy way to do this is to go down here to animate and comment out clear rectangle which clears old paint from canvas for every animation frame rather than clear and old paint completely i will just make it fade away slowly by drawing a semi-transparent rectangle on top of canvas over and over if i set fill style to black and i call canvas fill rectangle method to draw a rectangle over the entire canvas from coordinates 0 0 to canvas with canvas height it will look the same as if we are clearing the entire canvas because that rectangle just covers the old paint look what happens if i change black to rgba so i can give it some alpha opacity let's reduce the number of particles on line 27 and down on line 69 i reduce opacity further how about 0.1 now we can see some trails particles now appear under the mouse when we move it around the canvas and also when we click we get a burst of particles let's reduce opacity even further i will try 0.02 now you can really see the old paint and particles are even interesting trails behind white is a bit boring how about we give it some colors instead of rgba i will use hsl color declaration i will explain it in a minute up on line 6 i create a global variable called u and i initially set it to 0. i will use let keyword here because value of this variable will be changing as we cycle through color spectrum inside animate on line 73 i will increase u by one for every animation step u plus plus on line 49 inside the draw method on particle class i replace white with hsl color declaration hsl is just an alternative way you can declare colors we have rgb and rgba we have hex colors and we have hsl which stands for hue saturation and lightness the first value in hsl hue is a degree on the color wheel from 0 to 360. 0 is right 120 is green 240 is blue so we are still dealing with red green and blue like we do with rgb saturation is a percentage value zero percent is gray and hundred percent is full color lightness is also percentage zero is black 100 is white so we keep this one at 50 to see full color not affected by light or dark on line 49 i will concatenate hsl color and i insert my ever changing hue variable here like this saturation will always stay at 100 and lightness will be 50. although if you want you could also use the same technique to dynamically change these values as well for different effects now as a hue variable increases for one every animation step we are cycling through the color spectrum when hue reaches 360 the whole circle when it goes all around the color wheel it starts from red again so you can just increase to higher and higher numbers and it will still work so doing this recolors all particles dynamically to the same color what if i want particles to be assigned a color when they first appear and then remember that color i think that might look even better on line 42 i add new property to particle class constructor called this dot color and i set it to my dynamic hsl color declaration from line 50. on line 50 i set ctx fill style to this dot color property from line 42 doing this will assign particles individual colors at the point when they are created by the constructor and they will remember that value now i can create this nice rainbow effect on line 74 i can change the speed at which we cycle through color spectrum look what happens if i say hue plus equals five colors change really fast if i change the value to 0.5 colors will change very slowly so this is how you can display fading trails behind your particles for the next effect i want to delete old paint we will be entering a more advanced territory now and we will really bring this effect to the next level i will explain the algorithm and what exactly it does but if you are a beginner don't feel bad if this next part feels more challenging this is just a canvas introduction course i will cover these techniques again in other videos and with practice it will become much easier i comment outlines 71 and 72 and i uncomment line 70 to clear old paint from canvas and hide particle trails all we see right now is just the current animation frame i want to add constellations effect where each particle connects to all particles within a certain distance around it with a line most people use libraries to achieve this effect but here we write everything with plain vanilla javascript because we want to understand how it works under the hood so we can modify it and create our own variations as i said right now we are entering more advanced territory so don't feel bad if it doesn't make much sense at first once you have solid understanding of the basics of canvas animation we went through until this point adding algorithms and other cool things on top of your effects will become much easier if it was easy on the first try everyone would be able to do it as with everything it takes practice to master something and that's a good thing constellations effect is achieved by comparing every particle within particles array to every other particle in that same array we calculate their distance and if they are within certain range from each other we draw a line from particle a to particle b that's all but how do we translate this into javascript on line 57 we have handle particles function that cycles through the entire particles array for every frame of animation i will create a nested for loop which means a loop inside of another loop and for every particle in the array we will cycle through all remaining particles in the same array comparing their distances so in this nested for loop i can't use i as a variable name because i use that in the outer for loop i will call that variable for example j and initially i set it to be equal to i index from the outer for loop i do this to make sure we don't unnecessarily compare particles we compared in previous loops it might be a bit difficult to visualize it but this is how you do it let's just write this code down and explain it when we can see the whole thing as long as j is less than particle's array length increase j by 1 j plus plus to calculate distance between two points on canvas in our case two center points of our circle particles we can use pythagorean theorem we have particle i and particle j here and we imagine a right angle triangle between them this side is distance between their horizontal x coordinates this side is the difference between their vertical y coordinates and we know this angle is 90 degrees distance between the particles is hypotenuse of our imaginary right triangle the longest side opposite to the right angle since we know this side and this side and we know this is right angle 90 degrees we can use pythagorean theorem to calculate this side which is the distance between particles so that's the theory let's translate it into javascript first i have to calculate this side i will call it dx distance between particles on horizontal x-axis it's very simple it's just x-coordinate of particle i from the outer loop minus x-coordinate of particle j from the inner loop difference between their positions gives us this value i do the same for this side i call it d y distance on vertical y axis so now we calculated these two sides and we know that angle between them is 90 degrees since this is right angle triangle we use pythagorean theorem to calculate size of hypotenuse of this imaginary triangle between particle i and particle j the formula is square root of dx squared plus d y squared instead of doing dx squared i will just do dx times dx plus d y times d y it's the same thing so now our distance variable holds value of hypotenuse of this imaginary right triangle this hypotenuse is the actual distance between particle i from the outer loop and particle j from the inner loop now i notice here on line 66 variables in the inner loop are supposed to be called the j not i now it's correct i get error in the console on line 67 it is trying to calculate dx but that particle has already shrunk and was spliced out of the array on line 62 so it doesn't exist anymore i will just swap these two if statements so that it compares distance first and then it removes small particles that should fix it i think so we are calculating distance between all particles on line 64. what will we do with that value let's check if distance is under 100 pixels and if it is i will draw a line from particle i position to particle j position connecting them together as i said in the beginning when you want to draw a line on canvas you need to start with ctx begin path then i call ctx move2 method this built-in canvas method expects x and y coordinates on canvas and it will set this position as starting coordinates of the new shape or mu line starting point will be x and y-coordinates of particle i that passed my distance check on line 65. now i call built-in canvas line 2 method which will also expect x and y-coordinates and it will draw a path from previous point we defined in move 2 to these coordinates we passed to it now x and y here will be coordinates of particle j that passed distance check on line 65. now i call ctx stroke to actually draw the line on canvas it works but we didn't declare stroke color so it defaults to black on line 67 i set stroke style to color property on particle x this value is coming from line 42. width of these lines defaults to 1 pixels what if i want it to be dynamic on line 68 i set ctx line width to be equal to particle size up inside particle class constructor i remove lines 37 and 38 we won't need them anymore and i take this.size property here from line 37 and i use this value to determine line width on line 66. now width of lines connecting my particles is equal to radius of my particle circles so the line width should be exactly half size of my circles this looks really interesting and maybe you should play with these values to see what happens it will help you to get comfortable and familiar with different canvas drawing methods and its global settings at this point we are just experimenting and trying to make it look clean and interesting i think the lines are too thick let's try size divided by three how about size divided by 10 i love this constellations effect it is not that hard to achieve if you go over the code we just wrote a couple of times and really try to understand what's happening i get this weird behavior where lines are randomly being drawn from outside canvas area let me pause when it happens here this shouldn't be happening hmm strange let's try to close path on line 70. i don't really know why it's doing this but i noticed it started when we used really small numbers here on line 66 so i suspect it has something to do with line with being too small at some point and it's glitching out i might be wrong if you know what's causing this let me know in the comments please i will fix it if i said line width to one so the glitch is gone now but i would like it to be thinner line width set to 0.5 actually looks really nice how about we go to 0.2 beautiful if you are a beginner and you manage to code along all the way here and build this effect with me you should be really proud of yourself we went from canvas basics to advanced animations in one tutorial this is not begin level javascript anymore let me know in the comments if you finished you can just type yes or i did it i have a playlist i specifically picked with more beginner-friendly tutorials or if you feel more confident and want to try some of the advanced effects check out some of the videos in my vanilla javascript creative coding series or in my game development playlist great job today hope you had fun and learned something new see you soon [Music]