JavaScript Game: Interactive Questions With CSS Transitions & Animations

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey welcome back to this bootcamp series in this video we're going to continue practicing our javascript by creating a simple little math game so before i talk anymore let me show a sneak peek preview of the finished product that we're going to build together so the game can randomly generate math problems and if you get the question right you get a point here you can see the green progress bar start to fill up if you get 10 points you win or if you get a question wrong you can see it sort of zooms the question in in red to alert you that you got a wrong answer and if you get three wrong answers you lose now if you win or lose it shows this sort of overlay and then you can click the button to start over now big picture we're building this game for two reasons number one i think it'll be a fun exercise to practice more javascript and number two the challenges that we're going to run into while building this segue perfectly into the topic we're going to cover in our next video i'll explain what i mean by that at the very end of this video but for now i'm excited to start building the math game with you let's jump into the action okay so i have a new folder here so far i've just set up a basic skeleton html file i'm loading an empty css file and an empty javascript file if you're not sure how to set this basic skeleton up that's okay you can go watch one of the earlier videos in this series okay but when it comes to building out this game where should we begin well if we look at the finished product i think we should start with generating a random number right every time i refresh the page it generates a new math problem so we're going to need to be able to generate or choose a random number from 0 to 10 with javascript so how do you do that well let's actually jump into our browser's console and we can take a look at how that's possible so if we just inspect and then jump into the console tab we can write a bit of javascript here so javascript has a built-in object uppercase math this is just a core part of the javascript language itself and we can look inside it so dot and call a method named random so parentheses to call it if we push enter we see a number appears now if we push up on our keyboard the up arrow key we get the command we just ran so we can push enter and run it again and if you just keep pushing up and enter you see you get a random number each time however it's always going to be a value from either 0 all the way up right before a value of 1. so it's never going to be exactly 1 but it could be 0.9998 so it's inclusive to 0 but not 1. so how does this really help us if we want to create numbers like 0 through 10 right we don't just want a decimal or a fraction of a number well if we know the largest number we want is 10 we can just multiply that by this right if this is always going to be some fraction less than 1 well we can just say math and again that's uppercase math dot random parentheses to call it asterisk right to multiply it by 10. so now that gives me 6.9 if i push the up arrow and run it again 0.4 6.8 okay now before we learn how to round these to whole numbers let's first address something and that is that we would never actually get our max value of 10 because if this is always going to return something slightly less than 1 well then it's impossible for us to get 10. at most we could get maybe 9.9 or something like that so why don't we actually add 1 to whatever we want the largest number to be so maybe uppercase math dot random times 11 instead of 10. now it is random so off camera through the magic of video editing i'll run this until i get 10. okay so i finally got 10.6 cool that was just a proof of concept to show that it works at this point we just want to round these down to the nearest whole number well maybe round isn't the correct term because since this is larger than 10.5 you would round up but you know what i mean maybe not round but just go down or return the nearest whole number in the downward direction right so we'd want this to just be 10. we'd want this to just be seven so what we can actually do is just wrap our formula within something called math.floor which rounds down to the nearest whole number so all together we could just say math.floor parentheses to call that inside that right you give it a number and it will round down so that's where then we could say math.random parentheses to call that times 11. let's run that so we get two if i try it again eight five three you get the idea so now that we've figured out a formula that works for us let's copy this into our clipboard and jump back into our text editor and let's jump into the javascript file that we've attached to our basic web page and i'm going to begin by creating a function you could call it anything but i'm going to call it generate number parentheses create the brackets okay inside the body of this function let's say return and then just paste in your clipboard right that formula that we were working on okay now i want to make this function dynamic or flexible what i mean by that is what if in certain situations i want to randomly pick a number up to 10 but then in other situations i only want to pick a number between 0 and 2. well all we would need to do to make this function flexible like that is give it a parameter so in these parentheses you could call it anything but let's call it max okay and then instead of hard coding this to 11 let's get rid of the 11 and just say new pair of parentheses max plus one right before we wanted 10 but we added one to it for our math reason so now this is the same thing right we're just making it flexible now if you're confused as to why i wanted to create a function out of this let me show you so down here let's create a new function and let's name it generate problem parentheses curly brackets right because if we look at the finished product not only do you receive a problem when you first load the page but then after every answer we need to generate a new problem so we would want a reusable function now in this let's just return an object so return curly brackets remember in our first javascript lesson we created a cat object i believe we named it meows a lot and it had different properties like species or eye color and it had a method of jump well in these curly brackets we can give this object multiple properties so let's drop down let's do this let's say it should have one property called number one colon right that's the first number in the math problem and we could just say generate number parentheses to call it say 10 is the largest value we want after this line we can say comma have another property of number two i'm just making up these property names by the way colon generate number max of 10 and now here's the interesting part so comma one more property and that is operator right if we look at the finished product the mathematical operation is supposed to be random as well so sometimes we want it to be subtraction or multiplication or addition so here's how we can handle that just say operator property colon and then just give it an array so square brackets inside there i would just say quotes plus symbol comma quotes subtraction or that's just the dash symbol comma quotes and yes technically in javascript multiplication is asterisk but let's just focus on what the visitors should visually see right most people don't know maybe that asterisk is how you multiply in javascript so visually we would want people to see x for multiplication so let's just say x okay now this creates an array and then we know that after an array you can say square brackets and then a number so 0 would give you this first value right 1 would give you the next value so on and so forth so instead of hard coding this to a number in these square brackets we could just say generate number call our function give it a max value of 2. right so that's going to pick a number from 0 1 or 2 at random so that gives us one of these randomly so let's go ahead and save this file and test it out in the browser so if you refresh your page and jump into the console we can manually run that generate problem function parentheses to call it cool so it's going to give us an object and i think from here you can see how we just want to turn this into a user interface right we want to display this to the visitor right number one operator and number two so let me jump back to our blank page where should we begin well we are going to want to store this generated problem in memory somewhere right because the visitor could open this page up and then take half an hour to actually try to answer so we need a way of accessing these same values again in the future to be able to check if their answer is correct or not so let's do this there are a million different ways you could set up this game but this is what i'm going to do up at the very top of our javascript let's create a variable so let's say let state equal an object and then inside that object let's have one property of score let's set it to zero right away when you get 10 points you win but you start at zero comma let's say wrong answers put that to zero to begin with again once you have three wrong answers you lose okay now let's think about when we need to generate a new problem and display it to the user so it's when the page first loads and it's after every correct answer or if the game starts over so let's create a brand new function let's give it a name of update problem parentheses curly brackets and in this function we want to do two things number one we want to generate a new problem and then store it in our state but then number two we want to update the html user interface to actually visually display the problem to the user so first of all if we want to store it in state we can just say inside our function here state dot right we're working with this object state dot let's name it current problem should equal and then just use this function generate problem okay now that we've stored that in memory let's focus on visually displaying the problem to the user so to do that let's jump into our html and in our body element here let's have an overall div with a class of main dash ui there's nothing special about that name that's just what i'm going to choose and if you want to be on the same page as me you can choose this as well now to start let's have a paragraph that will show our problem so let's say p dot let's give it a class of problem right by the way in case you didn't watch any of the earlier videos in this series i'm just using tab triggers here so you can hit p dot and then whatever class you want hit tab on your keyboard anyways now let's go into our javascript and select this problem paragraph so maybe up at the very top you can select html elements in line in your javascript but i like to just select them once up at the very top so i'll say const problem element equals document dot query selector and then we just give it a css like selector so quotes dot for a class and we gave it a class of problem okay so now we can access that html element with this problem element so in this function below this line let's just say problem element dot inner html should equal and then you could use quotes but let's use back ticks so we can do something dynamic inside the text the first thing we want to do is pull in number one so dollar sign curly brackets to run an expression or do something dynamic so that's just state dot current problem dot number one okay then we want a space right we don't want it all to run together we want a space then we want the operator so dollar sign currently brackets state dot current problem dot operator we want a space dollar sign curly brackets state dot current problem dot number two big picture we're just outputting the problem visually okay now this is just a function definition so we would actually want to run or execute or call this function when the page first loads so right below this we would just call update problem let's go ahead and save this and back in the browser if we refresh cool we see nine times six if i refresh again four plus zero you get the idea now that we're displaying this to the user i think the next logical step is to have an input field where they can try to type in the correct answer so let's jump back into our html and add that so right below our problem paragraph but still within our overall sort of main ui div let's just say form hit tab on the opening form tag let's give it a class or an id it's up to you i'll give it a class so class equals quotes let's name it our dash form inside the form let's have an input field so you can just say input hit tab yes we do want it to have a type of text again we would want to give it an id or a class so that we can hook onto it with our javascript say class equals our dash field and then this isn't required but i think it's annoying if the field tries to show you previous answers you've input into it i don't think showing previous values makes sense in a math guessing game so i'm going to say auto complete and set that to equal off okay then still within our form but below the input let's have a submit button so just button hit tab let's have it say submit okay let's save this and see what it looks like visually cool so if i try to put in the answer and hit submit or enter on my keyboard well it completely reloaded the page right and you can even see it added a question mark at the end of the url we don't want that so we don't want the default behavior when you submit a form in a web browser we're not trying to send this data off to a server anywhere we don't want to change which url you're on and we definitely don't want to reload the entire page so we want to use javascript to prevent that default browserish behavior let me show you how we can do this so back in our javascript let's begin by selecting that form so up at the top say const you can name this anything but i'm naming it our form equals document.queryselector it had a class of our dash form okay so now we have this that represents that form html element let's go down to the very bottom of our code here and let's say our form dot add event listener parentheses to call it so in javascript when you have an object that represents an html element it has a method add event listener when we call it we give it two arguments so for placeholder a comma b the first is the specific type of event you're listening for so are you listening for a click for a mouse hover for a scroll for a keyboard press in this case we're listening for the submit event so this will cover both our bases whether the user clicks on the submit button or presses the enter key on their keyboard to submit either way this event will happen when the user submits an answer and then the second argument is a function that we want to run in response to that event happening now you could provide an anonymous or arrow function here but just to stay organized why don't we create a named function we can call it handle submit and then on a new line of code we can just create a function with that name so function handle submit parentheses currently brackets now we're circling back to the actual task at hand and that is we want to prevent the default web browser-ish behavior of thinking we want to send this data somewhere and then completely reloading the page we want to prevent that behavior with javascript so to do that in the parentheses for this function we can include a parameter you could name it anything but i'm naming it e this is short for event essentially when add event listener calls our function it's going to pass into it all sorts of information about the event that just happened so that's what this is going to be inside our function so in here we can just say e dot prevent default and that's a method so we call it with these parentheses let's save this and now if i reload now when i try to type in my answer or submit the form nothing happens this is perfect this is what we want so now we can sort of make something happen ourselves all with javascript and we keep the user on the screen without trying to redirect them to a new url we don't want to completely re-render the page at this point i think the next logical step is to determine if what they typed in is the correct answer or not so here's how i would do that back in our javascript inside our handle submit function right below this e dot prevent default that's still inside the body of the function let's create a variable and call it correct answer i'm not even going to set it to equal anything on this line of code i just want to create a variable with this name in this scope essentially before we even worry about what the user typed in i first want us to determine or compute the correct answer so first let's handle the situation if the operator is addition and then once we have this up and running we can set up the subtraction case and the multiplication case so i'll say if parentheses we can fit what we want to do if this is true all on one line so we really don't need curly brackets so we'll just say if state dot current problem dot operator if that equals so quotes the plus symbol if that's the case then what do we want to do we can just say correct answer equals and then we would just look inside state dot current problem and add together number one and number two now actually to save a lot of typing why don't we create a variable that points towards state dot current problem just so we don't have to keep typing this out over and over so right here we can say const name it something really easy to type like p p for problem so const p equals state dot current problem so then right here this can just be p so the condition is if the current problem if it's operator equals this then correct answer should equal p dot number one plus p dot number two okay now that we have this we can just duplicate this for the subtraction scenario so just copy that line say if p dot operator equals dash or subtraction then the answer would equal number one minus number two and then finally paste it in again if the operator equals x remember we wanted to visually show x instead of asterisk well then the correct answer would equal and then we change the operator here to asterisk okay now below all of this but still in the function now we can compare what the user just submitted in the form with this correct answer value so let's set up another if parentheses create the brackets in this case we do want an else block as well right if the answer is correct or if the answer is wrong for the condition we're going to want to check the value of that input field so let's go up to the very top of our document and select the field element so you can actually just duplicate this line change the variable name to our field change the selector to our field okay now we have this that we can use down at the bottom of our code the condition is if and before we actually grab the value of the input field let's make sure that we parse it as a number or as an integer right instead of a string of text so you can just say parse int this is a function in javascript parentheses to call it you give it two arguments so a comma b i'm not going to lie the second argument is a bit over my head in terms of mathematics but i know that if you give it a value of 10 this is going to sort of behave the way we would expect it to behave it's going to parse it as a number instead of a string of text so the first argument instead of a that's just the number that you want to parse or i should say the value or string of text that you want to parse as a number so that would be our field dot value okay so now this is going to be whatever the user submitted and then right after that so in between these two closing parentheses here let's say double equal sign we're checking for equality if what they entered equals correct answer now you could set this to be a triple equal sign and that will make sure that they're of the same type as well because javascript can do some weird things where it converts one type of data into another type right like the difference between a string of text a number a boolean value so to review one equal sign is how you say that something should equal something you're assigning that value two equal signs is how you can check for equality and then three equal signs make sure that the two values are also of the same type and there's no weird value coercion going on okay but anyways if this evaluates to true that means they typed in the correct answer so in the if block just for a quick test we can alert out and say good job in the else that means they got the answer wrong so let's say alert try again let's give this a save and test it out so back in the browser if i refresh let's try value of nine cool you see good job now obviously we didn't tell it to switch to a new problem yet but if i type in something wrong on purpose try again perfect so now that we can tell if the answer is correct or not we don't actually want to just display an alert instead why don't we work on outputting this text here if i zoom in a bit you can see it says you need x more points and are allowed to make x more mistakes and then that way we can update these values if you get a question right or if you get a question wrong so to do that let's jump into our html and maybe right below the form let's just add a paragraph and say you need and then i'm going to wrap the number 10 inside a span so span tab put 10 inside that and say you need 10 more points comma and are allowed to make let's have a span two more mistakes okay then let's give these spans a class or an id so we can select them with our javascript so i'll just say class equals maybe points needed and then i'll name this one class equals mistakes dash allowed okay if we save that and refresh okay so now instead of the annoying alert pop-ups we want to do two things one we actually want to keep track in memory the score but then number two we want to visually update or re-render these values on the screen let me show you what i mean so back in our javascript within the if block instead of the alert that says good job we'd first want to increment our score in state right up at the very top remember we created this object state equals and as a property of score well we just want to increment that value and then if you get the question wrong we would want to increment this state dot wrong answers value so down here instead of alert good job let's say state dot score plus plus to increment it or add one to it instead of the alert try again we would say state dot wrong answers plus plus so that's task number one we affected those values in memory task number two is to actually visually update our user interface now we could select html elements down there on our if else but i like to do that all up at the top so up here we can just say const let's call it points needed equals document.queryselector and i give it a class a dot of points dash needed i'm just going to copy and paste duplicate that line this one will be named mistakes allowed and the query selector was dot mistakes dash allowed okay so now down in our if else in the if block in addition to just incrementing the score we would also want to say points needed dot and then we could use inner html but really we should only use that when we need to actually set html if you're just setting something that's plain text right in this case just a couple characters we can instead just use text content should equal and then we can just say you need 10 points to win so 10 minus state.score okay if you get the question wrong in the else block after this we can say mistakes allowed.text content equals 2 minus state dot wrong answers let's give this a save and test it out if i refresh so this would be negative seven cool you can see now i only need nine points or if i refresh and get it wrong on purpose cool you can see now i can only make one more mistake now at this point there are several next steps we could take because there are several things we need to work on so if i refresh and get the question correct we would want to generate a new question if you get it right and we would also want to clear out your previous answer and refocus this field for you okay so that's one thing we need to work on also if you get the question wrong and you just keep getting it wrong we need to have some sort of logic that checks to see if you have made three mistakes or if you've scored 10 points right we need the logic in place that sets up either the win condition or the lose condition let's worry about that a bit later for now let's set things up so that if you get the question right it gives you the next question and clears out the input so back in our if block if you get the question correct after these two lines we can just call that function that we already created called update problem right we already created this function up here it's going to generate a new problem store it in our state and then render it to the user interface okay so if we save that refresh if we get this question right cool we see a new question this was also updated let's update that function though so that it deletes whatever is in the input field and re-selects the field in case you click on the submit button right so for example if i say zero but instead of pushing enter on my keyboard if i click off that field and click on the submit button we would then want this field to be reselected so you don't have to click into it manually so within this update problem function let's add a couple new lines let's say our field dot value we just want to clear out the previous values that it's empty right so the user doesn't have to manually backspace or delete their answer and then let's also focus the field so our field and then just call a method of focus let's save that and give it a test 16 i'll click on this button so it reselected the field automatically put my cursor there and now i can just keep going cool but notice that even if i get more than 10 questions right well i should have just won the game but we didn't set up our win condition or our lose condition yet so now let's work on that so down in our handle submit function regardless of whether you get the question right or get the question wrong we're going to want to check the logic either way to see if you just won or if you just lost so actually what i would do is right after the closing else block let's just call a separate function let's call it maybe check logic and then down at the very bottom we can create a brand new function with that name so function check logic okay inside this function i'd have two if blocks and we could even give ourselves a comment to stay organized so the first comment can say if you won and then if you lost so for if you won it would just be an if statement the condition would be if state dot score now equals 10. and the condition for if you lost would be if state dot wrong answers equals three now in either of these situations we would want to display a message to the user either congrats you won or sorry you lost and then we would also want to reset the game in either case right so you'd want to set their score back down to zero and their wrong answer is also back down to zero so inside this if block why don't we say alert congrats you u1 but then also right below that let's call a function that doesn't exist yet but it will be called reset game and then i'm just going to copy this into this if statement as well only now it would say sorry you lost okay now let's go set up the function called reset games maybe down here we can say function reset game so when the game gets reset we want to do several things first why don't we generate a new problem or update the problems update problems call our function we'd also want to set state dot score to equal zero again state dot wrong answers to equal zero again we'd also want to update the user interface in that paragraph right so let's say points needed dot text content that should equal 10 once again and mistakes allow text content that should equal two once again let's give this a save and see if it works or if i forgot something so refresh i'll get these wrong on purpose so there's one mistake two mistake this third mistake should reset the game sorry you lost and if i click okay cool we get a new problem and this is reset off camera to save some time let me try to get six answers correct okay i just need two more cool congrats you won and as soon as i click ok score gets reset new problem appears at this point we have the basic skeleton of the game up and running for the next bit of the video we're going to focus on improving the user experience so if you look at the finished product there's this cool progress bar right and as you get the questions right it animates or fills up also if you get a question wrong notice this turns red and also sort of gives you a zoom effect also when you win or lose notice instead of the browser default alert pop-up we instead blur the background behind in the actual game and we have this sort of overlay screen that appears and then you actually can click this css styled button here to reset the game now if you're not interested in this user experience or design bits of the video do go ahead and skip to the end of the video instead of just closing this out because at the very end of this video we're going to talk about the major problems with this application well maybe not this application in particular but just sort of the problems with front-end javascript in general i'll give you a hint it has to do with the disconnect between our values and memory and the user interface that we actually want to render discussing this will segue perfectly into our next video and next topic but let's not get ahead of ourselves let's go ahead and set up this progress bar that sort of animates as you earn points so to set this up let's add a bit of html to our page so back in our html right below this paragraph with our you need x amount of points text let's add a new div and let's give it a class of progress and inside it let's have another div with a class of boxes as in plural and then inside of that i want 10 divs each with a class of box now you could just select this and copy and paste it so there's 10 of them however i want to show you a cool trick this should work in codepen vs code or any other editor that has emmet installed i like vs code because it has emit installed by default but we can just say div dot box asterisk or multiply 10 hit tab cool we have 10 of them okay finally not only after all 10 of those box divs but also after this closing boxes div but still within the progress div let's have a div with a class of progress dash inner so this will be the element that animates or fills up with green and then these will sort of just be the 10 empty placeholders to visually divide up the progress bar in 10 equal chunks so if we save that and refresh visually we don't see anything because all of those divs are empty but now let's just go write a little bit of css to make it come to life so if you haven't already in the head section of your html go ahead and link towards a css file like this okay i've already created an empty styles.css file here it is so let's begin by selecting the box class right there are going to be 10 of these and i'm just going to say have a height of 40 pixels and let's give it a border on the right side just on the right side so border right one pixel thick solid we don't want it dotted or dashed just a one pixel solid for the color let's say hashtag c7 c7 c7 let's give that a save now this looks a bit odd but it's because each div is going to sit on its own line so instead if we tell their parent element to use flexbox then all 10 of those divs will sit on a single line so let's do this in our css let's target the parent element boxes and just say display flex and then because all of the content is empty this still won't really take up any space horizontally but if we say width 100 percent that will sort of force it to take up space horizontally let's give that a test well they all sit on one line now but they're not taking up any space so maybe in our box rule let's say flex one right so they all take up an equal amount of space let's give that a save cool this is a move in the right direction so now we can just give the overall progress div a top border and a bottom border well and a left border as well just basically a border on every side except the right side so in our css i'll say dot progress border one pixel solid c7 c7 c7 but i will say border right none because we don't want a double thick border on the right edge since each individual one is already having it so if we save that cool so we have 10 equal boxes now we just want to work on the green progress bar that sort of animates or fills up to represent your score so back in our css let's create a new rule for progress dash inner and i want to position it absolutely in relation to its parent so first i want to tell the parent to use position relative and then on progress enter we can say position absolute we want it to use the full height of the parent so top zero bottom zero and to start out let's have it use the full available width so width 100 percent let's give it a green background color so background dash color hashtag 7 e c c 0 0 and i want it to be a little bit see-through so maybe opacity 0.57 okay let's see what that looks like cool so now instead of it always just being the full width we need a way to change its size horizontally on the fly so here's what i would do in order to get the smoothest possible css animations instead of modifying its width value we actually want to use transform and say scale x this way the web browser won't try to repaint anything else on the screen it can just use the graphics card to actually re-render this one element on the page so if we say scale x 0 that's going to make it invisible because it's zero percent of its original size but if you say 0.5 or you don't need the zero just 0.5 semicolon at the end there that's going to take up half of its normal size right or if you give it a value of 0.9 that's going to take up 90 percent of its original size obviously if you give it a value of 1 it will just be its natural size so let's put this back down to maybe 0.5 but we don't want it to be centered we want it to be aligned on the left so we can just say transform origin center left so the first value controls the vertical placement this controls the horizontal placement give that a save cool now when we change this value on the fly with javascript depending on how many points you've earned we don't just want the bar to change immediately we want it to animate or transition so let's say transition the transform property maybe over the course of 0.4 seconds and we'll use the ease out timing function save that now if you wanted to you could go into your dev tools and in the css panel if you change the transform scale x value you'll see that this animates but for now you can just take my word for it let's use javascript now to actually change that value when you get a question right okay so by default we would want this to have a value of scale x zero right when you first come to the page you have zero points okay at this point let's tie it all together with javascript so back in our js file up at the very top let's select that progress enter the green div so const let's call it progress bar equals document query selector it had a class of progress dash enter okay let's scroll down to the if block for when you get a question correct so currently we're incrementing the score outputting the new text needed and updating to a new problem right below that let's just say progress bar so this is an object that represents that one html element we want to look inside it for a property of style and i want to push dot again to look inside this but you can see that vs code is going to try to auto fill this into something else i don't want that so i'm just going to hit the escape key on my keyboard and now if i hit dot i can look inside it we're looking for transform equals and now this is how we can change that value from within javascript so i'm going to use backticks instead of just regular quotes and then just say scale x parentheses inside this i'm going to do something dynamic so dollar sign curly brackets and then just pull in the score so state.score divided by 10 right because that's going to give us a fraction if you have 5 points divided by 10 that's going to be 0.5 let's save that and test it out so if i refresh if i get a question right cool let's also make sure the progress bar updates when the game resets so if i get questions wrong on purpose three times so i lose right and then i hit this button to reset the game we would want the progress bar to go back down to zero so here's what i would do this line of code is responsible for re-rendering or updating the size of the progress bar so instead of duplicating this in the reset function i would just copy this into my clipboard and then in its place here let's just call a function let's call it render progress bar parentheses to call it and then we can call that in our reset game function as well just say render progress bar and then we just need to create down here an entirely new function with that name so function render progress bar parentheses curly brackets paste in your clipboard for the body of this function let's save that and test it out so if i get a few questions correct cool but now if i get them wrong on purpose to reset the game cool now that our animated progress bar is up and running let's switch gears and let's focus on showing an overlay right with sort of a transparent blurred white background and then instead of the browser default alert we have a bit of custom html that appears right about here in the middle so for example if i look at the finished product and get questions wrong on purpose right you see the background is blurred we have this sort of full screen overlay sorry you lost and then you can style this content however you want and then when you click this button it resets the game so let me show you how i would set that up so first i would jump into our html and down towards the very bottom so not only after our progress div ends but even after our main ui div ends after that so just in the root of our html i'd say div dot overlay inside that i'd say div dot overlay dash enter inside there i'd have a paragraph that says congrats u1 now obviously we'd use javascript to make this dynamic but for now let's just hard code it and get the styling up and running and then let's have a button that says start over let's save that now we just want to use css to make this appear as sort of a full screen semi-transparent overlay so to set that up let's jump into our css let's create a new rule for overlay i want it to take up the full screen even if you scroll so let's say position fixed top zero bottom zero left and right zero let's give it a slightly transparent or see-through white background so background color let's give it an rgba value i think this is the first time we've used this in this series so the first three values you give it a value of anywhere from 0 to 255. now if you max out all three values red green and blue that creates white if you set them all to zero that would create black and then obviously a mixture of any other values can create just about any color in the world so that's the first three values red green blue but then if you add a fourth value that controls its opacity or transparency so a value of one is it's fully visible value of zero would be completely invisible but if we say maybe point 82 basically 82 visible give that a semicolon at the end if i save that and refresh so you can see here's that content it's positioned sort of on top of everything else the background is just a little bit see-through okay but now we would want to center this content both vertically and horizontally on the screen so to do that i would just say display flex justify content center and align items center see what that looks like cool now let's set it up so that the overlay is invisible to begin with and then you can maybe just add a class to the overall body element to both make it visible and to blur the main ui div here's how i would do that so back in our css in overlay i would say opacity should be zero and visibility should be hidden okay however if we go into our html let's set it up so that if on our opening body tag up here if we give that a class of overlay is open be sure to save that just for testing purposes if that exists on the body element then we want to blur the content of main ui and then actually make the overlay visible so in our css we can just say body dot overlay is open look inside that for the overlay div and then that's where we can set the opacity to 1 and visibility to visible and why don't we have it so it animates open so we can say on the baseline rule transition all properties over 0.33 seconds using ease out we can also maybe have it zoom so it sort of zooms in so we could say transform scale maybe 1.2 and then when it's actually open we can just set it scale back to normal so transform scale one okay now to make that main ui blurred here's what i would do just create a new rule say body dot overlay is open inside it look for the main ui div and then just say filter blur with a value of 4 pixels let's save that and if we refresh cool you can see the background content is now blurred however if we go into our dev tools and remove that class from the body element right so here's my dev tools here's the body class if i remove this overlay is open and push enter notice how the overlay sort of animated or faded away so now we just want to control that from within our javascript instead of hard coding anything in our html so back in our html on the body tag get rid of this class and then also down in the overlay html let's hollow out the value for this paragraph text so just an empty p element because the overlay displays whether you win or lose right as long as the game is over this will display so we would want this to be dynamic either a win message or a lose message so we could give this p a class so that we can select it in our javascript class equals end message okay let's save that and then back in our javascript let's find our function that's called check logic so this is the win condition and lose condition so we don't want to show that annoying alert so let's get rid of that instead let's set the paragraph text to say congrats you won then as soon as we do that we can add that class to the body tag to make the overlay visible so let's go select that paragraph element up at the very top just say const and message equals document.queryselector had a class of end dash message okay now we can go use this back down in our checklogic function within the if for the win condition we would just say end message dot text content should now equal congrats you won okay now as soon as that is set on the very next line we can just make the overlay visible by saying document.body.classlist dot add call that method give it a class or a value i should say so a string of text of overlay dash is dash open okay now let's copy these two lines of code into our clipboard and then down in the losing condition just get rid of that alert pop-up instead just paste in your clipboard and change the message to sorry you lost let's give this a save and test it out so if i reload if i get three answers wrong on purpose to see the error message sorry you lost cool so now we want to set things up so that when you click this start over button it closes the overlay and it sort of resets the game so to do that let's jump into the html and give this button a class so that we can select it with javascript back in our html on that opening button tag i would just say class equals maybe reset dash button give that a save back in our javascript up at the very top you can just duplicate one of these lines give the variable the name of reset button the class was reset dash button okay and then down towards the bottom of our code within the check logic function instead of calling reset game immediately let's wait until you click on that button so let's get rid of these reset game calls instead maybe right above the reset game function we can just say reset button dot add event listener call this method the event we're listening for is when it gets clicked on comma the second argument is the function we want to run in response which would just be reset game okay and then to make the overlay disappear inside our reset game function we can just remove that class from the body element so right inside the body of this function i would just add a new line and say document.body.classlist this time it's dot remove class we want to remove was overlay dash is dash open save this and test it out so now if i lose on purpose sorry you lost and if i click on this button cool however i think it would be nice if you could reset the game just by pressing enter on your keyboard what i mean is if i lose on purpose again i think the start over button should be focused so that i don't even need to take my hands off the keyboard and move my mouse to click the button if it's focused then i could just press enter on my keyboard since that's already what i was pressing to enter answers into the input field and then it would start the game over right because if this is focused it's going to register the enter button as a click so to set that up within our check logic function we could try to focus the button as soon as we display the overlay but remember that our overlay takes 330 milliseconds to actually animate into view and in certain web browsers if you try to focus an element before it's actually visible it won't be correctly focused it won't work so to make sure this works in just about every web browser i would actually just wait maybe 331 milliseconds and then focus the button so right about here right after we add the class that makes the overlay visible i would just say set timeout you give this two arguments so a comma b for placeholders second placeholder is how many milliseconds you want to wait the delay before your function runs let's say 331 milliseconds and then the first argument is a function that you want to run now you could create a named function or you could create an anonymous function but let's actually create an arrow function so an anonymous function would just be function parentheses curly brackets without giving it a name well similar to this is an arrow function and an arrow function is where you just don't need the word function so you just have a pair of parentheses and then this arrow symbol which is just equal sign greater than squished together okay and then if the body of our function is just one statement we don't even need the curly brackets so you can actually get rid of that so just parentheses arrow symbol and what we wanted to do after the delay is just say reset button and then call its focus method okay let's copy this line of code and then just paste it down here in the losing condition so right below that line just like this let's save this and test it out so if i lose on purpose i'm just pressing enter on my keyboard cool notice the reset button gets selected so i don't even have to take my hands off the keyboard if i press enter again awesome at this point we're almost done i'm not going to bore you with all of the super specific css for text align center and font size and font family we've already covered that in earlier lessons and if you do want your game to look exactly like mine you can find a finished product codepen link in the description of this video with my exact code however before we bring this video to a close i do want to show you how to implement sort of the red animation so when i get one wrong notice how the problem sort of zooms in and turns to red for just a split second so i do want to show you how we can set that up so back in our copy of the game it looks like this back in our javascript above our checklogic function i'm looking for our function that checks to see if you got the question right or wrong so that's our handle submit and let's look for the if else section so else if you get the question wrong this is where we would want to animate the problem to sort of turn red for a split second and zoom in a little bit so within the else block i would just say problem element right we've already selected that p element and i would just say dot class list dot add that's a method let's give it a string of text of we could make up any name but let's call it maybe animate dash wrong okay and let's imagine the css animation takes 330 milliseconds well once it's completed i would want to remove this class from that element so that if you get a wrong answer again it's ready to receive the class and animate again so just right below this i would say set timeout give it two arguments right a comma b is a placeholder let's wait 331 milliseconds after that amount of time we can just include an arrow function here so parentheses arrow symbol right it's just equal sign greater than squished together we don't need curly brackets if we just have one statement in the body of our function and you could actually just copy this line of code paste it right here but just change the add method to be remove right we want to remove that class okay let's save this and now before we actually create an animation let's first just create a style that makes the text red just to see that this is working so in our style sheet at the very bottom we could just say dot animate dash wrong that's what i named the class and just say color red let's save that and test it out so if i get a question wrong on purpose cool it didn't last very long but if you watch this very closely it turns red cool so now to actually have it sort of animate or fade into red and maybe zoom in a little bit to really draw your attention that you got it wrong let's do this instead of just saying color red let's say animation colon 0.33 seconds and the name of the animation we want to use well we haven't created the animation yet but let's imagine we name it maybe show error semicolon okay so the web browser is going to use this animation and make it last this long so now right above this we just want to spell out an animation with this matching name of show error so right above this we say at symbol keyframes and then the name of the animation you chose so we made up a name of show error curly brackets now inside here you spell out what kind of styles you want to use at different percentages so for example i'll say 50 of the way through the animation right so as the animation plays right halfway through this time period i want the text to switch to red and i want to zoom in a little bit so transform maybe scale 1.2 and then you can set any other percentages you could say at 75 percent i want it to turn blue or at 80 through the animation do this or that but i'm just going to say at 100 so once the animation completes it should just put it back to its standard color so either a dark gray or a black and put the scale back to normal too so transform scale one okay but you're free to experiment with css animations you can add intermediate points where it rotates or changes colors or anything you want to do but let's save this and test it out so now when i get one wrong that did not look good at all i think it would look a lot better if this text was centered so let's see in the css we can just say dot problem make sure the text align is set to center let's try that out so now when i get one wrong i think that makes the animation look a lot smoother but there you can see it's turning red and zooming in if you wanted the animation to be a bit slower that's not a problem you could just change this from animation wrong maybe bump it up to 0.45 seconds and then back in our javascript you would just want to wait that long before removing the class right so then you put this maybe milliseconds let's test that out so if i get this wrong notice the animation is a little bit slower now cool now again i'm not going to bore you with the exact font sizes and text align center and padding and margin that i set up in this finished product right in the exact font family i chose so on and so forth but aside from those tiny css details we have now completed our math game again if you do want to see my exact finished styling code you can check out the codepen link in the description but that is going to bring the technical aspect of this video to a close that was another long video but hopefully it was worth it and you feel like you learned something anyways where do we go from here well at the start of the video i said that the challenges we would run into while building this app would segue perfectly into our next topic now before i say what our next topic is let's first discuss what the challenge was while building the math game i would say is that it felt like there was this huge disconnect between our data and our user interface so remember we had an object we named it state and it kept track of how many points you have and how many mis and how many mistakes you've made so far well there wasn't any way for us to tie that data to the user interface in a way that didn't feel fragile or messy right it felt like we had to babysit way too many different html elements and update their text content at just the right moment and all of these different moments it just didn't feel very ideal or robust and so this does bring us to our next topic which is something called react what in the world is react well it's the world's most popular library for building user interfaces and in our very next lesson we're going to get started with it however before we jump into that next video i am going to give you a little bit of homework so i have a freely available 10 part playlist here on youtube called the 10 days of react now while it would be helpful if you watch the whole thing you don't need to you really just need to watch day number one or the very first video because it explains the problem that react is solving okay and in my opinion if you don't understand the problem that a tool is solving you have no chance of ever truly understanding the tool so for the next few nights your homework is just to go at least watch day number one of the 10 days of react i think that'll set you up perfectly for our next video essentially in our next video we're going to use react to rewrite our math game in a much more elegant fashion anyways that's going to bring this video to a close if you've been enjoying this series so far like always i'd appreciate it if you could share the link with your friends and family take care i'll see you in the next one [Music] you
Info
Channel: LearnWebCode
Views: 12,254
Rating: 4.9766989 out of 5
Keywords:
Id: EVze4Cq-dZ8
Channel Id: undefined
Length: 65min 4sec (3904 seconds)
Published: Wed Sep 09 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.