Animate elements with GreekSock

GreenSock Animation Platform logo

The GreenSock Animation Platform (GSAP) is, as the name suggests, aptly suited to animation on the web. But it can actually do far more than that; GSAP can vary any numeric value over time. Morphing SVGs, animating CSS variables, tweening elements across the screen, changing text and PNG sprite animations are all possible.

Team it up with some form of controller (such as the brilliant ScrollMagic) and you really do have a powerful base from which to create highly interactive and immersive experiences.

In this tutorial, I'll run though the basics of the program, and show you how to get started creating your own timeline-based animations in JavaScript. Then we'll discuss the relative benefits of CSS keyframe animations and GSAP animations.

The basics of GSAP

GSAP comprises two main elements: TweenMax, which enables you to animate the properties of any object (for example the transform of a DOM element); and TimelineMax, which enables you to create sequences of tweens. Both come in Lite varieties, which contain just the bare essentials, and fewer options and plugins than what are bundled with the Max varieties.

To get started we’ll need a copy of TweenMax, but by far the simplest way is to head over to CodePen where you can ‘Quick Add’ TweenMax and start creating right away. TweenMax contains TimelineMax and most of the plugins we’ll need, other than CustomBounce (used in the last step), which is a paid-for plugin.

Before we delve too deep into GSAP, I thought it would be fun for us to get something moving, so we are going to create a simple bouncing-balls animation. We’ll focus on just the JavaScript/GSAP code here, so head over to the tutorial CodePen for the full code.

Get something moving

We have a scene consisting of the sky, the ground and three balls, so let’s get the balls falling to the ground. We achieve this using GSAP’s .to() method, which takes three arguments: the object (our ball DOM selector), the duration (two seconds) and a vars object.

The balls will fall, bounce, squish and raise back up, all in a few lines of code

The vars can be any property we want to alter. In our case, we wish to move each ball by 150px so that they hit the floor. Changing the y property will achieve this for us.

TweenMax.to(‘.ball’, 2, { y: ‘150px’});

Let’s make things a bit more realistic. When a ball hits the ground, it should bounce. TweenMax has a whole host of easing functions built in to it, most of which are customisable. 

We’ll select the conveniently named ‘Bounce’ ease to get the effect we want. This goes in as one of the properties of the vars object.

TweenMax.to(‘.ball’, 2, { y: ‘150px’, ease: Bounce.easeOut });

Now that we’ve got things looking a bit more realistic, we can take advantage of TweenMax’s staggerTo() method. This takes all the same arguments as the .to() method used before, along with an additional stagger value.

This creates the effect of the balls falling one after another. We have also added an infinite repeat (-1) and repeat delay so that we can watch our beautiful creation forever more.

TweenMax.staggerTo(‘.ball’, 2, { y: ‘150px’, ease: Bounce.easeOut, repeat: -1, repeatDelay: 1 }, 0.2);

Our animation is nearly complete, but notice how at the end of each loop the balls return to the start instantly, as if by magic – that’s not what we want. GSAP allows us to add the yoyo:true property, which will make the animation reverse back to the start. 

However, with our bounce ease, this looks unnatural because the balls bounce back up from the ground to the start. Since v1.20.0 we now have access to the yoyoEase property, which tells our animation how it should reverse. This means that we can bounce on the way down, but have a more natural ease on the way up.

TweenMax.staggerTo(‘.ball’, 2, { y: ‘150px’, ease: Bounce.easeOut, yoyoEase: Power3.easeOut, repeat: -1, repeatDelay: 1 }, 0.2);

In this next step, we'll be using a paid plugin (more on those in a second). CustomBounce allows us to define a bounce and squash value, giving the balls a realistic feel. 

First we must create the CustomBounce and specify the strength and squash values. Then we create a TimelineMax and move our repeat and delay parameters to it. We then add two separate staggerTo tweens to this timeline. The first specifies the bounce behaviour. 

The second specifies how it should squash, but we set it to start at the same time as the first by adding 0 (the start) as the final parameter. Using a timeline, we lose access to the handy yoyoEase we used earlier to great effect, so we add this final step of code to our timeline:

CustomBounce.create(‘ballBounce’, {strength:0.75, squash:3});
const tl = new TimelineMax({ repeat: -1, repeatDelay: 1 });
tl.staggerTo(‘.ball’, 2, {y:’150px’, ease:’ballBounce’}, 0.2)
.staggerTo(‘.ball’, 2, {scaleY:0.5, scaleX:1.3, ease:’ballBounce-squash’, transformOrigin:’0 100%’}, 0.2, 0)
.to(‘.ball’, 2, {y: 0, ease:Power3.easeOut});

GSAP plugins

GSAP comes with the Tween and Timeline methods to animate and sequence animations, but there is a raft of other plugins available to extend the functionality. This list is not exhaustive, but covers the most useful (see full list). 

Let's start with those include in the free download:

  • Draggable Make any DOM element draggable and spinnable
  • ScrollTo Smooth scroll to any position on the page
  • attr Animate any attr value on a DOM element
  • CSS Tween any CSS value
  • Bezier Animate any property (including position) along a curved path
  • colorProps Tween any colour property, including hex, rgba and string

Not everything in GSAP is free. Some plugins are reserved for paid members, including the CustomBounce plugin we used in the last stage of our tutorial. These are some of the best paid-for GSAP plugins:

  • SpiltText Split text strings into words or characters – for animated titles
  • ScrambleText Randomise strings of text – for animating between words
  • CustomWriggle Provide ‘wriggles’ to create anticipation and playfulness
  • CustomBounce Create natural-looking bounces – including a ‘squish’ value
  • MorphSVG Tween any SVG object from one shape to another
  • DrawSVG Progressively hide or reveal sections of SVG elements

CSS versus GSAP

You may be thinking you’ve got everything you need with CSS keyframe animations and transitions, so why would you need GSAP? Don’t get me wrong, CSS transitions still have their place, and for anything extremely simple – such as button-hover effects – they are still the option I’d choose. But as soon as you need to do any form of sequencing, CSS quickly starts to struggle.

Being able to offset one part of an animation based on the end of another part of the animation, without having to calculate keyframe percentages, is enough to jump into GSAP alone.

The two compared

You’ll often hear people saying that CSS animations are more performant than JavaScript animations, which is actually a fallacy – this isn’t always the case, and it certainly isn’t when you get to more complex situations. It depends on the browser and machine, and what you’re trying to animate.

One thing that causes confusion here is that when people say ‘JavaScript animations’, they are often referring to their experience with jQuery effects, which more often than not are pretty abysmal.

In this situation GSAP (on the left) greatly outperforms CSS (on the right) transitions 

In fact, if we take a particle-type animation as an example and animate them to create the hyperspace type effect shown above, you would see that with CSS we get a lot of mistimed animations and banding starting to occur. 

With jQuery we’re getting a lot of slow down and banding, and it is clearly not up to the task. But GSAP performs admirably, even on a poorly specced machine.

Sprite animation with GSAP

Create sprite animations like this cheeky monkey one on Inside Asia Tours (click to see) 

One thing that I have often used GSAP for is to create a sprite animation. A sprite animation involves making a series of images appear and hide quickly. 

This is achieved by transforming a sprite image past a ‘whole’ (<div> with overflow:hidden) with a stepped ease, making the image rest, then disappear instantly at the correct frame rate.

This can be done in one line of JavaScript with a few calculations. The effect can also be achieved in CSS, but is far less performant. For a comparison between the two, and the code to do this, head here.

This article originally appeared in issue 299 of net, the magazine for professional web designers and developers – offering the latest new web trends, technologies and techniques. Buy issue 299 here or subscribe to net here.

Read more: