Animating with the JavaScript Web Animations API | Ben Frain | Skillshare

Animating with the JavaScript Web Animations API

Ben Frain, Author, Developer, Teacher

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
23 Lessons (1h 59m) View My Notes
    • 1. Introduction

      1:19
    • 2. The Project Build

      1:30
    • 3. Why not just use CSS?

      10:46
    • 4. What even is an API?

      1:49
    • 5. A Simple Web Animation API Example

      8:00
    • 6. Project Refresh

      1:32
    • 7. Basic Setup

      3:47
    • 8. Creating the Stage and Controls

      9:56
    • 9. Web Animation theory: Keyframes

      5:38
    • 10. Timing Options

      6:07
    • 11. The Same Animation made with CSS and JS

      5:52
    • 12. Adding Animations Together

      5:28
    • 13. WAAPI 13

      4:22
    • 14. Animation File Overview

      11:57
    • 15. Writing the Animations

      4:11
    • 16. Sequencing Animations

      4:51
    • 17. Callbacks and Promises Basic Explainer

      5:36
    • 18. Pausing and Restarting Animations

      4:08
    • 19. Refactoring Our Code

      9:33
    • 20. No More Matrix

      2:30
    • 21. New Animations mid-transform

      7:16
    • 22. Committing Styles into the DOM

      1:41
    • 23. Conclusion

      1:33

About This Class

This class teaches you how to animate on the Web using the JavaScript Web Animations API.

You'll learn how to transfer what you already know how to do in CSS, into JavaScript and then add extra capabilities like pausing and playing animations, starting one animation half way through another. Combining different animations together and synchronising a number of animations. All things you just can't do presently with CSS alone.

We will start by re-making some basic CSS animations with the JavaScript Web Animations API, then once we get through the fundamentals, we will start making our project together — a interactive set of sequenced animations.

By the end of the course you should have a solid understanding of how to animate on the Web with the JavaScript Web Animations API.

Who is this class for?

You don't need to be a JavaScript expert to use this API — I'm not!

However, if you are completely new to web development, this probably isn't the class for you. I'd expect you to know how to write HTML and CSS and have a basic understanding of JavaScript. If you know what a function looks like, and how to write a click handler with 'addEventListener' I reckon you will be fine!

Transcripts

1. Introduction: Simple animations are easy enough with CSS. But as soon as you want to animate a few things at once or in sequence, it can soon become problematic. There's no simple way of CSS to say when this animation is finished, run, this other one, for example. However, that is something that you can do easily with the JavaScript Web Animations API. And that's what we're going to learn about in this course. Now, if you're a complete beginner with web development, this probably isn't the course for you, but if you know HTML and CSS and have a moderate understanding of JavaScript, I think you gotta do just fine. However, I am getting ahead of myself. I'm Ben Frain, a web developer and author of the best-selling Responsive Web Design with HTML5 and CSS. If you take this course, I'm gonna show you how to write animations with JavaScript Web Animations API. And we're going to do everything from simple animations you'd be used to using and CSS all the way to a number of sequenced animations in a piece of interaction that will build together. All you need for this course is a text editor, a browser, and a tolerance for substandard jokes. So get yourself comfy, get yourself a nice beverage. And we'll get started in the next video. 2. The Project Build: Before we build this thing out, I want to show you where we are going to end up. So you can see here on the right my screen, we've got this sort of what I'm grandly cooling the stage area. And we've got a set of buttons at the bottom. And as we click through, you can see where we're running a couple of sequences, sort of Star Wars text scroll that are rocket going across. And you can see that as number of animations running sum together and some also in sequence. So the three of these battle scenes, and you can see our Rocky sort of comes in and goes across. And then our final scene at the end, these are rocket London. The Jets go off. And then after just a short delay, UCL little friend pops up who have lovingly called eddy. What you build doesn't have to be the same as this. It can be this. It could be something similar to this, or it could be something completely different. All is important is that you learn and understand the Web Animations API well enough that you can start moving things around the screen with JavaScript. Now, before we go any further, I think it's worth looking at why we want to do this with JavaScript instead of CSS. Now I'm a massive fan of CSS. Sometimes It's about, about choosing the right tool for the right job. So we're gonna take a look at that in the next video. 3. Why not just use CSS?: Let's have a look at a very simple animation with CSS. I've got live reloading going on here and I've got a tool called prettier, the reformats, that tax does it go? We'll come to that very shortly. For now, we're just gonna make a very simple animation. So she's gonna make, let's give stick a div in the page. We're gonna give it a class of thing. And then let's see if with the power of CSS, we can first of all, make a nice box. On the page. Width, 100 pixels high, 200 pixels, background color. We'll have a nice bright orange. That's just check. We've got R-square, okay? And now we're going to run an animation. So I'm just going to write the animation declaration first and then we'll write the keyframe afterwards. So don't worry about the fact that there's no key frame there at the minute. So Animation, and we're going to call it move, right? It's going to take 1 second and it's to go forward. And we'll go easing out. That's the timing function. If you don't know what 0s in, out is, we will be covering that soon it off, don't worry about that. Okay, so now we need to write the actual move, right? Keyframes. Let's get that little quickly. And we're just gonna go, this is going to move to. So when you use to, in this situation, you can write naught percent 200% or something like that. But it's easier if, if you want to just move on animation to something new. If you write it like this, it will just move straight to where it, where you want it to end up. So in this case, I just want to move our little square. Let's do translate, and we're gonna go, let's go 300 pixels to the right. And I'm gonna move down. And while we're here, let's just change the border radius to 50%. So with a bit of luck, what helps go crazy? And let's change the background color. And we're gonna go to, we'll go to a nice dark gray. Ok, let's see what this does for our fortunes. Whatever Dunya to do doesn't want that at rule or sought to expect it to go. I need to write a key frames move, right? Okay. Because the smiling on me, okay, so you can see we're getting from a bright square, moving right, turn it into a circle, fine. What if we now wanted to wait of a second and then move all circled down and turn it back into a square is a couple of ways you could do this. You could either add another animation to all selector or we could build it into the key frames. So if we're going to build it into the keyframes, Let's look at that first. If we're going to build into the keyframes, Let's suppose we're going to go just copy this down and that's going to be our new. So it's gonna go 0, that it was gonna go 33%. We want it to end up. So 0 is not gonna have any transforms on it. It's not going to have an Ebola radius. This is essentially our starting position, and this is r. So we're gonna go for our bright orange third of the way across. We're looking like that. And then we want to wait there for another 2.5th. So from all the way to 66%, this works in my head of donor for swatch, the work In real life here. And it's going to be the same. Because when we get to 60, 66% through our animation, I wanted to be in the same place. So, so between 3366 is hopefully going to be a pause and then just grab this bit. I'm an idiot, sorry. Let's grab that. So this is going to be all 100%. And then at a 100% we want to still be over on the right. We're going to come down 300. We're going to turn back to a square. We set differently. And then we're gonna go back to our square. That's going to happen pretty quick at 1 second. So I'm just gonna make the duration is animation a little bit longer. So I'm gonna change the 1 second to three seconds. So we should get now something like 1 second across, 1 second pause, 1 second down. Such are done something wrong. There we go. And try that again. Wait down. Well, we p, OK, so that was okay. But let's suppose now, while designers who love what we've done with this square though, they were knocked me out the party, uh, but they actually want 1 second across, two seconds delay and 1 second down. We can work around this couldn't wait. We could, we could change our keyframes. You could work it out, work out where the percentage would be for the, for the pools and then change you book. It starts to get quite difficult to manage. And this is just one animation we're running here. I said before we could do this another way. So let's try that. If we, if we back up to where we were a moment ago, where we've just got to move right animation. Instead of doing this with keyframes, Let's suppose what we did is we made another set keyframes. I'm going to call this move down. And this one's going to do is it's gonna go from MEA, that's not gonna work. So we're gonna go from just to be clear, when we want to move down, we know that we're going to be 300 across 0 down. We're going to be a circle. And we're going to be in the 3s, which is the sort of dark gray. And then by the time we get to complete, we would like to be back and looking like a square. Looking like a square, ideal all the time. 300 Darrow, Xero, border-radius. O, but two. 90. So that will be our keyframes for moving down. So then we could put into here, moved out. And we want that to say 1 second. And we want a 500 millisecond delay. And we want to give a forwards and we'll go ease in out. There's an obvious mistake in here why this isn't going to work. I'm going to run it. And fingers on the poses. You can tell me if you know what it is. Let's just run that from the beginning. Did you see that? It doesn't even get across before it starts coming down. And the reason for that, and this is why CSS, CSS animations can be problematic, is because in an all, in order for all second animation to run, we've got to factor in how long it takes off first one to complete. There's no way NCSS to say when that first one is finished, then do this next one. So what we'd have to do here is we have to go, okay, so our delay, we want you to five, we made a 2.5th delay after it going across. So it's not a 500 millisecond delay, it's actually a 1500 milliseconds, 1.5, so I can delay. So now this should be something more like we want to see. We've got the delay and then it moves down. We've worked around this issue here. But the reality is, isn't a fantastic way to think these things through. Arguably, you could make this a bit easier with custom properties, which you could do that for sure, we could go. Duration is 300 milliseconds. And this, this might help. It depends on your preference or suppose, but we could do duration. And this is also going to be the duration. Duration. And then for our delay, I'm not even convinced this is any better and I'm certainly not convinced he's the sort of thing that's easy to reason about. If you came back to this code in six months time, it would take a bit of head scratching. So it'll be duration times 1.5. No, that's not right. Ok. Closed in the wrong place. That's weird. Hopefully, this will do the same thing and let's just try it. Yeah, okay, so, so that works. Doing it this way. It does make it slightly easier to change the overall animation because instead of having to go in and recalculate or delay, he's generally speaking Here we can show and this write down 1 second. Okay, so we've got a 1 second house. I could delay 1 second down. We've worked around it there and we've looked at how you could potentially make that little bit easier. I'm using custom properties, but there's still no easy way to say rudeness thing than when this thing is finished ruinous. Next thing, when that's finished, run, this other thing. And there's also we've not even touched upon here. If we wanted to pause animations and then resume them, will suddenly make them go back in the other direction. The truth is, CSS just doesn't have a good answer for that. And you know what I'm gonna say? The Web Animations API does have a good answer for it. You're probably aware there's plenty of third party JavaScript animation packages that you can download and use in your project, which you find, there's some very good ones out there. I'm thinking of things like green sock. But the problem is, that's something that you've then got to put in your webpage, the application that you're building. Each and every time you want to run an animation. And it's also, you're having to learn a custom piece of syntax which may or may not be around ten years from now. With the Web Animations API, this is a standard, this is not going to go anywhere. So what you learn with a Web Animations API is going to stand you in very good stead going forward. Hopefully, that's addressed the why we would want to use JavaScript. And let's look at the how we do it with JavaScript in the next video. 4. What even is an API?: Before we write our first animation with JavaScript, I just want to cover off the term API. Api, the acronym stands for application programming interface. All that means for what we're doing here is that there's a JavaScript interface built into the web browser that lets us control animations with JavaScript as it's a web standard, there's a specification that you can go and read. Specifications differ greatly when it comes to web features. So very easy to get your head around and understand others less cell. I find the Web Animations API specification little bit intense. Now, hopefully, if I do a half decent job here, you shouldn't need to go and look at that specification much. Unless you want to, which, you know, that's entirely up to you. I don't judge. Much in terms of browser support. As I record this late 20-20. And if we use, can I use.com type in Web Animations API, then support looks something like this. You've got decent support right across everything you can sensibly wanted to use. Notable absentees, IE 11 and adjunct to version 18. But obviously there are less and less of a concern at this point. There's also polyphenols. If you feel you need to do that, obviously is pretty good already. And it's only gonna get better. That's enough intro. Let's get on with right in our first animation with JavaScript. In the next video. 5. A Simple Web Animation API Example: Right, let's run off first animation with the Web Animations API. We're going to start with the shape that we had a couple of videos ago that we were moving around with CSS. So if you remember, Don was very simple and a single element with a class of thing. And I'm just linking out here to animations ab.js. Now, animations dot JS at the minute is very simple. There is nothing that has just a console log so that you can see that doing something. And the first job is just to get rid of all the styles that we have before that were doing this animation. If you remember. I'm just going to clear some of this other stuff out of the way. So sorry, just once again, we have the square going across ten to a circle and then coming back down. Now, we wanna get rid of Olof animation stuff for me because we don't need any of this stuff. Now. What we have now is r-squared doing nothing. And we're going to remake that animation with JavaScript. And just to show you, let's get the devtools opening so you can see console Jess reporting for duty. We know that all JavaScript files hooked up, no problem. The first thing we're gonna do, and let me use const keyword here to make a variable of sorts to the element on the page. You could use less. You can use VAR for what we're doing. It doesn't really matter. I'd just like to get into the habit of using cons 20 is something that's constant and I'm not going to change. So another document, dot query selector. Don't need to do query selector all because there's only one of them on the page. And its thing, cool is think of thing equals document, query, selector. All. Just to check, we've got that on the page. We're going to do this with everything, but just to make sure this first bits go in. Okay. So you can see here down in the console, we've grabbed all element. Ok, so now we've got it. We want more animated. And so we're gonna go thing. And that the first method that the method that you'll use most of the time, he's animate. Animate. Okay, so I'm principally to animate takes two sets, well, two arguments, don't worry at all in this video, if this sounds like gobbledygook it, we're gonna go over this stuff in a great amount of detail shortly. I'm just going to show you what that same animation that we made in CSS looks like when you do it with JavaScript. The first argument will be an array of key frames. So our first keyframe is gain to be trans form. And you'll notice here that we're using a string for what happens in the transform. So I think it was translate 300 pixels, nothin plot timing functions in here and we're gonna say is gonna take timings in JavaScript. And the JavaScript API is always done in milliseconds. So you might be used to in CSS, say in 1 second is 1S. That's a no-go. In JavaScript, it's always in milliseconds. So 1 second, 1000 milliseconds. You don't need to put the units on. It's always assumed that you'd be using milliseconds, fill. It's going to be both. So of case we are going in either direction again, don't worry about that for now. Easing, we're gonna go in Justinian JavaScript as well that the Web Animations API, the default timing function in CSS is an ease, whereas in JavaScript land it, the default is A-linear. So if we want to do something that isn't a linear animation when you have to actually say that. So let's say we go 0s and out here just to sort of show you what that looks like when I save this now this'll get reformatted slightly by prettier. So there you go. So you can see the first little bit that we've put in is just that transform. And we'll say move across. And we'll say to do every 1000 milliseconds we wanted to fill so that we get the styles of the final point of the animation persistent. And we're using an ease and out timing function. Now we also had, we changed it from a square to a circle as it went right. So what we actually need to do here, we're going to go from border-radius. And you're also in JavaScript land use, camelCase, property names. So in CSS we would have border dash, radius in JavaScript is border and then radius with a capital R. So a border-radius is getting to be no opex and we'll transform is not. So that's going to be our starting point. And then we're gonna change that to be builder radius. And then that's going to be 50%. Let's have a look. Okay, so something around here. While we got wrong. I'm missing a comma there. With your key frames, you can see here they use these curly braces. And after each set of curly braces, this is, these are by each individual keyframe. And after each of those you need to put a comma in. Okay, so there we go. And again, I think on the one we built with CSS, we also, we transformed the and the background color. So it would be back ground color it like that. And again, you pass in a string and a thank you was threes. So there we go. That was the first part of what we did with the CSS one. What's interesting about this is we can now say, we can sequence things. So we can say when this is finished, then. So when that animation is finished, we're going to set off on a new one. And we're going to say thing dot, and I'm eight. And again we're going to pass in two things. The first one is our array of keyframes. Again, don't, don't get hung up on this for now. And it's going to go into trends form. And it's like damn under pixels. Let's just check what happens here and you can see how this gets sequenced. And so I'll leave up for now. We'll, we'll fill this in more detail in a moment. And this again will say there's a delay here of 2.5th. And then we'll do the same stuff as before. Using again easily and out. Ok, duration. Again, you can see there's no specific orders to these things. As long as you've got the right stuff in there, it's going to work just fine. Okay. So let's see what that does for us. Okay, so can you see how one run after the other, even though I've got the wrong values in there. So at the minute I'm transforming from 300 over here to then be 0 and the x axis. So I need to make sure that that 300 is in there. And we'll we'll make that 200 for now. Okay. So let's see what that does for us. Okay, and then if you remember, we also wanted to turn it back to a square. So again, what we need to do here, as we'll make our background color back to what it was. And that was F9 0. And we'll make up border-radius back to 0 pixels. Or we could use percentages that overlaps phi. Again, I don't expect you to understand this now this is just giving you an overview of how you would write simple animation with the JavaScript Web Animations API. Okay, so that's a very brief overview done with and now we can get into the nitty gritty. 6. Project Refresh: Welcome back. So let's just refresh our memories as to what the main projects that we're gonna be building together is. We've got a stage area will canvas, if you will, not to be confused with the canvas element which you get in. You can also use a JavaScript to paint things with. We're not using the canvas element. I'm just calling this, um, this element that we're going to move everything into Canvas. And we've also got these buttons down below. So we've got next to skip things on. And then we've also got as pulls Boston, and then we've got black hole, which will come too much later. We've got a bit of setup to do here. We've got this little readout of whichever scene where on as well. We're going to set up, actually building out the shell, this thing first in the next video. Now, if you're primarily interested in just understanding and get into the bit where we actually use the API. You may want to skip on a little bit, but in the next few videos, aside from building out this structure, we're also going to cover things like timing functions and keyframe animations. In general terms, just as a kind of refresher in case he's something you've never done before or something you just need a little bit of a I get back up to speed with. So if you're not worried about ease in timing functions, durations, how to do iterations, any of that sort of stuff by all means skip ahead. Otherwise, hang around for the next few videos and we'll get through elasto off and then get building or actual project together. 7. Basic Setup: We're gonna start with the simplest setup you can imagine. We've got a virtually blank HTML file. Nothing but a console log in our JavaScript file. And I'll styles and obviously those two style sheet and the JavaScript file both link to the style sheet. And they were calling out to our animation script. We don't need, and you don't need any build tools in order to follow along with this and get things running. I am going to use a tool called Browser Sync throughout these videos, just because it gives me automatically reloads and means that we can move along quick without me continually refreshing the page. Now, you can also obviously installers yourself. If you head over to BrowserSync dot IO, you can see here installation instructions for doing so. It doesn't necessitate a couple of extra things like npm and node, which if you're not familiar with those tools, I think my advice at this point would be just forget about this part. Don't get bogged down and getting these build tools up and running that. That's not the focus of what we're doing here. We want to get onto the good stuff and doing the web animations. So if you're familiar and comfortable, maybe carve out half an hour and trying to get this thing running book. Don't labor this point, it's not super important. All it requires is doing an MPI install, installing browser sync globally. And then you can see if you click, get started. Again, it'll be different depending on what OS you are on. I'm a Mac here. You may be Windows, you maybe Linux. And once you've got that open and running, it's a simple case of you open a terminal and you pass it in a command, BrowserSync, which you're basically telling BrowserSync to start up a local server. And you can see here, I'm telling this to things that I'm telling it here. I'm running the browser sync as the command, start, stop browser sync. And then the two sort of arguments, if you like that I'm passing to serve and sorry, server and files. And those two options let you tell it where the root of the server will be, that it's going to spin up and where the files are that you want it to watch. Now, in this example here, my fault, my files that we're looking at here in a folder called vid seven. So from this point on, I'm running this command and click Enter and the spins me up a local server here. And then it's simple as if I wanna change this to favor orange color. I'm getting these instant reloads. So it's just a very helpful tool if you're quickly iterated on things. It'll save you quite a bit of time of the command and all to refresh your or using your mouse to do so, great tools only you can get it running quickly. Don't stress about it if you go on. In addition, you'll probably see here I'm using a tool called prettier. And we'll prettier does, is it takes the form actually code essentially. So rather than you worry about indentation or whether to put semi-colons on and all the rest of it. Pretty just takes care of that for you. So you can see here is an example. If I've not indented this file correctly, I can just save it. And pretty is going to make it look pretty. So prettier if you're not familiar with it. I do highly recommend it. Prettier dot IO. And again, it's another tool that's going to need node is going to need MPM. Don't stress about it if it's taking time or it's difficult to get up and running, skip over it. You can always come back to it later, but don't let that hold you back from getting on with animating some things. So with that said, let's go on in the next video and actually build our basic structure. 8. Creating the Stage and Controls: So in this video, we're going to look over the sort of the bedrock, if you like, of what we're about to build. So if we start with HTML, you can see the only thing I've added from our blank file. He's, I've got a main element here, which again, might be easy to look in the dev tools actually. So we've got a main element. We've got here, you can see the canvas area, not the real Canvas. Just a div that I'm 6'2 and Canvas, that's where we're going to shift a law stuff around. And you can see over here, it's just got a fixed width and height border around the outside background-color. And you can see importantly, it's got overflow hidden non a position of relative. The overflow hidden is important because once we start shifting things around, we want that as kind of like our film camera, if you like. And so when things go off to either side, we don't want hanging out the side of our stage area. And the position relative is important because as we move on, you'll see that when we add things into our canvas, we're going to typically be positioning them absolutely will cover that shortly. But the relative is important because otherwise things that were positioned absolutely would position themselves against the viewport rather than our stage area. You can see here that we've just got standard button elements for each of our controls across the bottom, each of them has got an ID type button. I always get into the habit of writing Type button on buttons because the default behavior of a button element is to submit, which in this case wouldn't make any difference. But if you by any chance had a button that was within a form and you don't write type on, it can submit the form. So that's just an aside what an explanation as why I always put the type equals button on foreign elements. We've got a class of Annie Dash button, as in animations button. On each of those items. The first hear the Previous button and our black hole button, which will come too much later on. You can see they're starting out life with disabled elements on them because when the page first loads, you can neither go backwards nor start the blackhole off. And so by default they're disabled in our styles. Pretty simple again, basic styling for all or main elements, which gives us this sort of page width of 800 basic Canvas Dan, as I explained before. And there are buttons have just got the standard ghost button style, if you like. There's nothing really of consequence in there. It's all very basic stuff. Animations at this point. All we've done is we've made constants for each of the buttons. So if you remember, we've got control previous, which is that one, next, which is that one black hole and pours down here. And then the readout is the bit of text that appears there. So as we skip on through the scenes, it'll say one of two, sorry, one of 32 of 3.3.3. Then we've added two event listeners that at this point, we've got, we're not, we're not ready to do stuff around, play pause, and we're not interested in doing stuff around the black hole. We are. The first things we're interested in doing is wiring up this next and previous button. And what that's gonna do is that's gonna give us a mechanism to shift forward scene, if you like. And I'll show you the mechanics of that as we go. But essentially we just need to create a listener or a function that runs when those items are clicked. And we could equally, instead of clint, you could use pointed down there if you prefer, moving down from the listeners that we've got on those two bosons. You can see here there's a max idx, which is the maximum index that I've set to three. Now that's going to be the limit of how many scenes. The thing that we've got is going to have. I'm hard-coding that here. But there may be instances when you're building something where it makes more sense to do that dynamically. So you might do, it might be a DOM read that you have to do. It might be based on the data coming in. That's telling you this seven slides to go through at this point is just hardcoded. We've also set a couple of laps for previous index on the current index. And that's so that we can figure out if we're going forwards or backwards, which will hopefully make some more sense as we go through this process direction click function. Now I've purposely left this process direction click function folded up because it's quite dense, although hopefully, well commented. Now if you remember, we are only firing dysfunction when you either click the Next button, when you click the Previous button. And so the first thing that we need to do is ascertain which of those two that you clicked. This thing that we're making works in principle by having a set number of scenes which you can click Next to go through one way and previous to combat through the opposite. The first thing we determined is what I'm calling polarity here. And I want to know whether you've clicked the first or sorry, if you've clicked previous or next. And on that basis, we are setting polarity to either a 0 or a one. So is a ternary operator here, which is like a condensed if else statements. And all we're doing, we're saying is the ID of the thing that click this control priv. If it is, then our polarity is 0, IE we're going backwards. And if you clicked next or, or, you know, if it isn't that then basically it's a one which means we're going forwards. We also want to set the previous index to wherever we are currently. That seemed confusing because when we click this were moving in one direction or another. We need to save where we are currently in case you want to come back for it. Or rather we can tell which direction we're traveling in. We set that there. And then based on whether our polarity as a one or a 0, if it's a one, We're going forwards. And so if where we are currently is the same as the maximum index, which if you remember, we set maxIndex appear at the top. Then basically quit out. That means we're right at the end of our set of scenes. Otherwise, we want to remove disabled from the button. It may not have disabled on at that point, but if it has, it will be removed. And then we want to set the current index. So this is going to work for the next time. We're going to set the current index, do an addition to it. We're going to count it out. We're going to step up that integer. So if it was non-zero, it is going to be warm. But first of all, we need to check. So we're gonna say if the current index, when it's got one added to it, is the same as or equal 12 maxIndex. Then we set it to maxIndex. Otherwise, we set current index to be current index plus one magnitude rewiring that, listen to that again, sounds confusing. Trust paperwork. Then also if the current index is the maxIndex, we want to set it to be disabled. So basically if we've moved on to the last one, we want to set next to be disabled because you can't go any further forward. Else is the same thing, but going backwards. So if you go in backwards, we want to take disabled off forwards because if we're going backwards, then we can obviously go forwards. If the current index is 0, we can quit out because we're right at the beginning. Otherwise, we're gonna remove all disabled state from the button, sorry, disabled attribute from the button. And then we're going to set the current index to be the current index minus one. If that's less than or equal to 0, then we're gonna set it to 0. Otherwise, we're going to set the current index to be current index minus one. So just remember if, if you're not use to ternary statements operators in JavaScript, you just think of these as condensed if elses, that's essentially what they are. And what you're doing is you're saying if, if something is true, but there's you condition basically. And if that condition is true, do this first thing, otherwise, do this second thing. And then just for the sake of seeing what those values are, we are going to console log that out. This bottom section here will come back to later. This is about how we're going to make animations and stop doing what they're doing each time you click forward and backwards. So don't worry about that. But for now to get up to speed on this video. And again, this obviously isn't, this isn't essential for the Web Animations API. This is just for the project that we're building as just give us a framework for firing off these different animations and scenes. Just to check, this little works with our browser sync running from the last video. If I click Next, it was non-zero and now it's one, was on one and now it's too wasn't too and now it's three. And there are disabled states kicked into like I can't go any further forwards coming back the other way. I was on three and now it's too wasn't too. Now it's warm water on one and now it's 0 when it can't go any further back. That was a lot tool for what seems like not very much on the page, but that's going to be essentially what we wanna do in the next videos. Now, before we get onto animating with JavaScript proper, there's still a couple more subjects that we just need to get a handle on first. And that's key framings in principle. And then also the different timing functions. So we're going to look at those in the next couple videos. I'll see you in a moment. 9. Web Animation theory: Keyframes: Just to be sure that we're setting off on the right fall. I'm gonna go over now the basics of what we mean by Keyframing and tweens and animations and all that sort of stuff. So just on the off chance that you are not familiar with the idea of key frames. If we have a very basic animation and let, let's suppose, let's suppose we have a ball here. And we want it to move down to here and then finish up here. In animation terms, what we would actually see as the end-use or if you watch it, a call to, you would see you wouldn't just see the thing move instantly from there to there to there. What you would see is the path of the ball moving from 1 to another, and then finally to that point. And the terminology for these things, or hear or your key frames. And then the bits in between, or where the word tween, tweening comes from. It's the in-betweens between these key frames. So what we're principally worried about when we're animating whether that's through after effects or whether that's through JavaScript or CSS, is we're interested in making these keyframe points and letting the computer figure out the in-betweens. So that's the basics of keyframe. So when we talk about organizing keyframes and writing keyframes, remember that's all you're doing is you're, you're specifying where these points are. Where there's a distinct change between the movement of the thing that you're animating, how that manifests, view and think about something. We're not going to actually animate something. But let's just suppose div class equals box. So let's suppose we have a box here and we're gonna say box width. Wonder pixels, right? On the pixels. That ground cola. Who doesn't love a bit, hot pink, pink, pink. Okay. There's our box. And if we wanted to move this thing around, the way that these lock in JavaScript terms is we would say const box equals query, Sorry, document dot query selector. And there's a box. And then we would say Box dot animate. This is the how the API, Web Animations API has this animate method. And you can see here the tooling inside of Sublime is telling me this takes two arguments, a set of key frames. And then what is cooling options or keyframe animation options. And we'll come on to those in the next video. The first thing that we'd be interested in passing. So you're going to pass it. Usually two objects or an array of objects and a set of objects. What this first bit before the first argument that we'll pass it is always the keyframes, whether that's a single keyframe or a set of key frames passed in as an array. So you'd be typically, if this was one key frame, so this would happen when some things already somewhere else on the DOM. And let's say we want to transform it to, we're gonna say translate its val runs late and it's always a string here. And we would say 500 pixels, 200 pixels. That's just the single one. If we wanted to move it. A few key frames like this kind of incredible piece of artwork that I showed you before. You'd need to pass in an array of objects. So instead, what you do here is let's just neat in that upper minute, I'm going to get these away because you don't need to worry about those for now. Instead of passing a single object, you would pass in an array of objects. So it's just needed this up a little bit in fatty prompts makes more sense for drop us down fully. So u, b and the second bit and transform and we get to scale to three times its size. So in this instance, that keyframe, that passing two key frames in there. First one is translate. Any second one is changing the scale. Now, you could, by default just pass in a duration. This should Rome. So if we just passed in two thousand and two thousand milliseconds to seconds, and we got rid of this bit. So now we're just setting in sending sentient all keyframes with duration. You can see our wonderful piece of animation there. However, this second bet here is where we would usually, and more often than not, you'll be sending in an object with a bunch of options of bunch of timing functions. And we'll look about in the next video. 10. Timing Options: In the last video, we looked at keyframes, theory of keyframes, and how they're applied basically with the Web Animations API. In this video, we're going to look at the second argument that we pass into the animate function. This is where we left the last video. And we had, if you remember, we have the animate we passed in. The first argument we passed in was an array of keyframes. We left this at the end of the last video and the second argument was just sat blank. Essentially, we did try if you remember, setting this to a duration which will run everything at default, but with a duration in their 3 thousand milliseconds, three seconds. And you can see here, that's the effect that we get when we run that. However, typically, you won't be sending in just the duration. You'll be wanting to send in other things too. Now, if I just neediness up, hopefully a little bit here so you can see what's going on a bit better. He's the opening and closing of all animate function. First thing we're doing that we looked at last video, is sending in this array of keyframes. And what we're interested in this video is what comes after the comma, the second set of arguments. And typically That's going to be an object. Now, things that you can pass into this object are all to do with the way that you want the animation to Rome. So things that you can send in or duration, which again, milliseconds and you write it not as a string, but as an integer. So 3 thousand would give us 33 seconds delay. You may choose to set a delay so that thing doesn't run straight away. You delay also an integer. So 500 milliseconds would give you a 2.5th delay. Iterations. If you wanted to run something a set number of times, you could say, you know, for, for it to run four times in CSS will, if you want to run an animation infinitely, you would use infinite. Slightly different. And the JavaScript API, you would actually set infinity as the JavaScript number infinity like that with a capital I. And infinity, fill mode takes, you didn't write film oats or it's just fill and you have to pass it a string. So you could have the default. In JavaScript, a linear timing function. Css is different and CSS it's an ease. So that may catch you out. So just be aware of that. And what you can send in 0s and out. Or if you wanted to get fancy, maybe there's something nice, you've seen it easy wins, and let's pick one, let's choose this sort of. So you might choose to use a bell curve. And again, you just pass that in as a string. So if you quotes around it and send it in. So as thing now is gonna go, it's gonna take three seconds going to be, I'm going to remove that delay because we'll be boring. Assent to watch. Two seconds. It's going to carry on a forever and we've got this film out giving up. You can also tell it to move. You can also set the animation direction, which if you've done any of this sort of stuff in CSS, you know, you can go normal, reverse, ultimate, an alternate reverse. At first glance you might think why is the reverse and why is the, sorry, Y is the ultimate reverse. So normal would go from backdrop, but vapor, normal would go in that direction. Reverse would obviously go in that direction. Ultimate is back and forth. Ultimate reversed there. The key difference as it would start at the end, move that way, and then keep going. And you would write that direction. And again, that's a string. So it would be normal or it would be reverse or ultimate reverse. Let's get rid of that. Let's get rid of that. And see what that does. Not a great deal. Okay, so a botch something. Now let's go and have a quick look and see if we can determine what I have done wrong. That edited editor. Okay, so like an idiot, I've set the fill mode to be a bell-shaped curve where what he should be is easing. Is that or fill. Phil we've not covered. Phil could be normal backwards. Here we go. It's gone. Auto backwards, both forwards, not often. You gotta use at least forwards. So when the animation runs, you want to retain the styles that exist at the end of that animation. Maybe you don't. The other one that I tend to find myself using a lot is both, which means that whichever direction I run this animation, I want the styles at either end to apply depending on whichever direction it's round. So in this case you'd die. I'm just gonna stick in both there. So let's see what that does for us. And you can see there that the ease in slightly unusual got this nice sort of popping and timing function going on there. So by and large, if you've done this sort of thing with CSS, this should feel instantly familiar. Few differences, but by and large, it should be what you used to. Now we've looked at the basics of these things. Both the keyframes in the prior video and the timing functions and options in this video. Hopefully, it will make a bit more sense as we move forward into making things with this API. 11. The Same Animation made with CSS and JS: In the last two videos, we looked at writing the key frames for an animation in JavaScript. And then we also looked at the options you can pass to an animation Duration Delay timing functions. In this video, I just want to drive home how to write a comparable animation in both CSS and JavaScript. So we're gonna, we're gonna put two items on the page. We're gonna make a spinner once with CSS, and then I make exactly the same spinner with JavaScript. So div class, and we'll call this one spinner CSS class. You'd probably guess spinner JS. Both of these will share some styles. So let's set the common styles. First of all, not terribly spinner ish book mats because we've left off here, border radius 50%. And this will make our rectangle circle. And in fact, just to a bit of space around these wants to stick a bit of margin on the outside. And then spin CSS. Let's say animation. Hopefully he will have at least written 102 CSS animations. If not, hopefully this will make some sense. We're going to make the animation property, or the short-term property we're gonna pass in our animation name, which is going to be and spin me. And it's going to say 1 second. It's going to have forwards and therefore retain the styles as it goes and it's going to go infinite. And then if you remember, and animation in CSS uses at ease timing function by default. And we're going to want, well, in fact, I'll show you what this does by default and then we'll put that initiated the difference. So keyframes spin too. And hopefully you recall in CSS, if it's default state is where you wanna move from. You don't need to define that, so you can just say where you want to go to. So in this case I'm gonna go do a transform which is a rotate 359 degrees. Okay, now can you see here that's the default CSS timing function, which is an easy, which is this sort of staccato kind of movement that you get there. So we can solve that and CSS for our needs here by just saying linear. And that will give us a, a linear time and functions of the spinach just keeps going. So that's our CSS one sorted. Let's look at how we'd write the same animation with JavaScript. In reality, spin it like this is not a good use case for a JavaScript animation with the Web Animations API. We're doing this really just to drive home the format that we're now getting used to in JavaScript of the animate method, passing in the keyframes. And then the various timing options that we want as well need to assign to this context, our spinner J S is equal to document. So I'm just going to grab this and the document first. And then we're going to animate and we're going to pass in two objects. In this case, this is going to be our options, including the timing function. And this first one is going to be our keyframe. So again, keyword is not as a string, but the value of the property is, so we're going to get rotate 359 degrees. And then here we're going to say duration. If you remember, in JavaScript with the JavaScript API, it's not seconds, it's milliseconds and we pass it as an integer. So there's our 1 second is milliseconds. We don't want to delay. We do want our fill. And we're going to say again, passing as a string, willing to say forwards, because there's things only ever going forwards, force iterations. And JavaScript, we pass it infinity rather than infinite. And then as we discussed a moment ago, JavaScript's default timing function is a linear, so we shouldn't need to set that. You can see they're exactly the same. Spin animated once with CSS and once with JavaScript. Now a common problem with CSS animations is when you want to take two transforms, for example, and run them concurrently on the same element. That's just not something that you can do with CSS, but it is something that you can do with JavaScript Web Animations API. So in the next video, we're going to look at how we could add something simple, like a scale. In addition to this, transform rotate. And we'll see how that's possible with JavaScript. 12. Adding Animations Together: By the end of the last video, we'd made ourselves to spinners. One animating with CSS and the other animating with JavaScript. And I mentioned that one of the common problems you'd get with CSS is if you're trying to apply to keyframes that use Transform, for example, at the same time to the same element. So first of all, I'm going to do that with the CSS one. And you can see the problem that occurs. So let's suppose we have our autopsy spinner here is the CSS version. And let's suppose that alongside this thing's spinning, I also want it to pulse. So it goes a little bit smaller, a little bit bigger as the spin is occurring. So you might think that you could do something like this. So I have another transform and you'd be forgiven for believing that this should work with made another keyframe that and all that does is scale the element that is applied to. There's our first, I'll just copy that. He's I'll second. And this one will be Scale me. Can you see how it's confused? Form of a better word? It's trying to do both animations are ones. Breed doesn't know how to resolve that. It can't, it can't figure out how to apply both those transforms together. Now, at present, as we be caught this at the end of 2020, there's no solution for this in CSS. There is, however, a solution for it in JavaScript just to stop that top one being quiet, so annoying. And I'm gonna turn the animation off of the CSS one. Flip across to the JavaScript file, and then we'll look at how we could do that with JavaScript. In fact, we can, we can save time here by, let's take that one. And we came to change this bit to be scale 0.8. Now this is exactly the same situation that we had with all CSS one. But the Javascript Web Animations API as a trick called up the sleeve. You can also inside your options, you can use composite. And There's a few. You can see here, strings that you can pass to composite accumulate at replace, replaces the default that takes whatever previous animation was running and replaces it with this new one. What we want to do here is choose out. And what this is going to do is take our second animation and add it in with the first. Accumulate is similar but slightly different. We're not gonna get into the differences of that. Now I just want to show you what happens when we stick it in as well. You might think this is still broken, isn't actually it's just because what I haven't done is I've not set direction to be ultimate at the minute. It's resetting itself. But by doing this, you can see we get this lovely combination of these two separate animation, something you just cannot do that with CSS. Another thing worth noting at this point is you can see as these animations are written here, they immediately play. Now that may or may not be what you want to do. So there's a, there's a couple ways you can solve that problem. The easiest way would be to assign, spin me like our other one. And this one is going to be Scale me. And what we could then do is go spin may dot pools. And they should turn off one of them. And then you could also do Scale me dipoles. And what you can do here is you can, as soon as you've defined an animation, you can immediately because we've, we've assigned it to a const there. We can then use that to say, this thing is attached, it's an animation and immediately pause it. And then you could choose to fire that off. And other events like a button being clicked or some other animation finishing as we look at this now, as well as also an opportunity to tidy this up a little bit. Each time we've looked at these animations so far, we've just been passing everything straight into the animate function, which is fine here. But when you're doing something a little larger scale, it quickly gets difficult to manage all these keyframes and different timing function. So in the next video, we're just gonna spend a little bit of time looking at how you might refactor this to make it a little bit easier to deal with. 13. WAAPI 13: Cast your mind back to hopefully milliseconds ago. In last video, we'd got to this point where we'd, we'd made to spin us almost CSS or JavaScript. And we looked at the joy of this composite property that you can use in JavaScript to combine two animations together. If you can remember, this was giving us the ability to have a scale running on one animation, a rotate running on another animation, and getting the result of those two together in the DOM. Take the opportunity whilst we've got relatively little code on the page that just refactor this slightly and make it more manageable. At present. Each time we run in this animate function, passing in the keyframes and the timing functions just as, as objects. So probably the simplest thing that you can do if you've got a bunch of animations is you can name your key frames and separate them out. So in this case, although this is very simple, we might say const, spin kf and obviously don't have to name them this way. I just, I tend to put kf, kf on the end or the beginning just so that I know that it's a keyframe Miss comes. And all we're gonna do is just take this and public like that. And then we'll pass in. Instead, we will pass this in Latin, this spring k, f. And then this thing we can pull out and we can say const, spin timing. And then with a better look, yes, there we go. So all still works the same. But what we're doing is we're, we're separating out our key frames into a different object and we're separating out all our time in for that animation, typically, you tend to do this because with keyframes, you won't always be passing in just one thing like this. Typically it will be an array and a bunch of key frames. And seeing all that inside the animate function can get a little bit messy. So we're gonna do the same thing now with this one here. And you could stack all these but the top if you wanted to. So let's suppose we will grow up this scale KF Wiki frames. And we'll say, put it under here just to there in a sensible audit const, scale, timing. And again, we'll just grab these. And then if you imagine here, has just makes it a bit more sensible to think about these as irrationally. So here's our animate function and we're going to pass it on, sorry, scale or on here only, passing all keyframes. And our time and save that just so that pretty does its thing. And then what you can find is if you're working with it, a large piece of interaction. Once you figured out you key frames, you can stick more elsewhere and just import men and keep the, keep the logic of what you're animation is doing to these nice, succinct little cause to the animate function. You'll see this kind of pattern more as we get on to build out little project out together. To give you some example, let's suppose we have a button, add event, listener, listen. And then it just makes it easier to do calls like that. Rather than how in all the time means and older. The keyframes o inside that if and if you've made it this fall, I think you know, everything that you need to, to start building this project together with me. So in the next video, we're gonna take an in-depth look at the project will be building and we're gonna go line-by-line section by section through the finished article. And hopefully at this point, it will be fairly clear what's going on. So go and get yourself a cup of your favorite beverage. It's likely to be a long one. I'll see you there in a moment. 14. Animation File Overview: In this video, we're going to cover off everything apart from writing the animations themselves. So I'm gonna take you through the entire structure of this project. Just so you understand the mechanics of everything that's going on around the animations themselves and how I arrived at that, this point with the various things in the DOM and how they're positioned. Don't want it to seem like I'm breezing over any bit of the implementation. So this is all the stuff that's getting the HTML and how it got there, got the SVGs from how they were optimized and put into the DOM, the basic style in and how that was set up. So if, if all that stuff you can live without, by all means, skip on to the next video where we talk about the actual animations in this project. But otherwise hang around and I'll take you through everything that we did. You can see we've got a main element here. And in prior videos we showed you week. I showed you these controls at the bottom, which is the, the various buttons that we've got here. You can also see here there's this aside element here where this is just where I'm giving credit to the artwork and where that's been sourced from. The, the sort of interesting bit in terms of the project itself and the stuff that you can see going on as you skip through these scenes. All of the all of the graphical assets that were sourced from a site called vector easy. So if you head over to vector easy, search for something that's in the kind of thing that you're interested in using. So obviously I chose something space themed, but you might choose something, well, whatever you want. The key thing to do, two things to be aware of. You need the screen a little wider. You need to make sure that you take editor compatible. And then any of these things that you then click, you can see you get this little edit button here. For reasons I don't understand when you screen is small or that capabilities taken away. So needy it little bit wider, click the edit button. And then what you can do is you can actually just download the asset straight out of this editor here. That's effectively what I did. So if you imagine I've grabbed the SVG apps effect easy. And then what I did is I just made it all board. I'm using sketchier, but obviously you could be using fake mirror or whatever your favorite graphics packages, paste it in each of the assets that are No, I was likely to need and gave them a title. And then one thing I always like to do, if I'm ever gonna put SVG asset onto the web, then I'll always run it through. There's a tool called SVG, which basically optimizes SVG files. And even better than uneasy. And that chap called Jake Archibald miter, a tool which wraps SVG, which is a command-line tool, puts it into a nice graphical interface. So in this case, I would get my get my art board here, copy the SVG code. Open SVG, paste in my markup, and then it gives you these two tabs here, the image tablets, you just check that nothing has gone awry after the optimizations have been done. But you can see here the difference in the code. I will just make this full screen for a moment. This is the optimized code. And then that was the original. So you can see it's taking away a lot of the whitespaces, normalizing all of the numbers, removing any elements that aren't needed. The upshot is as long as the thing looks like you want it to look. You can see here we've got a 64% saving in the file size. So wasn't massive before by any stretch, but it's come down a fair bit. You can just copy that out of there now. And this was our Moss. And then what it was doing is inside the HTML. Just move this over there. So yeah, inside the HTML, all I'm doing is for each of the graphical assets of wrap them in an element. And I've just pasted that SVG code straight in inside the element. And this class on the rapid element is just so that we can put some basic positioning CSS on that's been done for each of these elements here. So you can see these named exactly the same Saturn moon malls, rocket strike planning, Eddie. There you go. Oh, across the moon, stars back ground. You can just about make out layer, but that was sort of star escape if you like, which you can see behind each of the scenes. So you can just make that one out there with these amalgamations without using it as a background element, which you'll see in a minute. And then this div here is just our initial sort of Stowe's ask scrolling text. He is the kind of meat and potatoes of what we'll be dealing with when we come to animate in stuff and the basic styles to take care of that. You can see here we've got some basics to from HTML. And our rapid element canvas is what we are calling this area here. There's our stores background and each set to give us our star escape. I thought this line was worth calling out because I subsequently went past this. But I thought it was interesting enough to just talk briefly about at first to have the background stars, these things here. I had those brighter than you seeing them there. And what it was doing is I was sticking them. That was using the background element, sticking the styles at the back and then in order to put a darker wash over the top and dark and those stars down. I was being lazy and doing it in code instead of just doing it in the graphics editor. But while I was doing is using a linear gradient, which was effectively no gradient, but that lets you put a semitransparent overlay on the top of an image with CSS. He's a bit of a sort of CSS trick. However, what I found when I did that is that the animation quality, not quality, that the animation performance started to suffer. So I would say occasionally they're the sorts of things that you might make a choice. Not realized why our animation stills her in trying keep your elements as simple as possible, things that you are adding capacity and filters to. And CSS are less likely to animate Well when you shifting them around the screen, the wiper, which you can see here that that's when each CNN's, you can see we have various sort of transitions. Again, sort of borne off the stove style screen dissolves. And the white part is what we use to do that. And it's just a single element that we're moving around the page again with the y p, you can see that there was a, there was a box shadow on there at 1 where again, I ended up pulling that out because it didn't really add much. And again, it's more and it requires more computational power. If you've got a render, a shadow to the screen and your movie about us, obviously more intensive for the computer to do. Everything else you can see is positioned all of our graphical assets. I'm setting them inside the canvas. Absolutely position. So by default, they'll all just sit up at the top left of that rapid element. Assume things are half left to filter on because I felt it was worth it. So if you want to take you back to the beginning here, I liked this little kind of glow from the moon, a full that was quite an asset left that in yet all these elements are positioned, some of them basic transform on just to position them somewhere reasonable on the page. And then we're going to animate from there to somewhere else. It's worth cool it out just in case you're not aware when we use absolute position in NCSS, those elements again, to be positioned relative to their nearest non-static element parent. So in our case, you can see up here all Canvas which is the parent for all these graphical assets. We've given that a position of relative, which means that our absolutely positioned elements will position themselves relative to that. The other good thing about in terms of animation is that you don't have to use a transform and it won't affect other elements. Typically, if you're, if you're elements are in normal document flow and you move them around with margins, paddings and all that sort of stuff, they're going to interfere with anything else that's also in document flow. So because of what we're doing here, I've just made everything absolutely positioned so they can all move independently and not affect any other element. Then just a bit further down in the CSS, you can see here, we've got some default transform on that initial sort of Star Wars tax just to give it up twisted perspective. So using a few transforms, they were rotating it and translating it. Comic of any other words that rhyme with that. That's what we're doing to it. And then we've also got here, you can see black holes spin when we come onto the black hole. You'll see that when we set the blackhole off, it spins around. And I'm just using a CSS animation here to do that rather than doing it in JavaScript. Just to show you, you can mix and match these two things together quite happily. When it comes to the JavaScript. A lot of this stuff you will have already seen in the prior videos in terms of the basic setup of this file, we're assigning all our buttons to concerts. And we've got some click listeners going on, on the next and previous. We've got one on the pores, which we'll come to in a later video and, and on the blackhole button as well. All we've all elements on the page for the graphical assets that we've sourced stuck in the DOM. They're all just referenced here. And then we're into the variables that we set up in the prior video for our next and previous functionality. So we can move through this, these sequences of animations in the few videos as well. If you remember, we looked at refactoring that code so that our keyframes and keyframe timings were in separate scientists, separate variables or constants in this, in this case. So here's a bunch of our key frames and don't, don't worry about those for now. The timings here offer each of the scenes and I'll explain why we've done that here as we go on in the next video. Or animations for the different scenes are all handled in this single and m function, which I was too lazy to write animation out. I didn't want it to be confused with animate that were obviously an actual method to the API. Enemies where all the magic happens. And then aside from that, we've got processed direction click function, which we've been through before. So we don't need to worry about that. Toggle play back is what we use to do a play and pause. And again, we'll come to that shortly. And then I'll black hole function again, which will come to further on. In terms of our JavaScript file. We're just referencing our controls. We're wiring up the controls to functions that we're going to fly it to do what we need them to do. We're also making references to each of the graphical elements that we might want to animate. And then principally, We've got a boatload of different keyframes assigned to constants. And then we've got a function, main function, which is going to start animating those elements. And that's what we have finally got to now and we're going to look at in the next video. 15. Writing the Animations: Assuming you've not started on this particular video, you will know what we're looking at on the left-hand side of the screen here. This is a lot of different keyframe animations. The cover off all the possible bits of animation will the different key frames that I need to run on various elements in order to get this set of animations working. Or scroll enough taxed are rocky flying across with the planets, move in slightly. The little title thing coming up, the WIP moving across. That. Why narrowing down there that the rocket coming up and across Mars, moving across the trail of the rocket, boosters, turning off and alittle alien popping up as well. Every one of those is covered off by these different sets of key frames here. So I've tried to name them somewhat sensibly. But the key thing here is to say that there's no, there's no magic skill that you can learn to get these right. It's just lots of time, trial and error, getting the things to work the way that you want them to work. The only thing that we've not looked at so far, It's worth calling out is as you're down these keyframes, you'll see occasionally offset here. Now, what offset does is it lets you do the equivalent of percentages in CSS animations. And CSS animation. We might say that no, we do this 50%, we do this at a 100%, We do this. That might just as easily be 73, sorry, not 730, 73%. And at that, that's obviously what you do at that particular point as the keyframes are going through. And it, if it's five seconds long, it'll be at a particular point. And if the animation was run for ten seconds, it would be at 73% of ten seconds. So you can do the same thing in wet with the Web Animations API using this offset keyword, you can see it's not a string, it's an integer and it's between naught and one, with one being a 100% note being 0%. So 0.2 is at 20%. So it's as simple as that is when you keyframes, and crucially it's the keyframes that you pass it in with, not the timing options. You'll see that dotted around here in there, but that's essentially what it is. There's nothing here you haven't seen already is we'll go through a couple of examples. So cruel text offers or Stowe's text. And you can see here, That's where we're starting. And then we're just using the translate Y to shovel out Feng off into the distance. Most of these have only got two keyframes, is sort of starting and ending point. There is a few that have more like this one that we just looked at here by and large, even though they look, let's put a bit more space here. Even though they look, it can seem a little bit intimidating at first, but there nothing that you won't be used to doing in CSS if you didn't CSS animations at all. It's just a lot of them. Once the entire total of everything that goes on. Again, this pattern, You should be used to square brackets for the array keyframes, comma separated or an object each. So here we go. Square brackets as our object for the first keyframe and as the second key frame. And you can see, even though these are written differently in different places, it's exactly the same pattern. You now to do this, you've done a couple of lessons, Mark. I think you've got this now. So in the next lesson, we're going to look at how we actually run these keyframes together and actually build the animations ope. 16. Sequencing Animations: Last video we were getting into the thick of all main JavaScript file that runs all these animations for our project that we're building together. We look through these key frames and we can see that they are, whilst there's a lot of them. And it can seem confusing at first. It's the same basic pattern that we've, we've used a few times throughout and is essentially the same as what you would be doing with CSS. Beyond that, we want to look now at our main animation function. And if you remember, this little project works by us having a simple counter that goes through the scenes that we want to run. And on the basis then of of which particular number were Ohno scene that we're on were going to sequence a bunch of these animations and keyframes to R1. C1 is effectively what happens here. The Stowe's text goes off. A rocket moves across, but a text comes in and these planets are moving softly. The first thing that you'll see here inside of the, the C1 section is I'm actually resetting upon ship stuff here. So the reason that is done here is because you may be coming back to scene for scene one from s2. And if that's the case, we need to cater for that by shuffling all the bits and pieces that we need back in the right place. Now, you can see here with all of these will, these ones that are resets, the duration is set to be 0, so you don't actually see the animation happening. It's just a quick way of getting everything back where it needs to be ready to run the animation proper. This animate function is doing everything that you've seen plenty of times already. Now, we are choosing the element. We're running the animate method on it. And then we pass it in our keyframes which, you know, scroll, scroll, text off or fade. So that's referencing our keyframes appear. And then we're passing in our animation options or timing functions or durations and things like that. And in this case, all these say running with 0 duration just to reset them back to normal. So the interesting stuff starts a bit further down here. And you can see here that cruel textile Stowe's text. We start by running up for three seconds. The fill mode is forward so the styles are retained as it goes off. And then interestingly, you can see here that the next thing that we get, remember at the beginning when I was trying to sell you the idea of learning this stuff. One thing that you could do with a JavaScript API that you cannot do with the CSS animations. As sequencing. You can run one animation of the back of another animation. And we do that with the JavaScript Web Animations API by utilizing a fairly recent addition to the language, which is promises. And what promises do is they let us say finished, which is basically like when this thing is finished, then go and do this other thing. Now in the next video, I'm going to struggle and try to give you a layman's version of exactly how promises work and why they're so important for what we're doing here. But for now, just consider some of the other things that are possible here in JavaScript that aren't possible or not as easy with CSS. You can see on some of these animations that are running in terms of the duration, we're able to say C1 duration divided by a certain amount. And that isn't just to be Coyle clever. It's because if we decide to change the C1 duration to ten seconds or 15 seconds, we don't have to come back into our animation and real-time everything. The fact that this is all based on that initial value means that we don't have to worry about it. You can see here that we're saying when this thing is finished, realness thing, when this thing is finished, wrongness thing. And on and on it goes. And you can see here at the end we using the finished not to run another animation was actually to just change something in the dome. Although I can appreciate if you're not used to writing animation to JavaScript, this might seem pretty complicated, pretty intimidating book grew up the code. Take your time and look through it and you'll see that it's actually just a whole lot of stuff that you already know how to do. So with all that said, I want to emphasize how important and useful this idea of chaining the animations is using these promises that are part of the Web Animations API. In the next video, we'll talk about promises in general and why that is so useful to us. 17. Callbacks and Promises Basic Explainer: If you're watching this video and you do know what JavaScript promises, or an a for you watching the wrong video. Go onto the next one. For everybody else. I'm going to attempt in the simplest way I can to explain what promises are in JavaScript. Now let me be clear. This isn't going to win me a place that Google, I'm interested here, not in technical accuracy, but rather just conveying the fundamentals of the concept of promises. In JavaScript. Ordinarily, the parser goes down line by line and runs each line of code in the JavaScript file. What it doesn't do by default is know to wait for something. So for example, it would hit Align. You'll say, go and get me this bit of text from the internet. It doesn't ordinarily wait for that piece of text to comeback before it moves on to the next line, nor should it, where we'd have some very, very slow JavaScript in the wild. However, previously, we got around this issue with something called callbacks. A callback function is simply the term that we use to describe when you pass a function as an argument to a different function, which is then executed from within the author function. And you'd see a pattern whereby something will come in. They're, there'll be some bit of code and then you would get your callback here. And this would have whatever name it needs to have. This is going to run after this first bit. So you might have options in their, Angie would go, Here is my main function body. And you do all the stuff that you needed to do inside your function there, using the options that had been passed in. And then when all that had been done, you would do something like that to run. The second function that you are passing in when you call it. That has worked well enough. Although it does end up with code which kind of coat the pyramid of doom, where it's going triangular, lower, triangular, really track. It's going across the page. We can do better than that now with promises in JavaScript, we can all identify with the fact that we've made promises to people. Sometimes those promises are filled and sometimes they are not. And they work exactly the same in JavaScript. In a promise lets you represent something that may or may not get fulfilled or rejected. Why that's interesting to us with a JavaScript animations API is because one of the fundamental things that we've been wanting to do with animations and CSS is wrong. One animation of the back of another animation without having to do the mental gymnastics of figuring out the correct delays for things to run in sequence. And we using this extensively in our little project to make one thing happen. And once that is done, another thing happen and on and on and on. And the syntax or all that you need to understand for the purpose of using this JavaScript API is this finished dot then keywords, keywords, syntax. When an animation is finished, you, you can see it if this whitespace isn't necessarily, it's just the way that it gets formatted. You'd run the animate method. And then immediately you go dot finished dot then. And you can see here we use an arrow function so you could pass something through there if you want to put typically you're not. And then you give it an arrow function. And then there's the body of the next thing that you want to happen. So in this case, the text scrolls off, removing an attribute in the DOM, and then I'm running another animation. And then again, I've got a promise here on this one. And when that one finishes, I do the next thing. With the JavaScript Web Animations API. You don't need to get into the complexities typically of whether a promise is pending or whether it's rejected. Those are the sorts of things that you worry about when you're doing real programming, if you like, rather than just moving things around in the UI. But this promises concept is still very useful to us for this very reason. So the only things that you really need to take from this or that promises awesome thing in JavaScript that allows us to do things asynchronously. And the syntax for us to do that with animations and to sequence animations is dot finished dot van braces, arrow function. Next thing that you want to do. And you can chain those on and on and on as much as you would like. Now, another really great thing about the Web Animations API is the fact that it's very simple to pause and restart animations. And we'll see how to do that in the next video. Using our new best friend promises. 18. Pausing and Restarting Animations: One of the great things. Another great thing about Web Animations API is that it makes it simple to pause and then replay videos. Remember right back at the beginning when we made our index page, we had a button that we'd inventively titled pools. And we're going to look at that now and see how that's wide open, See how it pauses and plays the animation. So just to give you an idea of what's going on. So as our animation plays, we can click pause. And when you click it again to stop things running again. And the way that works appear at the top of all file. We've just added an event listener to the pause button. And you can see here that when you click it, we are running a function called toggle play back. I've collapsed up all the other functions that aren't relevant. And it's quite a small function that we're looking at here. So down at the bottom of our file here you can see here's our total playback function. All that they stores. There's a method that's part of the Web Animations API, which you run on the documents, and it's called Get animations. And what it does is it collects up any animations that are running in that document. And then you can do basically what you want to do with those animations. You can inspect the prophecies of those animations and you can also make changes to those animations. So in this case, what we're doing here is it gives you the dot map method, which is a method that you can run on arrays typically. But because there's a bunch of these animations you can map, which is basically, if you don't know what map is, it's, it's like running a loop over a number of things. He lets you iterate over something. So in our case, we're saying get all the animations and then we want to loop over them. And you can see here that I've, I've titled each of the animation, I've inventively titled animation. And what that lets me do is say, if the play state of the animation is running, IE does an animation happening, then what I want to do is pause it. However, if the animation is already paused, then I want to play it. So it's just a very simple toggle, but it's using these methods that we get with this API. So just to go through it one more time, we're saying, get me all the animations, which is here. And then we ought to map over them to iterate over all those animations that we found in the document. We're naming. Each instance of those animations. You could call up sausages if you want, or coat or a window. It doesn't really matter, is just an identifier for as we iterate over them. And then I'm saying, if this particular animation has got a play state of Rodin, you can see it. This is a string and I'm using equality here to say that's basically three equals signs. If we're running, pause it. So again, it's this dot pores brackets calls that function, pauses it. Otherwise, if the animation itself was already paused, then we want it to play. And it's really as simple as that. That lets you gather up anything. Animations wise, whether it was written in CSS, JavaScript, and then pause it plate. And there's also other methods which we have available like dot council, dot finish. And we're gonna take the opportunity in the next video, we're going to try refactoring what we've got at the minute that the end result will be exactly the same or very close to. But what I want to do is look at what would happen if we refactored the code that we've got and tried to basic more around assigning the animations to variables and running those and what are the things that we could do without doesn't give us any economies writing things in a different way. So we're gonna do that in the next video. 19. Refactoring Our Code: In the last video, we looked at how we could easily pause and play all the animations that are occurring at anytime in the document. And as a consequence of that, we looked at methods of the API such as pores and dot play. And also mentioned there was things like dot furnish and dot cancel. And that got me to thinking, I wonder what this file would look like if we refactored it, to base it more round using or setting up the functions with variables. So that could be called with dot play and dot pores and dot reverse, rather than the kind of declarative way that we've done so far. So we're going to compress the next couple of hours down into a very quick and timelapse, if you like, of me refactoring this code. And then we'll examine what I've dorm and we'll see whether there are any benefits in doing that and what the tradeoffs are, all the rest of it. So see you in about 40 seconds real-time, few hours for me. I've got all these animations and there's probably going to be more that I just need to run the same current time equals 0 and up pores to stop and so forth. I more sense if I just look sort of abstract this bit functionality out into a function. So I'm going to do function reset and animations. And that's going to take an array of animations, animations for each. And I'm just going to loop over these. Basically, we Animation, say animation dot current time equals 0 and animation don't. And then here I should be able to just do VSAT animations. And then I'm going to pass in this array of all the things I want to run it on self got on in Stowe's text off and M phase traffic planning on him. Because fade and evade. My panel. Intro. Okay, another thing should work exactly the same. I've got to tell you about the most fond of hot in two or three hours. Let's compare now the two files. So this is what we had before. And then we'll compare it with this one, which is the one that's been refactored. Most of the stuff up at the top is exactly the same. You can see as we look at things like the keyframes I've just added kf on at the big, at the beginning. Just so that I don't get confused between what's a function for the whole animation and what's just the keyframes. Nothing is materially changed there, just, just slightly renamed. Where it gets a little bit different is once you get past the, the timing durations here, you can see, well actually I'll just skip past this a minute. If you come down to our anime functional main animate function now, it looks quite different in comparison to our main function as it was before. You can see that before that we were resetting things like this. And then we describing each one right there in the function. And then we'll move in on using our promises to sequence the next animation that looks slightly different. Now, what, what we've done is taken, taken something like wiper animate that. And I've wrapped that up into something like this. So this bit here is essentially what you are getting. The. And then what I'm doing is I'm assigning it with a name so that I can call out with dot play or I can stop it with dot pores. So further on down you can see that the actual animation function itself is far more terse because we're just doing things like that thing play when nothing is finished. Roma animation than Rona animation and then run that animation. And although that's nice and compact, I've actually found that more difficult to reason through and think about. It gets essentially the same result. There's a few little bits and pieces left in here where I, I don't think it works quite as well, but it was enough of a refactor to make me realize that I actually prefer it the original way. What's important here though, is that it illustrates that there's a number of ways that you can write these things to get very similar results. It really just depends on your use case and your preferences. But you can see here amusing things here that you, that we've not looked at before. There's ways of reversing an animation where you can use dot reverse, but that always reverses the direction it's just running. Whereas a playback rate of one is always forwards and a playback rate of, of minus1, which we've gotten some places here, is always reverse. So I've got that from time to time. Cancel, where we've got this dot cancel method. What the dot cancel method doors is basically ends that animation and walk. It's, it's dead. There's nothing left from that thing there. Dot finish, pushes and animation on to its endpoint, immediately drives the animation forward to its final point. So you can see that something like a scene three, very, very compact in this way. And we using that recent animations function to just loop through anything we want to set it back to the beginning. So if you compare seeing three, this is how we had it before. That. Then here it is. In totality, totality, in total. This way of doing it. However, whilst this looks compact, once you factor in the fact that you've got to rewrite all these, all the bits of pieces appear and assign them to constants or variables. The actual total file size of the refactored one is about 565 lines. And the original one was coming in about 459. So it's actually more long-winded in some ways, but may be better off going to leave this in the files for you to have a gander through my preference, the way we've done it originally. But this way is equally valid if that's your preference. Now we've been on that little refactoring excursion. We're gonna go back and use the original code, the code that we looked at all along. And what we're gonna do next is look at how you can inspect a transform, something that used to have to use something called the matrix to get the values out of a CSS transform. And there's something we can do now with the API that lets us pick up things elsewhere on the page are already transformed and move them to a new place. So we're going to look at that in the next video. 20. No More Matrix: No more matrix. Now, that's not to say you can't carry on watching arguably overrated Keanu Reeves movies from the nineties. However, what we can do is stop using the CSS matrix to try and figure out what's going on with the transform. If you have no idea what I'm talking about, Consider the existing situation with CSS animations where you will put a transform to an element and based upon its current position, you want to read that with JavaScript, get the coordinates of where it is at the moment and move it or change it somehow. With JavaScript. Historically, we've had to use the matrix property. Now the matrix property is what the browser compounds all the different transforms that you may have put on an element into one fearsome syntax. So there's a tool vehicle, it's angry tools.com, CSS, dashed generator slash transform. And this lets us go nice, simple UI. You can just add a bit of at a few different transforms onto an element here. And now what's important to note is what's generated. Down here. You can ignore the vendor prefixes used to look at this top line here. This is the matrix value there is the result of all these other separate transforms. And he's a succinct way of the browser communicating exactly how it works out thing to look. However, when you come to read that back in JavaScript, it's very difficult to try and figure out which bits the rotation, which bits the, the x transform, which bits the scale. The good news is, with Web Animations API, you can simplify that sorts of profit process by just using Get Computed Style. You can pass lesson to the Web Animations API and use that as a starting point for another animation. We're going to use that when we look at how we make all black hole function. When you do that in the next video. 21. New Animations mid-transform: This is potentially go in into the weeds a little bit, but I wanted to show you the sort of thing that's possible when you animate with JavaScript as opposed to animating with CSS, if that's what you're used to. So inside our little animation project, you can see that when we click next from the front, pay each, this black hole button lights up for us to use. Now I'll just refresh this again. I'll show you what happens when we press that. So the black hole light soap, I click black hole, a black hole appears and it sucks many of the elements that are on the page into it. Now, how that is achieved is as follows. We've wired up our black hole button to create black hole function, which is the thing we're going to look at now. So write down the bottom of the project file, the last project file. You can see here, this crate black hole function. Now, I'm just gonna go through the sort of the setup pieces of this function first. Even though they're not actually to do with the Web Animations API, just so you understand what's going on. First of all, we're just saying we've got a Boolean which we sat black hole active, which is set to be true when the black hole is activated. If that's already activated, we don't want to start it again. So if the black holes already go in, or the current index e would not unseen one, then we're basically just return out the function we're doing an early return there. Then what we're doing is for all of these other boxes, for next, previous and pause. If the black holes running, we want to pause. There was just so some become mess something up and stop the animations met flow, something like that. Then what we're doing is we're getting the canvas area by either the sort of the scene area. And we're getting the client rectangle box. So it gives us all the geometry information that we might need. We've then got a function random float, which if you feed it a minimum and a maximum, it's going to give you back a random figure in between those two points. Random coordinates is just another little function that lets us generate an X and a Y value based on our canvas size. We've then got this thing called applicable items. And this is just an array which I've added in any of the elements that I'm happy to get sucked into the black hole. So that means I wanted the Rocky to carry on and not get sucked into the black hole. So by doing this, it means that I've got some control over what does get pulled in. We then got a little function which just checks to see if the element that's currently being animated as part of that list or not. And then what we're doing is we create a div and append into the DOM with a class of canvas black hole. And down there in the CSS, you can see here that we've just got some basic styles for this thing. It's 50 pixels by 50 pixels wide. We've got this black hole JPEG, and we're just running a standard CSS animation on that. And you can see that that's, that's what gives us this sort of spinning black hole, kind of OK. So back in our JavaScript, that thing gets added into the dom. We then position our DOM based on the coordinates that or randomly generated by this function. And the minus 25 is just because the Baco itself is 50 pixels in size. So we want the center of that to be off of that in both axes. Now we're on to the bit where we're actually using the Animations API. So remember in the prior video, when we looked at pause and play, we use this document.write animations, dot map to loop over annette any animations that are currently running. So first of all, I'm checking that if one of the animations that ruin it is part of the list of things. I am happy to do something with this little, if they're just checks that, then we're into getting the elements itself. So when we loop over the animations with that get Animations API, we can get information out of there as well. So I'm getting the toggle element here of the element that is being animated. And then in turn, and I'm doing things or getting the geometry of that item, I'm getting its position left, its position top. And then setting some new coordinates, which are the new random coordinates minus the existing coordinate, such kind of the distance we need to move. And then for each element, each target elements. So you can see again, I'm guessing that that's the animation. And then I'm going up and finding the target. So I0 the element that the animation is running on. And then I'm running a new animation which uses I'm passing in this window get computed style Anan element transform. And that's basically when we looked at in the previous video about the matrix. And in the past, you would have to read that value in and try and determine what transforms currently being applied to an element. We could do better than that with this API because we can just say, Go and find me this element on the page and use its current transform inside the keyframe that he then goes on moves. So you can see here, the first section of this keyframe is basically say, start from where you are at the minute. And then we're translating the item to its new coordinates and scaling it down. So these two parts of the keyframe that we're making here. So here's our new key frame. We starting from where it is and then we're translating it from there to some new coordinates. And where we end up with the element with an opacity of 0. So it's basically grabbing it, moving it to where it needs to go and shrinking it down. So it gives the kind of appearance of being sucked into a black hole, or at least that's what I was going for. And this thing happens over a 2.5th and obviously that could be whatever you wanted it to be. So that is what we're dealing with, that black hole function. Again, let's just look at what that looks like. Now you've had it explained to the black hole appears, everything gets soaked in and the CSS animation continues to run spinning black hole. Okay, next video, we're just going to cover and talk about a few little bits and pieces which we've not really covered in detail so far. Before we come to the end of our time together. 22. Committing Styles into the DOM: One last little nugget that you may find useful when you're using this API. There is a method called commit styles. And what that lets you do is when an animation comes to an end, it applies the effects of that animation as inline styles onto the element. So I'm just going to show you the effect of that. Now, we are using the blackhole function here that we looked at in the previous video. And all I'm gonna do as it loops over each of our elements that are animated. I'm just gonna stick in here at the bottom. After this element has animated, I'm going to say animation. Oops, animation.com styles. And so each time it loops over one of these things, what I'm hoping to happen is I'm going to see is inline styles the end result of all those animation. So let's save that and have a look what happens here. So Let's set things in motion here. And then we'll press the black hole. And then let's have a look down. And you can see here that the commit styles method has applied the final resting place, if you like, the results of everything that's going on in the animation. Now, I've not used that much at all. What we've built here together, but you may find it very useful in what you'd use to build. So that's just a brief heads-up about that method and what you could use it for. 23. Conclusion: Here we go, my friend. At the end. Hopefully, if you follow it along all through this course, you'll now have a better understanding of how you can animate things on the web with the JavaScript Web Animations API. Just remember, we've gone from having no animations in JavaScript to writing some simple animations, ones that we would normally do in CSS. To then a project where we've got a whole slew of animations sequenced one after the other. We've touched on things like picking up transforms from one place in the DOM, move in them elsewhere. Learning how to pause and replay animations, how to counsel them, move them right onto the end. If you've managed to follow along and build something of your own or even this product itself. As we've gone through these videos, you should feel very proud of yourself when you try out for the first time. If you find yourself stumbling, comeback, give myself a refresher. It's like anything else on the web. You're only going to get good at it by practicing it and using it in the wild. Nobody picks this default straight away. This is the first video, of course, have made. So it would be really useful to have your comments Good, even bad. So please find me on Twitter at Ben frayed. Or you can email me at contact at Ben frame.com. And I'd love to hear your thoughts. Otherwise, I'll see you again next time.