TimelineLite is a piece of the Greensock TweenMax library that provides the ability to create sequenced animation with very little code or setup.
Lukas Ruebbelke: [00:00] Hello, this is Lukas Ruebbelke and welcome to another video on AngularJS and the GreenSock animation platform. In this tutorial, I'm going to show you how to sequence your animations using TimelineLite from the GreenSock animation platform.
[00:21] What we have here is an album with three tabs. When I click the tab the appropriate slide shows up. In the code, what we have is a main controller with a slides array that has three slide objects. We are defining a background image, an avatar, a title and a subtitle.
[00:47] We also have a direction property that we're using to determine the direction of the animation, if we want it to go from left to right, depending on the order in which you click the tabs, as well as a current index property that is keeping track of the current slide.
[01:08] We have a set current slide index method that we're setting in an index parameter. We're comparing that to the current index and if it's greater than the current index, we are setting the direction to left. If not, we're setting it to right, and then we are updating the current index to the new index.
[01:28] Then we have this method, is current slide index. We send in an index parameter again. We compare it to the current index. If they're the same, it returns true. If they're not, it returns false. We are using this method to actually show or hide our slides.
[01:48] We have ng-repeat and we're laying out our slides using slide-in slides. Then ng-hide and we're comparing the index property of ng-repeat, that's $ index, to say, "Is this index of this slide the current slide index?"
[02:07] If it's not, then it hides that slide. We have slide animation, which is our animation that we're going to be hooking into in just a moment.
[02:16] Then inside the slide we are binding to the background property, the avatar property, the title and the subtitle. That's the actual layout of the slide.
[02:30] The cool thing about AngularJS is that we can use the same data structure that we used to lay out our slides to lay out our navigation. ng-repeat, slide-in slides. Then we are dynamically setting an active class based on whether or not that navigation element corresponds with the current slide.
[02:50] Then on click we're setting the current slide index to the index of that navigational element. Then we are binding to slide title for the label on the actual button or tab itself.
[03:06] Let's get started by adding in a simple animation that when you click the tab we're actually going to just animate it from left to right. Then we'll get into the sequencing.
[03:18] We need to actually grab the scope element or the scope of the element that we're animating on, so that's fairly easy. We just go element.scope.
[03:37] When ng-hide is being added, then it's actually hiding the element. So we're going to set our finish point or where we want this animation to finish. We want it to simply finish at the width of the parent, so we want it to basically slide off the screen.
[03:58] Then from here, depending on the direction, if it's not right then we are just going to flip the finish point. Then let's add in our animation.
[04:16] We're going to animate the element, create a half-second animation. We're going to animate the left property, set that to finish point. We're going to use ease, ease in, out, and on complete we need to call done.
[04:42] I'm actually just going to copy this so I don't have to retype everything. Now we're going to do our intro animation. Now instead of a finish point we want to do a start point. We're going to say, "If this does equal right, let's go ahead and flip it."
[05:05] Then from here we are actually going to do a from-to. We want to start at a certain spot and then finish at a certain spot as well.
[05:18] The starting place is pretty simple. Because we know where it's going to end up. It's going to end up at zero, so it's going to slide from either the left or right and end up at left=0We're going to set our starting point here, and then we're going to do set left to zero. We're still going to use ease, .ease-in-out on complete, done. Let's see this in action.
[05:49] Now you can see as I click the tab, it animates it. Now watch when I actually click a tab that is less from an index standpoint than the tab that I'm on. Is that the animation actually goes in an opposite direction. That's what we were setting up with scope.direction.
[06:09] Let's go ahead and actually add in our sequencing. We're going to hop back into the code and we are not going to sequence the outro animation, but we're going to focus on the intro animation.
[06:23] What we need to do is to create essentially a container for us to put our animations in. This is where TimelineLite comes in. I'm going to create a TimelineLite instance.
[06:36] We're actually going to go new TimelineLite. The nice thing is that you, TimelineLite is essentially a container to put in our animations. Well, we can define those animations just like if we were using TweenLite.
[06:58] I can actually just change TweenLite to TimelineLite and it's going to work. But let's chain another animation together, so you actually can just chain these animations in sequentially. Another from-to.
[07:14] I want to animate the title. I'm going to go find, like so. Let's set a half second animation. Let's set our left to -200 and let's set alpha to zero.
[07:35] Then from here we'll set left to zero, alpha to one, and ease=ease-in-out. That should do the trick. Let's see this in action, and then if all goes well, we will animate the other elements in slides.
[07:59] You can see that I animated the title, so it slides in, and then your title slides in, so that's pretty neat. Let's take this just a bit further. I'm going to duplicate this line three times. Just clean this up real quick. Then from here I am going to change title to subtitle.
[08:26] We're going to leave this animation the same, but we are going to change the avatar one just slightly.
[08:35] From here, we actually want this to come in from the right, so we're going to say, create a number greater than the actual width of the slide. Then we will have this come in somewhere in the middle of the slide, so we'll set this to 300.
[08:54] All right. That I believe is all there is to it. We are now basically adding in or chaining four animations using TimelineLite. Let's see this in action. Refresh the page. You can see now you have your title, subtitle and your avatar sliding in.
[09:18] The interesting thing to point out in terms of review, all I had to do was create a TimelineLite instance, continue to define my animations as if I were using TweenLite, and then just chain them together.
[09:34] Then it essentially does one animation after another. That is how you get this really neat effect of elements sliding in one after another. I was able to do that in about four lines of code.
[09:50] This just illustrates not only the power of AngularJS, but the power of GreenSock in conjunction with AngularJS. This entire application we were able to do in about 50 lines of code, 50 lines of JavaScript, and about another 20 lines of HTML.
[10:10] Thank you for joining me for this GreenCast. Stay tuned for more episodes on this topic. Catch you next time.
to give more insight, I'm doing something like this on an ng-click I have on a button calling a loadData function:
$scope.loadData = function (url) { TweenMax.to($('.pages li'), 1, {opacity: 0}); $timeout(function() { window.location.href = url; }, 1000); }
..and it feels like a hack cause I doing an animation that last 1 second, and also waiting 1 second before doing the location.href. I should be able to use a callback and I was expecting to use the onComplete from Greensock. Thanks!
Community want to learn more about TweenMax, GSAP animation library.
hi I'm using angular with greensock. I want to be able to update a Scope variable or switch to a specific route when onComplete from a TweenMax animation, is this possible? I feel I need to approach my problem in a different way but I'm wondering if I can process angular code inside the onComplete function. I don't necessarily want to use routes, i do want to run animation before doing "something in angular"