FREELessons: 29Length: 8 hours

Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

3.5 Full Control With animate

Up until this lesson, we've been using jQuery's helper methods, such as fadeIn and slideDown(). However, behind the scenes, these all reference the animate() method.

Today, we'll review how to use it, and why it's necessary when you require full control over your animations.

Homework

Tonight, I want you to create your own fadeSlideToggle() method that will combine the functionality of slideToggle and fadeToggle. You may not reference either of these methods directly; instead, you'll use animate(). Hint: jQuery allows you to pass the string, "toggle," as a value for height and opacity.

When finished, the method should be called, like so: $('#box').fadeSlideToggle();. We'll write a solution together in the next lesson, but try to do it by yourself this evening.

3.5 Full Control With animate

[NOISE] Up until this point, we've relied exclusively on jQuery's built-in effect methods. Such as slide toggle or fade toggle or show and hide but what if you need to animate something different for example, you need to animate the width or the height or the font size. Well, we can have more control by using what all of them are ultimately using behind the scenes and that's the animate method. If I switch to Chrome, you'll see that we have a little project here. We have a box of content and a button below, and the goal is when we click on that button, we are going to increase the font size within the box. So we're going to begin by taking a look at how we would use the CSS method. We'll revisit that shortly, and then we'll translate that over to using the animate method to achieve the same effect, but, by achieving the result incrementally rather than all at once. Now, if we open up Sublime Text you see I've styled the box giving it the red background. And here's our content and our button. So we should know how to do this at this point, it should be fairly simple. First step is grab that button. We'll be generic here and assume there's only one. If you need to add an ID definitely do for your project. And we're going to listen for when is it clicked. And when it is, we'll run a callback function. You should know all of this at this point. If not, go back and watch some of the earlier lessons. So when this button is clicked, we need to grab the div with the class of box and update its font size. So we'll hardcode a lot of this in and slowly improve and refactor. Grab the element with the class of box and we're gonna use the CSS method and we will update the font size. Or you can use font size when you're accessing it through the dom, but j query will allow you to use a dash. And for now, let's change that to 25 pixels, like so. All right. Let's try that out. Refresh. I'll click on increase, and sure enough that seems pretty easy. But if we come back, this doesn't do very much because it's not relative. So every time I click on that button, it's going to default right back to 25 pixels after the very first time. So wouldn't it be cool if we can make this relative and if we can. But before we do that, let's take a look. Every time the user clicks on that button, why are we jumping into the dom and looking for all elements with a classic box. That's really wasteful and I want to drill this into you. Don't do more work than you need to. Now, let's fix this. The first step is, because we're looking for a class, llet's precede it with a tag name, and especially when dealing with classes. This is a little bit better, because this way, rather than looking for every element on the page and determining whether it has a class of box. This way we can limit it to only divs. And then check to see whether those divs had a class of box. And then next, I'm going to get this outta here. And we're going to reference it above. That way, if we store it within a variable, we're only querying the dom for it, one time. And then up here, I can reference it like so. So now if I come back, we're getting the exact same effect but we've refactored our code. This is a much smarter solution for performance. Now, how do we make this font size relative? How do we increase it by five? So if the default font size is 16, when you click on the button, it will go to 21. Click it again. It goes to 26 then 31 et cetera. Well, I'll show you the old way we used to do it and then I'll show some of the new ways that jQuery makes it super simple. So right here, we will create a new variable called font-size. And once again, I'm going to wrap this all within a self invoking anonymous function, and you should be very familiar with these by now. We are getting rid of those global variables that we don't want. This font size is going to be equal to box.css and we are going to capture the font size. Now if I log that to the console, what you are going to see is probably around 16 pixels. Refresh, and sure enough, we are getting that string value and that's important. If we log "type of" to figure out what kinds, it's not an integer we are returning and what that means is, that is really important, because you cannot add an integer to it. So if you thought it was as easy as saying "Grab that variable and add 5 to it." No, it's not quite like that. What you're going to get instead is, you're trying to add an integer to a string, and if you have any decent knowledge of working with JavaScript, you'll know that when you add an integer to a string, it simply [UNKNOWN] that integer to the string so you end up with 16 pixels five. So, what we need to do is convert the returned value to an integer. And an easy way to accomplish that is to take advantage of JavaScript's parseInt function. And what this will do is it will read a value and it will take those integers. And as soon as it comes to anything that's not a digit, it'll chop that off and it will convert the existing value into an integer. And what that means it now. Sixteen pixels. The string is converted to 16 the integer. And then when we add five to it, we correctly get 21. All right, so that seems a little bit better. Now we can replace the hard coded 25, and we can say font size plus equals five. Now font size plus equals five s the same thing as font size = fontSize + 5;." We are adding a value to it and assigning it back to that variable. So, when you click on the button, "fontSize" will then equal 15, then 20, then 25. And that way we hold onto the value. One more time, let's close this out. Click on it. And now we're getting a relative value. Pretty cool. So this is the way we always did it before, now I'm going to show you how much easier it is. Let's remove this entirely. And now instead of parsing the string and adding to it we can simply use this syntax +=5. Let's try it. Check it out. Much, much easier. And that's a relatively new addition to jQuery. And what this is, is it's relative. So, we're saying we're gonna get the value of font size and we're going to say plus equals 5. So we're going to add five to it every single time. If you want to reduce it, you would say minus equals maybe one pixel each time the button is clicked. And then it goes down. Cool. So what if now we want to add something else, some other property? Maybe we want to make the color white. Well a big mistake that a lot of newcomers make is they keep stacking the CSS method. So they'll do this. CSS, color is right. They just stacked those CSS method calls. And if you try it, yeah, that is going to work, but that's not the way you want to do it. Instead, rather than using strings we can pass an object to this CSS method. And that's what we're gonna do this time. I'll pas an object here and now I'll save the font size or you could reference font size like that. And we'll make that equal to, once again, plus equals five. And then here, we can specify the color should be white. Increase, and now we're getting that effect, but we're only calling the CSS method exactly once. So now that we have a, a fairly solid understanding of using the CSS method. Let's switch this out for the animate method now and see what we get. Reload and I'll click on it and as easy as that now we're animating to that value. Incrementally updating the font size until we get to our desired size rather than instantly going from 16 to 21, increase. There you go. And that looks a little neater. Now you'll notice here, though, that it did not animate the color and that's because the animate method doesn't have the ability to animate from one color to another. To do that, you can either take advantage of CSS and CSS3 transitions, or there are lots of jQuery plugins that will do anything you need. The creator of jQuery, John Resig, he created a color plugin a long time ago, and that will give you that functionality. Now in this case, let's replace it with something like width. And we're going to take the width and we're going to increase it by 300 pixels. Notice that I'm not adding pixels here because the default unit in jQuery will be pixels. So it will know that we're working with pixels. Let's try it again. Click on it and now the width increases and the font size simultaneously. If we inspect this, what you'll see is the animate method is adding style attributes and it's doing that over and over, superfast. So ultimately we get to 700 pixels and 21. Now watch what happens if we reload and I click on it again. I want you to pay attention right here and you'll see that those value updated very, very fast. One more time and now you can see how that takes shape. There are two different ways that we can structure the animate method and we'll take a look at both of them. The first way is we pass our property, then as a second parameter. We specify how long it's going to take. What is the duration of this effect? So if we set it to three seconds and we reload over the course of three seconds we're going to move from the default values to these new values. Increase one two three, and now that's finished. Now, if you do not pass a value similar to slide down or fade in, jQuery will use its defaults. One more time. That's using default which should be about 400 milliseconds. Now and in addition to this, we can also specify the easeIn and all of these are optional. Now the default will be swing but you can also adjust this to linear. And Linear is going to be the same speed every increment no matter what. And you can think of that as maybe like a monotone voice where it never changes. It's the exact same tone the whole time, whereas swing will go down and then slowly comes back up. And then you translate that to speed and you get the basic idea. Now, these are the two options that you have. If you need more, there is a very, very popular easeIn plugin that will give you access to lots of different options like easeInBounce or Expo. You can play around with them a lot. Simply Google jQuery easeIn plugin. Now, these are optional, so we'll stick with the default. And then the fourth parameter would be a call back method. And this will be triggered as soon as the animation completes or in 500 milliseconds. Console.log completed and if I've reload, I click on increase after a half a second that callback will be triggered. And that's where you can perform any kind of action that needs to wait for your animation to complete. Now, the second way that we can use animate is by passing a total of two parameters. So, we can say box.animate. We pass our properties. So, in this case, we'll stick with one plus equals five and then we pass an object as a second parameter. And this is where we can specify additional things. We can specify the duration. We'll set that to 500. Let's make sure that's working. Increase. Same effect. We can pass once again our complete call back method. Completed. We can pass a step method. And this method's going to get called For Every Iteration of the Animation. So for example, if I say step here. And if I reload, you'll see that it will be called a bunch of different times. And this will be if you need to perform any kind of different operation each step of the way, you can do that. For instance, if we wanna console.log, if you're curious, what does this refer to in this context? Increase. You'll see that this is going to refer to the element that we're manipulating, in this case, the box. So then, we could say, console.log this.css fontSize, and we could say, The current font-size is. And we'll wrap this within string. And this way we can see for each step or each increment what the font size is equal to. And I need to wrap that within jQuery of course to access the CSS method. Let's try it. Click "increase" and there we go. And now you can see how that's working. Now there's also another option you can ask called Q, and let's take a look at this one. I'm going to delete these because we're not going to be working with them. We'll keep the duration though. Now, we can stack the animate method. So, if we want to do another one, and let's clean this up just a touch real quickly, we can once again animate. And this time, we'll say font size. Once again, we will plus equal. Ten this time, and we're going to do that over 500 milliseconds. Let's try it out. Increase. It goes up, and then it goes up even faster. So to really see that take effect, let's change that to three seconds. Increase. It goes one step. And notice that when we stack the animate method, meaning we call it once and then we call it again, the second one will wait for the first one to complete. So we can see this even easier if we set top equal to 500. Now it's important to remember when you're adjusting the top, right, left and bottom values you're still restricted the same way you are with CSS. So make sure that you have a positioning context or it simply won't take effect. Now, if I increase the font size goes up and then the box shifts down because we adjusted the top value. If we add a length to that or a duration, now we get that as well. But what if you're in a situation where you want them to occur simultaneously. Well, you could place here top 500 pixels, but the problem is now both of those are bound to the exact same duration. So they will both take one-half second to complete. But if you're in a situation where, note that top needs take three seconds to complete, and a way to get around that is to stack them. Then as a second parameter, we can specify the duration is three seconds. And we can set queue to false. And what that means is that we are not going to add this animate method to J's queue so that it knows to trigger each one and then knock it off the queue and go to the next one and execute that and knock that off the queue. We are saying no this should be bound to the queue. So, this will execute at the same time as the one before it does. Now let's try it. Increase, and notice the value's gong down at the same time. To compare, change that to true, and we're back to where they're doing it incrementally. One more time to false, just to make sure this is clicking. Increase. And now they're both happening simultaneously. Alright, so we should have a basic understanding of the animate method. Let's figure out how we could do a little project to where when we click on this button, we want to animate this box so that it is both vertically and horizontally centered. Okay. Well, let's come back and we're going to update the button text to center. Next and I'm gonna leave this commented so you can refer to it within a downloadable source code. And we'll say when the user clicks on that button, the first step is, we need to figure out what would be the coordinates for a horizontally and vertically centered div? Well let's create a new variable and we'll call this winWidth. And this is how we could grab the width of the window. And this big container right here. Let's see what that would be equal to. I'll add a semi colon and then log that to the console. Reload and you can see I'm recording at 1280 by 800. So the window width because I'm full-screen is 1280. If I shorten this, reload. Now you can see that that's adjusted. So with that in mind, we know that why don't we divide this by two. That starts to make sense. We want this box to be more or less in the center. So our first step is divide the window width by two and see is that value works. So right here at the top we'll say box and we'll use CSS just for now and we'll the left value should be equal to WinWidth. Let's try that. Refresh. Click on Center, and no, that's not going to work because although this point right here would be the center of the window, we're not taking into account the width of the box itself. So why don't we take one-half of the box and subtract it? Minus box.width divided by 2. Let's try that. One more time. Center, and now that's starting to look a little bit better, but it's not exact just yet. An easy way to tell is to shorten the width of the browser window, and then when I click center, you'll see that it doesn't seem perfectly centered here. And that's because box.width is not taking into account the padding that we've applied here. If I get rid of the padding. And we try it again. Now that's working, so it's too bad that there isn't a way with jQuery where we can specify that we want to factor the width and the width of maybe any borders or padding. Well, there is outer width and outer height. And what those will do, as I just outlined, is they take into account. The padding and the border and the margin optionally, and it will include that in what is returned. So, now if I try it, we still have our padding. But when I click on Center, we're getting much closer. And now, the final step is we need to make sure that we are absolutely positioning this. Because otherwise the left value is still going to be dependent upon the existing spot, so we'll have those margins there. If we want to zero out the margin body, margin zero, and now we center it. That is perfectly centered on the page, but once we take into account the existing margin, that's no longer exact. So, if we switch that to absolute, but now when i come back, you'll see that because its absolutely positioned, it's taking out of the flow of the document. And now, the button has been placed all the way at the top. You can't even see it at this point, but it is there at the very top. So what we'll do is we'll dynamically apply that value. Right here, we will pass an object, and then we'll also set the position to absolute. Let's try that now. I will click on this, center, and now this has been perfectly centered and the button will jump up. But likely you would have that contained somewhere else, so that won't be an issue. Let's extend this out again. Click on it. And now that has been horizontally centered on the page. There's lots of different ways to do this now. With CSS, it would be just as easy to adjust the margin. But, because we are going to animating this, we're gonna do it this way. Animate. And now that animate's into position. The next step is because we know this basic formula (window).width divided by 2 minus the width of the container divided by 2. We can update this to w. An h > window.height. You could cache window in the jQuery object if you wanted to. We're not gonna worry about it this time though. And now we can change this to width > top > this h. There we go. Let's get rid of the console. And try it. Center it. There we go, and now we've animated it. So what if at this point, we wanted to animate to the left and then go down once it's completed. Well, because we know that we can stack these, we can simply add another reference to the animate method. And right here, we'll say top is h. And we'll do that one over the course of two seconds. And then we can get rid of it up here. Let's try it. Center, and now it comes down, but it is bounced to that two seconds rather than that default before it. Now again if you want to make sure that those animations run at the same time, you'll want to de-queue. Duration is two seconds, but set queue to false. Retry, center it. There we go. And now it's coming down, like so. And you can see this easier if we do it super fast. One more time, and it's already at the bottom. And now you kinda get a swing effect where it comes down and moves to the right. So you can definitely have some fun with it. Now, it's important to remember that a lot of the things we can use with jQuery animations can honestly be done with css at this point. So while you might be use to doing something, for example, like animates, and let's get rid of these. You might, let's say you wanna add a border radius. Well, you could do it like this, borderRadius and we'll set that equal to 50. So click on it and that is going to work, but it's just as easy to add a class. So you could also say rounded {border-radius} is 50 pixels. And then, rather than animated, you can say add class rounded. Reload, click on center, and now the rounded class has been applied. And if you wanna make that animated, you can simply set some CSS3 transitions. WebKit transition, and we're going to transition the border radius property over the course of one second. Try it again, center it. And now, we've achieved the exact same effect. But we're using CSS to accomplish it which will be much more perfomant. So always think, can I do this with CSS three instead? Now the very last thing is, remember with CSS when you're using these prefixes. Make sure that Firefox has a prefix, Opera, Microsoft does as well. So maybe you can run this through a surface like prefixer and that will go ahead and update that for you. And if you need any help with that, you can visit prefixer.com here at touch plus premium member. You can go to touchplus.com/forums and ask your questions and we'll be happy to help. But now that will work in all of the browsers that support CSS3 transitions. I'll see you later. Bye-bye.

Back to the top