Some tips that blew my mind and enhanced my animation code.

Default Ease

I use eases a lot. Expo, Cubic, Linear, Elastic, Back... But except in specific cases, I usually use the same ease on every tween, which become kind of boring to write each time. Here comes defaultEase:

TweenLite.defaultEase = Expo.easeOut;

Enjoy the saved keystrokes! Now each tween will use Expo.easeOut as the default ease. It also easier to maintain!

Handling timers

If you need a more robust (cross-browser), enhanced timer, use the delayedCall feature. It’s basically a null tween with an onComplete callback. But it benefits from all the TweenLite/TweenMax methods:

TweenMax.delayedCall(0.3, someFunction); // Notice the time is seconds-based, not milliseconds-based TweenMax.killTweensOf(someFunction); // Convenient to prevent a function to be called async

Stepped animations

Sometime you need to animate a property between two values but without any ease — just switch it on/off, like a blinking element going straight from visible to hidden. It would be a pain to handle this with delayedCall. Fortunately, there is a special ease for this effect: SteppedEase.

var blinkTween = TweenMax.to($cursor, duration, {ease: new SteppedEase(1), opacity: 0, repeat: -1, yoyo: true});

The $cursor will blink from opacity 1 to 0 in 1 step. This ease is also very convenient for spritesheets.

Notice the repeat & yoyo properties: it means the tween will reverse at the end (yoyo: true) and repeat until manually stopped (repeat: -1).

Jank free animations with TimelineMax

When you design advanced animations, you might end up with something like this:

TweenMax.to($line, 0.4, {scaleX: 1});

TweenMax.to($left, 0.4, {x: -3, delay: 0.3});

TweenMax.to($right, 0.4, {x: 3, delay: 0.45}); … and so on

The problem is, it’s not really maintainable (delays are a pain in the ass to manage), and you might notice jank during the first frames of the transition. This comes from the object allocation: each static TweenMax methods hides a constructor call. That’s where TimelineLite/Max comes in handy:

var tl = new TimelineMax({paused: true}); tl.to($line, 0.4, {scaleX: 1});

tl.to($left, 0.4, {x: -3}, 0.3);

tl.to($right, 0.4, {x: 3}, 0.45); … later on: tl.restart();

Just replace your TweenMax/TweenLite calls with your Timeline instance (TweenMax.to -> tl.to), and voilà! It works with all methods (to, from, fromTo, staggerTo…). Because you created your tweens early on, no jank. You gain more control by putting the delays in variables, and gain some methods such as reverse, addCallback, ... See a more complete example:

var tl = new TimelineMax({paused: true, onComplete: onTlComplete}),

start = 0, // allow to offset the start time

duration = 0.6,

step = 0.08; // for staggered animations/delay between chained tweens tl.to($content, duration, {y: 0, opacity: 0}, start); tl.addCallback(function() {

mediator.emit('header:hide');

}.bind(this), start + duration + step); tl.reverse(); // Play backwards

Note that you can know if a timeline is playing in reverse with reversed() — convenient to add a special tween/callback depending on the timeline direction.

Storing tweens without Timeline

Another way of ensuring jank-free animations would be to store all of your tweens in variables.

var tween = TweenMax.to($node, duration, {ease: Cubic.easeOut, opacity: 0, paused: true});

Although I find it less convenient/maintainable than a timeline, it has one advantage: you can use updateTo to update tween props (which is not allowed within a timeline).

var tween = TweenMax.to($node, duration, {ease: Cubic.easeOut, opacity: 0, paused: true});

tween.updateTo({ease: Expo.easeInOut}); // later on

Use arrays FTW

Arrays are convenients with GSAP. They allow you to tween multiple objects at the same time but also to create advanced animations using stagger.

TweenMax.to([$bar, $foo], duration, {x: 120});

TweenMax.to($bar, duration, {opacity: 1});

Staggering animations (use arrays FTW— part II)

To create badass animations, you need to stagger. Nuf said.

// Nope

for(var i = 0; i < $nodes.length; i++) {

tl.to($nodes[i], duration, {y: 40, opacity: 0}, i * 0.04);

} // Oh yeah

tl.staggerTo($nodes, duration, {y: 40, opacity: 0}, 0.04, 0);

You can also specify onComplete callbacks for each tween, as well a stagger onComplete (i.e. all staggered tweens are complete).

Special trick: if you use a negative stagger value, the array will be looped from the end i.e. last item will be tweened first! Mind blown.

Remove inlined CSS after a tween

GSAP add transform matrices to your nodes, which can sometimes create positioning/styling issues because of the specificity of inlined CSS.

Fortunately, there is a fix: add clearProps in your tween object:

TweenMax.to($node, duration, {opacity: 0, clearProps: ‘all’});

You can use ‘all’ to remove all inline CSS, or pass the specific props you want to remove.

TweenMax.to($node, duration, {x: 0,opacity: 0, clearProps: ‘opacity’}); // will keep the 'x' value, not the 'opacity'

That’s all for now folks!