 I'm here to talk to you today about sort of like the natural things that you've been seeing. So we've actually had a pretty good lead up into this discussion. This is actually going to be pretty code heavy. This is the first time I've actually ever actually coded in front of people at a conference before, so it'll be kind of a new experience for me. If you want to kind of code along, or I actually would encourage you to pull out your laptops and do this, you can go to that link on the bottom left, mkeys.org slash talks. I also tweeted out a link to these slides. There's a lot of code examples and everything that you'll be able to use. So a little bit about me. I'm an instructor at a code academy called the Iron Yard. We teach people how to program, get them into junior and mid-level developer positions from 0 to 60 in 12 weeks. I focus a lot on the DIY. I'm not a huge fan of talking about just frameworks because paradigms are super important. And I think that's kind of some takeaways that you can get from this talk. It's just sort of like the bird flocking and all the different animations there. It's kind of hard to put that into perspective if you don't know how that rendering happens in the first place. So this is sort of the coding environment you can actually get. And I can make sure that this is a little bit large there. So this is the first example. So we're going to have a lot of really boring just numbers and text on the screen. And then we're actually going to have some canvas. So first, by abstracting out the pattern, the first 10 slides are going to cover stuff that are going to power all these sorts of games and other things that you can use in the second half of the presentation. So we have a function. And this is actually a live coding environment. It's ECMAScript 6. We have a kind of a function called Particle. And this Particle function has a couple of default parameters. So this is pretty heavy JavaScript talk here. We have a position, which is by default a vector. So anytime I say the word vector, I'm going to be mentioning an array of size 2. That's it. And it's using a random function. So at any time if I create a particle, I'm going to be creating a random position. I'm also going to have a velocity. That'll be by default 0. And acceleration, also default 0. So we're going to think about this in vectors. So we're going to be a lot of vector math today. I've got a simple function called logum. This thing actually takes an array and prints out the text. You're actually seeing that example text along the right-hand side. So that's being actually interpreted as I type. We have an array here. And this array is just using some ES6 methods because JavaScript, you have to create an array and then fill it with something that's truthy. And I'm just mapping those into particles. So right now it's just an array of size 1. But I can easily make it 10 or 20 or something like that. So this is kind of a general thing. And this is going to appear on every slide after this. So we've got now sort of like this render loop happening. So I've got the same code on the screen. But I've got a little bit extra. So scrolling down, I've got this nice little update function. This update function actually takes a particle and just does something to that particle. So instead of modifying something in memory, instead I'm going to try to do everything I can with this ES6 destructuring and restructuring syntax. So if I pass in a particle to the update function, I'm going to destructure and just pull out the velocity and the position from that particle. And I'm going to add the velocity to the current position. So if you have a velocity, if you maybe 10 times add velocity to it, it changes the position. So if we go down to the general basics, you're always going to have some kind of game loop. Anything that's going to have animation needs to run. And you'll see here, this is actually just using request animation frame. So if it hasn't been mentioned, that just kind of syncs up with your browser's refresh rate. So typically it'll run about 60 frames per second. So I'm running this function 60 times forever for the existence of this thing on the page. And I'm just mapping all the particles that I've created into a new set of particles. So I have one array of objects, and I'm mapping them into a new array of objects. So very simple. And at the bottom, I just have this little set interval. So I'm saying I'm just going to render out the code on the right-hand side. So that log function exists in this coding environment that gives me the ability to just kind of display some text output. So let's just change that request animation frame a little bit. We're going to create a little utility function. So we have this looper function. And this is actually going to return a function that we will always run. So if I call looper and give it a callback function, it's basically going to run that 60 times a second. And it's going to pass in how many seconds have passed since the last render. So using it is very much like this. And we have these update loops, where if I have maybe just one right there, that becomes just something like this below, which is just printing out this timestamp. So I have a new date. And I'm saying 60 times a second, I'm going to create a new date. And then print it out. Pretty simple in concept. Now, you might wonder why I need a utility just to give me a loop. And that's because a lot of things we're going to do. We're going to create many infinitely running loops in our program. So we're getting back to the loop. And now I'm including the particle in it. So we've got the loop. We've got the particle. And we've got our logum method. And we've got this random that gives me a random number between some minimum and maximum. So this particle's array is just being mapped and printed out. So if I look at the code below, I'll take a look at update in a second. We just have this kind of world friction. So friction is something that affects the force of something moving. We'll kind of look at how that affects it. But basically, I have a loop that's running 60 times a second. And I'm creating a brand new array 60 times a second. So I'm mapping every particle into this update method. So in other words, I'm always going to have an array of objects that look or shape the similar. They have a velocity, have a position, and acceleration. So when I update that particle, it's going to return something that looks the same. It's just going to have maybe a slightly altered position, maybe changed velocity. And again, just the loop at the bottom, the set interval here. So if we look at the update function, this is kind of one of the powerful things about ES6. I don't have to use object.extend. I can use destructuring pretty well. So this update just takes a friction, and it takes a particle. And instead of just adding the velocity, I've now taken into account acceleration. So acceleration changed the velocity. Velocity changed its position. I'm also multiplying it by some number. So 1 minus friction. So a friction is 0.1. It's going to multiply it by 0.9. In other words, this is going to be the thing that gives you that natural feel in motion. Everything kind of have this inertia eventually comes to a stop. So then the position gets set. We've updated the velocity. We've updated the position. And I've actually just gone and set the acceleration back to 0. So if I need to have constant acceleration, like gravity, I'm just going to put that into an infinitely running loop, just like that looper method. So in any case, I can have the ability to manipulate this array of particles through this series of calculations. So if I have this looper, I can just simply give this guy an ability to accelerate. So I'm actually saying, hey, let me accelerate. And from you looking at me, I'm saying, accelerate this direction. So I have a 2D vector. This is accelerating in that direction. So it's making those numbers crawl quickly. And you'll see that if I do things like if I manipulate the friction to be very low, the numbers are actually going to speed up much faster because there's less friction from the same force. And if I make that friction when it breaks, oh, hello, Mac. There we go. So if I have so much friction that it can't even move, the acceleration does nothing. So actually, this applied movement on that particle doesn't make it move. That is where we start to simulate movement and acceleration. So again, same code. I'm just adding more as we get down there. So I've got the world friction. I've got the same looper. This is our update loop. Any animation you're going to run has to have this. This is the one thing that's going to update position at all times. And I'm kind of looking at a few new functions here. So I've got a function called scale. Scale can take a 2D vector. And it can multiply it by something. So 1 in 1 scaled. If I had that same acceleration, it becomes 2 in 2 if I multiply it by 2. I have this add method. And I know this looks very lispy. So we can easily, just as much, log adding 1 in 1 and 2 in 2. So adding 1 in 1, 2 in 2. And this is very attic. So I can add 1 or 2 or 100 different vectors together. So it's an additive thing. Now having that feature, if I'm looking at, you see how these numbers are sort of changing? I have this constant kind of timestamp being printed out as before. But in addition to that, every second, let me see here. So every second, these particles are being mapped into something that's returned by apply force. So I'm applying some kind of force to a particle. And this apply force, you can see the signature there. P, M, and A. So particle. What is force? Force is mass times acceleration. So sometimes I have some kind of mass that I can hold in data. Sometimes it is acceleration. Acceleration is that direction, the vector that tells me the direction. So I have the ability to apply a random acceleration to every particle. So right now there's two particles. And if I apply the random acceleration, they're just moving in some direction. So if I want them to approach some object, so right now we're visualizing something. I've got two particles, and they're going to move towards it. I think I'm like gravitational pull. So quick recap. So we've got a particle. It's just a function that returns an object. It's very simple data. So it's primarily just three things. We can add data and use ES6 data, sorry, destructuring to kind of build up extra levels. So I'm not dealing with any problems with taxonomy of functions and prototypes at all. And we can also hold other data in there. So that makes it possible. Then lastly, of course, is just the idea of applying force to a particle, which changes the acceleration, which changes the velocity, which changes the position. And that's because of this update loop that we have. And this is where things start to get a little mathy, mathy, and that kind of gives you a bad taste. So these are all the different functions we'll need for the rest of this. We have our friendly random function at the top. We have a vector method. So instead of having to make arrays, let me just be able to call vector. And if I don't give it any parameters, it'll create a random vector. Perfect. In trigonometry, we're going to probably need to convert degrees to radians and radians to degrees. We have our add and we have our subtract. So we can get the difference vector between two things. We have other functions against scale. We have the dot product for things like projections. So if you get into 3D vectors, this is typically what you use. And you have the ability to also rotate things and kind of move them in different directions. So I have a vector that's just facing up. I can rotate it 70 degrees, 100 degrees. And this is the important to normalize. If I have a vector of any length, if I said I'm going to move five feet in one second, my magnitude could be five feet. Well, a normalized vector or the unit vector is something where its magnitude is one, but it's in the same direction. So I can take any vector and then scale it by one over its magnitude. So these two things, magnitude and normalize, you're going to find almost everywhere the rest of this presentation, because it gives you the ability to point something at something else, like the mouse. So a few other example functions down here. Heading, it can tell you when facing from north, right? If I'm facing down this way. Because in canvas, y grows downwards, right? Positive is down. So if I have a one-one vector, I'm probably going to look at 90 plus 45 degrees. So that's the heading. So I can look at all these different examples of just logging out simple vectors. I can add those two vectors together. Again, quite simple. And I can even scale some of these things. So I can put that down, just manipulate the numbers. So the normalize is the fun part. If I normalize x, x is one-one. So it's just kind of like a simple vector there. If I normalized it, I have these weird numbers. And I think like, how is that useful to me? Well, that's because, again, going back on the magnitude of a normalized vector, it should be about one, the magnitude. And just in case you're doing anything where you have an object bouncing off something else, when detecting collisions, we'll get into that. You have the ability to actually calculate the angle between, so that you know how to refract something. So if I have a zero-one and a one-zero, that's 90 degrees. So moving things back to this applying force. We're going to want to have some kind of mass and acceleration. And the mass, when multiplied by the magnitude of the acceleration, we're just going to add that to the acceleration. So if we have a function, I can give us that. So again, here's all our vector methods. Same things we covered earlier. Then here's our particle. Friendly particles never going to change after this point. We have our same update function, still taking the acceleration, applying it to the velocity, taking the velocity, applying it to the position. Same apply force method. This guy is going to take that mass. We're going to scale it. We're going to scale the acceleration. And then we're going to add that to the existing acceleration. So if I have something that's already in motion, I can maybe just push it. It's like a ball that's rolling. If it's rolling one direction and I kick it, it's still got some difference there. But I'm just adding to the acceleration. And I'm letting friction do the work. A ball in a soccer field, perfect example. We have our looper. So we're including a loop now, the game engine. And we've got now this more elaborate logging method, just to print more details to the screen. So we've got an x and a y. And things are just kind of moving around. It's kind of confusing. So you notice on the right-hand side, there's something called mouse. Mouse is just this thing that is moving from 0, 0 to 400, 0 to 400, 400, 0, 400. It's just moving around in a square. So if I have this function box, box is just going to wrap around particle. It doesn't have to be a subtype. It doesn't have to be something on the prototype chain. It can just be a simple function, a simple function that returns everything from particle and a mass. So I can create a bunch of boxes. So right now, we're looking at one. I can easily make it 10. I can make it 100. Doesn't quite matter. So these physics updates, same thing. I have the update loop. Got some world friction. We've got the looper, returns a function. I invoke it. It's like an iffy. So there's the mouse code. This mouse is simply a vector. Again, just an array of size 2. And this set interval code is just making it stop between all the different corners. Line 122, these different corners here. So this looper method. Here's kind of neat stuff about this. I already have a looper going on, but it's not going to kill the app if I run another one. That's the cool part about this request animation frame. So I can map all the particles. And what I'm actually doing here is subtracting, getting a difference vector between the mouse and every particle. So that gives me kind of a direction. But it's not completely a direction. It's not magnitude 1. So to make it a direction vector, I normalize it. So subtract, then normalize. It's very common as well, all the movement towards something. So when I apply a force on a particle, I'm including the mass. The mass is like the multiplier on the force and in that direction. So the bigger an item, the more force I'm applying in a direction. But it's still just an object. So I'm looping and looping and looping and looping. So our draw updates are just kind of giving this same structure there. And you'll notice that the mass and the velocity stay the same. It's the same particle. However, the heading sometimes changes. And the mouse, when it changes, you'll see x and y sort of approach that mouse. And this is all just the simple constructs that we have without any UI, taking the magic out of it. So this is a canvas representation of the exact same code. So instead of logging it out, these things are actually approaching some theoretical mouse on a canvas element. So that's the exact same code. So the cool part is I'm persistently telling all of these particles to kind of approach the mouse. I'm mapping them 60 times a second. And you might think it's very wasteful. I'm just creating a bunch of objects to be thrown away a fraction of a second later. And that's not actually true. Turns out browsers are really good at optimizing this, especially when they're simple objects. So that same code, all I had to do was change all those set timeout on the mouse. I took maybe six or seven lines of code, and I made it potentially one line if you expand it. And I'm just changing the mouse to be a 2D vector based on my own mouse. Then I have the ability to play around with these things and actually create these very beautiful systems where these flocks of birds are suddenly possible to animate. So having all these different abilities is something that gives us a lot of power and flexibility, because we can use these same constructs to build games, to build physics engines, to have collision detection, all such stuff like that, based off the same things that we could look at. So the same thing kind of happens. We don't have to change the drawing method. You'll typically see a lot of canvas simulations and things that show you kind of like a hierarchical structure. You might have a pointer or an arrow and it has a different draw method on it. Well, the data has to be different. If you separate the data from the presentation, the only thing that had to change was how I'm actually drawing something. So the only thing for this is I'm creating a bunch of particles that never move. So these particles that never move then can just point. I can calculate sort of the distance, or the difference vector, and normalize it. Then if I need to scale that, if you scale a normalized vector by a flat number, like 20, then I have a bunch of needles that are 20 pixels long pointing towards an object. So these needles don't actually need an update loop. This is the one example where you don't need that update loop, because they're not moving. The only thing that's really changing is how I'm drawing. If I don't need to change representation of a particle, I don't have to do much else. So sometimes we need to consider things like, what happens if I want to touch the floor? I want to know when I'm actually hitting the floor, collision detection in video games. I have the ability to kind of create these simple circles, and I can animate. Again, it's just gravity, stuff like that. So we have an update loop. And I'll show you our boilerplate code now. This example has an orb. So pretty much every example just wraps around this particle. I just give it a different name for context. So take a particle. I can give it a mass and a position x and a position y. So these orbs, I can create something. I can map this orbs array into an array of size 1 and then an array of size 2 when I click on the screen. So this mouse down, for instance, is pushing an orb onto that array. Simple enough. So there's a render loop happening at the bottom. So we do have update. And this thing is saying, OK, every time I find an orb, let me take its acceleration, change its velocity, take its velocity, change its position. Still those basics. And then I have this thing. There's a second loop. And all this is doing is perpetually applying gravity. It's a simulated gravity. This is applying a force on every particle with a magnitude of 3.2. It just felt like a right number. There's no reason I chose it. So I could easily make it 32 and make the balls fall a lot faster. So the last part, again, is this looper. This is the collision detection. That's it, right there. So each orb, I'm just checking its position. If the radius of the orb has hit the floor, I flip the velocity, just invert it to look up. The acceleration is still being applied. Gravity is still acting on this object. So I can flip the velocity just on the y-axis and then make sure maybe the position is at the floor. So this is just the draw code at the bottom. Again, another looper. I'm not doing any updates. I'm just drawing in canvas on this one. So I have three or four different infinite running loops. So that's fine and dandy. However, when animating, a lot of times we don't really know how fast the application is going to run. So in physics simulations, there's this one part about looper is that it tells me how many seconds have passed into the input of my callback function. I don't want to animate pixels per frame. I want to animate pixels per second. That's simulating a revolt scenario. So the only change I have to do to actually get this to have some extra stuff to show you of it. The only thing I did was I took the time. So I actually used the time input to my callback. That time is a number of seconds that have passed. So if I only have a fraction of a second that has passed, I'm basically taking that pixels per frame and turning it to pixels per second. So I'm multiplying by a number less than 1. So 32.174 is actually feet per second squared. That's gravity. So I have a more natural kind of description. It's actually moving 32 pixels per second. So that collision detection can be taken. I know this is ugly, too. Just bear with me. The collision detection is just a bunch of different checks. It's the checks for touching the left wall, touching the right wall. In addition, I can make checks on each orb each other. Is an orb conflicting with the space of another orb? If it is, calculate the difference vector, normalize it. That gives me a direction. Then turn it around 180 degrees. So invert it. So that calculation lets me change the velocity outwards. So then I have actually pretty cool systems that can then kind of apply to each other, too. And it's all built off the same thing, which is really cool. So then it's like, OK, what about video games, user input, and stuff? Let's start with drawing images and everything. So instead of 50 planes, you'll see this a lot in my code, is I have an array of objects I'm going to draw to the screen. And a lot of them are randomly generated in paste. That's that beauty of the random function. Let's just start with a measly one plane. There's actually handling of the key down and key up. So in games, there's always this kind of live pressed state. On key down, I have something true. On key up, it's false. Just simply by that, I already have some kind of engine that's checking the values and applying some force. It's persistent, persistently applying thrust to an airplane. So I can kind of fly this little guy around. And the same forces are the same things that are happening elsewhere. So the drawing, it's just objects. I'm just taking a bunch of objects, mapping it to new values, applying some force to the acceleration, some acceleration to the velocity, some velocity to the position. So the biggest thing about this change was the drawing code. So I can also kind of change the plane. So I kind of like different planes. So let's choose stuff like that. Now, if I go back to not just having one plane, let's do 100 planes. They all have different mass. So there is actually, you can see here, this plane function that builds out a particle. It gives a random image and a mass between 5 and 5,000. The greater the mass, the more force it takes to move the thing. So I can have all these guys kind of, it's pretty awesome. So in the cool part about this is how fast it actually works. The fact that I can have any number of particles, I can create all these different objects and suddenly just trash them a fraction of a second later, only to create them all over again and draw it to the screen at a very fast frame rate. It's pretty cool. So it gets better. So we can have objects interdependent on each other. Get on Mac again. So I can create the cloth physics and everything that kind of like manipulate movement. Audio video? Someone? Good old caffeine did not work. Man, live presentations. They're hard. All right, so all the same code yet again. I'm building up this basically the library for a game or anything else that you want to build. And if I have just two chains, I can do 20 if I want to. And I can have kind of like a simulated cloth. And the only difference in how this is changing is the way that I'm applying the updates. So I have chains, chain objects. These chain objects have a bunch of links on them. And each of the links gets the forces applied to them. So the links have gravity applied to them that pulls them towards the ground. The links have tension applied to them that pulls them towards the parent link. The links also have some limitation on their max length. There's some kind of physical property in the real world that tells us we can't stretch something any further or it breaks. So I have yet again several loops. So this is right here the update. And the update has to be a nested loop because I'm looping over chains and looping over the chain's links. But it's still pretty fast. Because I'm only mapping them to straight up objects again. So applying force, yet again it's still gravity. I have a check for the position of each link. So if the link is within 100 pixels of the mouse, then I apply a force in the opposite direction. So I push it away from the mouse, which kind of gives it that nice little cloth effect. The only thing I have to do is if I wanted to model this as an actual cloth, I just have to connect all the child links and still apply force. All works the same. So many examples. Y'all are given a treat today. So this is sort of like a spring or tension, okay? The bottom area is just the drawing part, right? So I have points and a single red ball, okay? The point is something that I can draw on the screen, but the point is just becoming an array, right? So I have a ball and I have points. The point is just a ball of size 10. And I can draw each of these points in the drawing code below, it's little gray squares. I can have mouse movement. So on mouse move, if the mouse is down, I can change the position of that point to the mouse position, right? All these vectors going back and forth. So I can kinda move this guy around and there's actually a tension, tension implied. So each of the three points are pulling the ball toward it. So that tension again is just yet again another looper method, right? And here it is. So at each point, if there's multiple red balls, apply a force in the direction of the point on the red ball with a magnitude that has a multiplier of the distance. In other words, the further something is away, the stronger it pulls, it's tension. So if I consider only having one red ball and three points, I could easily make this guy like 30 points, but they're all gonna act the same, right? And I can have, let's just say five red balls, but they're all gonna be kind of pulled to some center area because I have the same force being applied on all of them, even though they start at random positions. So the system sort of solves itself. And there's particles, so you probably see a lot of this kinds of stuff. And lots of colors and pretty things. Code pen is great for this stuff. So this is, instead of applying gravity, I'm applying an inverse gravity. All right, there's very little friction. I've set the friction kind of lower. So that friction instead of 0.95. So let's just say this is a flame, okay, just to cover this. So again, we're just kind of taking a particle and adding some extra data to it. So if we got some size, particles start at a random size, but then they also kind of get smaller as they grow and flow upwards. So the mouse move again is just changing that mouse point. And I have a looper method down below that's just pushing a new flame onto the array. So the friction here, we're looking at a pretty low number. I can easily make that a lot higher. And these things have a much harder time kind of getting through a very thick, humid air. All right, so friction and air is a lot lower. Now when I'm applying a force, I'm looking at something like simulated wind, right? So light particles, they might get moved in a random position this way and that, right? So this random function is coming in use a lot. This is what makes things pretty. So I can make, you know, I'm able to take a little bit of left breeze or something, right? So I can apply random methods to just kind of move it a little bit, right? So it kind of looks like a little bit of like a flame in the wind. So there's some simple checks that I'm doing, right? Just to actually make it more usable. If a particle gets so small, it never reaches the top of the screen. Or if it reaches the top of the screen, I can't draw it anymore. So I just filter all those out, right? Create a brand new array of those filtered out. So notice I don't use low dash or any kind of for each, right? Everybody tells you that ES5 prototype array methods are slow. If I can do this with ES5, it's purely ES5 prototype methods. I imagine with some optimization, this could get even better. So you'll see the loop here for adding a flame. You can see the size getting reduced. So there's a lot of neat effects you can do with this. So 60 times a second, this thing is being cut down to 99% of its size. So if I move that down to 0.9, sort of like this little wand or something, I don't know, it kind of looks kind of cool. I think of like a video game HUD display or something. So you have the ability to kind of mess around with a lot of this really cool stuff. So the drawing code is simply changing the color that the circle is drawn based on the size. And that's it. So this is just in Canvas, or this talk was supposed to be just Canvas. But the same ideas can be applied to WebGL. So I'm no master at WebGL, and I won't say that. But using the same looper method, I can use vanilla JavaScript to talk to vanilla WebGL, no frameworks. And I'm animating three vertices kind of around on the screen. And the cool part is if you're including WebGL, you can create shader methods. So based on the position of the mouse, for instance, I can actually shade and add all such really cool calculations that are post-processing effects. Using the same engine as before, I then don't have to do anything else, but add some extra power to it, right? Give it some GPU to help it out. So you can actually see my vertex and fragment shaders for people that are familiar with WebGL, just as ECMAScript six strings. That's the wonderful part about ES6-2 is that the back tick string gives you multi-line support, which is a blessing. So I can easily manipulate the fragment, just like one might, looking at other stuff. So I can manipulate the position and everything else post-processing-wise. So when being able to include things like that, the world sort of opens up, right? Starting with the purity of the system and then not trying to add too much complexity, but just sort of changing how we approach application of constantly changing values, how the animation works. So this last guy is kind of just for fun. You know, like there's all sorts of shader code you can find as well that applies post-processing effects to any kind of thing you pass into WebGL. So you can calculate the normal vector, which is a flat surface, it's something that's orthogonal to it. So if there's a collision or something beneath it, you can cast a shadow. Cool stuff like that. So takeaways, if I don't wanna code all this other stuff, what can I take away if I'm not doing graphics programming? And if I am doing graphics programming, how does it help? The ES6 syntax, I was not trying to pre-optimize the code. It was very blatantly memory unfriendly, using objects and throwing them away at will. So the spread operator and destructuring and restructuring of objects helped me organize the data as something simple instead of building out that taxonomy of prototypes and mixins and everything else that can get in the way of solving the actual problem. Simple concepts like applying a force that changes the acceleration, that changes the velocity, changes the position, right? It's a constantly running loop. So you can have multiple render loops too. Some things can apply force. The only time I ever used the time input from a looper was to apply force. Everything else is in a cascade through the system and just change the acceleration, velocity, position, et cetera, right? It already knows relative to the time that has passed since last render. So getting through all that, I have a lot of resources and other things. I've spent probably more time than I should admit, looking at all this. There's lots of great material out there. I'm really standing on the shoulders of giants here. So a lot of other people have written some good material. And like I said, you'll see lots of examples on code pen, optimizing drawings and everything else. And then I'm blatantly disregarded all of it. So with that, thank you. I appreciate it.