GreenSock: Animating an HTML5 Ad (Google Banner Ads)

Free JavaScript Tutorial

Delve into the depths of JavaScript with our detailed tutorial that covers topics like linking to the Google Hosted Version of GreenSock, creating timelines, animating multiple scenes, and more, with exercises for creating an animated HTML5 banner ad for Google Ads.

This exercise is excerpted from Noble Desktop’s JavaScript for Front-End training materials and is compatible with JavaScript updates through 2023. To learn current skills in JavaScript with hands-on training, check out our Front-End Web Development Certificate, Full-Stack Web Development Certificate, and coding classes in-person and live online.

Topics covered in this JavaScript tutorial:

Linking to the Google Hosted Version of GreenSock, Creating a Timeline & Animating Multiple Scenes, X & Y versus xPercent & yPercent, Timeline Labels & Using Seeking to Jump to a Specific Part of a Timeline

Exercise Preview

preview banner ad

Exercise Overview

In this exercise, you’ll create an animated HTML5 banner ad for Google Ads. You’ll be doing a fair bit of coding in this exercise, so we’ll emphasize best practices and a proper workflow to make the process as easy as possible.

JavaScript Development Certificate: Live & Hands-on, In NYC or Online, 0% Financing, 1-on-1 Mentoring, Free Retake, Job Prep. Named a Top Bootcamp by Forbes, Fortune, & Time Out. Noble Desktop. Learn More.

Previewing the Finished Animation

  1. On your Desktop (the Finder on Mac or Windows Explorer on Windows), go into the Class Files folder, then JavaScript Class.
  2. Go into the Done folder, then into GSAP-Ad-Banner.
  3. Ctrl–click (Mac) or Right–click (Windows) on index.html, go to Open with and select your favorite browser.

    Watch the animation a few times to get a sense of the pacing and the interaction of the various elements. The animation essentially consists of these 3 main scenes, which we’ll call panels:

    preview banner ad

    Static designers who give you a design to animate will often design these types of static screens (scenes, panels, whatever you want to call them).

Linking to the Google Hosted Version of GreenSock

  1. Switch to your code editor.
  2. For this exercise we’ll be working with the GSAP-Ad-Banner folder located in Desktop > Class Files > JavaScript Class. Open that folder in your code editor if it allows you to (like Visual Studio Code does).
  3. In your code editor, open index.html from the GSAP-Ad-Banner folder.
  4. Before we look at the page, let’s discuss linking to the GSAP library.

    Google Ads limit the total file size of all assets in your ad (150k at the time of this writing). That includes HTML, CSS, images, and custom JS. If you included your own copy of GSAP, it would count again that file size but luckily Google hosts their own copy of GSAP which does not count again the file size!

  5. Scroll to the bottom and notice we’ve already included a script tag linked to the Google hosted version of GSAP.

    We got that link on Google’s website here: tinyurl.com/gads-gs

Examining the DOM Structure

  1. Preview index.html in a browser.

    We’ve laid out all 3 panels in a vertical stack, like a storyboard. When creating a longer, more complex animation, it’s a good idea to section out the key moments in the sequence and code the HTML/CSS for these moments first—even before you create a single tween. This let’s you work on one panel at a time.

  2. Let’s look at the HTML. Switch to your code editor and scan over the content, paying attention to the IDs and classes of things (particularly the main sections, which we call a panel):

    <div id="panel1" class="panel">
       <h1 id="panel1-text">hungry?</h1>
    </div>
    <div id="panel2" class="panel">
       <h2 id="panel2-text">How about now?</h2>
    </div>
    <div id="panel3" class="panel">
       <div id="info">
    

    There are 3 panel divs, each with a unique ID that indicates their order of appearance in the sequence we’ll create. Each panels is an identically-sized (300px by 250px) div that shares the class of panel.

  3. Now that we know what’s going on with the HTML, we should formulate a plan of action. The easiest way to create this animation will be to reposition #panel2 and #panel3 so they sit directly atop #panel1.

    We’ll use a timeline to tell #panel2 and #panel3 to appear at the appropriate times. Because each panel is the same size, the animation will look seamless.

Creating the Timeline & Animating the First Panel

  1. In the script tag at the bottom of the file, add the following bold code to instantiate a new timeline:

    <script>
       let tl = gsap.timeline();
    </script>
    
  2. Now we can add tweens to the timeline. Let’s start working on the first panel by adding the following code:

    <script>
       let tl = gsap.timeline();
       tl
       .from('#panel1-text', {duration:0.5, scale:0.5, opacity:0, ease:'back.out'})
    </script>
    
  3. Save and reload the page in the browser.

    • The word hungry? should scale up.

      If the animation does not work and your code is correct, disable any ad blockers in your browser. They can block the GSAP library from Google!

    • Looks excellent, the first panel is done. Let’s move on to the second panel.

Animating the Second Panel

Looking at the second panel down on the page, it has two elements: the burger picture (which is the panel’s background image) and the How about now? text which has a red background (and an id of panel2-text).

  1. First, let’s position #panel2 so it sits directly on top of #panel1 by setting its top position to 0 (we’ve used absolute positioning to position them within the page). Add the following bold code:

    .from('#panel1-text', {duration:0.5, scale:0.5, opacity:0, ease:'back.out'})
    .set('#panel2', {top:0})
    
  2. Save and reload the page in the browser.

    As soon as the hungry? text fades in, #panel2 jumps into position to cover it. It’s a little abrupt, but we’re on the right track. Let’s give people a little time to read the first panel.

  3. Add the following bold code to the set() tween you just added:

    .set('#panel2', {top:0}, '+=2')
    

    By adding this position parameter, we ensure viewers will have 2 seconds to read the hungry? text before #panel2 appears.

  4. Save and reload the page in the browser.

    That’s much better, but #panel2 ought to appear with some sort of transition.

  5. At the bottom of the timeline, add the following bold code to scale down #panel2 as it fades in:

    .set('#panel2', {top:0}, '+=2')
    .from('#panel2', {duration:0.2, opacity:0, scale:1.5})
    
  6. Save and reload the page in the browser.

    The quick scaling transition is really dynamic—perfect for an eye-catching banner ad.

  7. Add the following bold code to make the How about now? heading slide in from below the panel after viewers have a moment to savor the burger picture:

    .from('#panel2', {duration:0.2, opacity:0, scale:1.5})
    .from('#panel2-text', {duration:0.2, yPercent:100}, '+=0.5')
    

    X & Y versus xPercent & yPercent

    Previously we used x and y for moving a fixed pixel amount. xPercent and yPercent are GSAP properties for doing percentage-based translations.

    We want the #panel2-text to animate up from a position where its top edge is aligned with the bottom of the banner. We could try to determine the height of the element and then offset its y position by that amount, but yPercent does this for us. It uses a percentage of the element’s height to change its position (in this case 100 percent of its height).

    Learn more at greensock.com/mistakes#percents

  8. Save and reload the page in the browser.

    Looking good. You’ll see that #panel2-text nicely slides in from the bottom. We want the #panel2-text to disappear again after 2 seconds, so let’s add that next.

  9. Add the following bold code:

    .from('#panel2-text', {duration:0.2, yPercent:100}, '+=0.5')
    .to('#panel2-text', {duration:0.2, yPercent:100}, '+=2')
    

    This code means that, after 2 seconds, the #panel2-text will tween back to sitting perfectly below the panel.

  10. Save and reload the page in the browser. Cool.

    The second panel is done. (Don’t worry if you notice the image scaling in spills outside the panel, we’ll hide that later.)

Animating the Third Panel

Looking at the third panel down on the page, it’s a red #info panel which contains list items (2 lines of text) and an #order-now button.

We want the red #info panel to slide up, then the list items (2 lines of text) to stagger in. Finally, the #order-now button should appear.

  1. Move #panel3 over the other 2 panels by adding the following:

    .to('#panel2-text', {duration:0.2, yPercent:100}, '+=2')
    .set('#panel3', {top:0})
    
  2. Save and reload the page in the browser.

    Good, #panel3 jumps into place at the appropriate time, albeit abruptly.

    By now you’re probably sick of seeing the first 2 panels animate. Let’s use a label to skip straight to the set() for #panel3 while we are developing and testing the rest of the animation.

  3. Add the following bold code to the line you just wrote:

    .set('#panel3', {top:0}, 'final')
    
  4. Create a couple lines of space after that line (so the seek() method that jumps to the label doesn’t get confused with the timeline’s chained tweens) and add:

       .set('#panel3', {top:0}, 'final')
    
       tl.seek('final');
    </script>
    
  5. Save and reload the page in the browser.

    Good, nothing will animate because we skipped ahead to the last position on the timeline.

  6. Add the following code above the seek() method to slide up the #info panel from the bottom:

    .set('#panel3', {top:0}, 'final')
    .from('#info', {duration:0.5, yPercent:100})
    
    tl.seek('final');
    
  7. Save and reload the page in the browser.

    • The panel should slide up from the bottom.
    • The #info panel now covers up the meatiest part of the burger, so let’s fix that.

    Creating Labels

    When you provide a label as the position parameter, GSAP will search to see if that label already exists.

    If the label DOES NOT exist, GSAP will create the label at the current end of the timeline (that is, the beginning of the tween).

    If the label DOES already exist, then the tween will be added at that position.

  8. Add the following bold code to move the burger up a bit:

    .from('#info', {duration:0.5, yPercent:100})
    .to('#panel2', {duration:0.5, y:-65})
    
    tl.seek('final');
    
  9. Save and reload the page in the browser.

    Better, but it would be nice to have the burger move simultaneously with the #info panel. To do so, let’s use the '<' position parameter as we learned previously.

  10. Edit the to() method for #panel2 by adding the following bold code:

    .to('#panel2', {duration:0.5, y:-65}, '<')
    
  11. Save and reload the page in the browser.

    Excellent!

  12. Let’s work on staggering the list items. Add the following bold code:

    .to('#panel2', {duration:0.5, y:-65}, '<')
    .from('#info li', {duration:0.3, opacity:0, x:50, stagger:0.1}, '+=0.2')
    
    tl.seek('final');
    
  13. Let’s review the parameters for this stagger tween.

    • The from() tween will take a duration of 0.3 seconds.
    • The #info li items will fade in from an opacity of 0 and move in from an initial position of x:50 (thus appearing to move in from the right).
    • The #info li items will stagger in 0.1 second intervals (the second li will start animating 0.1 second after the first).
    • All of this will occur 0.2 seconds after the previous tween has ended, as indicated in the position parameter.
  14. Save and reload the page in the browser. Looking cool!

  15. Add a tween for the #order-now button:

    .from('#info li', {duration:0.3, opacity:0, x:50, stagger:0.1}, '+=0.2')
    .from('#order-now', {duration:0.5, scale:0, opacity:0, ease:'back.out'})
    
  16. Save and reload the page in the browser. Fantastic!

  17. Let’s see the animation all the way from the beginning again. Delete this line:

    tl.seek('final');
    
  18. Save and reload the page in the browser.

    Watch it from the beginning. The banner animation is complete!

Hiding Overflow

In the second panel, the burger image scales in a larger size, so it extends (or “bleeds”) beyond the edges of the panel. Let’s clean it up.

  1. In your code editor, from the css folder open main.css.

  2. Find the #banner rule and change overflow to hidden as shown below in bold:

    #banner {
       overflow: hidden;
    

    Code Omitted To Save Space

    }
    
  3. Save and reload the page in the browser.

    Good, now the “bleed” is invisible.

Optional Bonus: Repeating the Animation

Let’s make the banner ad repeat, but we want to pause on the last screen for a little while before repeating.

  1. In index.html, add the following bold code:

    let tl = gsap.timeline( {repeat:3, repeatDelay:2} );
    
  2. Save the file and preview in the browser.

    2 seconds after the animation ends and should repeat automatically. Good stuff.

photo of Dan Rodney

Dan Rodney

Dan Rodney has been a designer and web developer for over 20 years. He creates coursework for Noble Desktop and teaches classes. In his spare time Dan also writes scripts for InDesign (Make Book JacketProper Fraction Pro, and more). Dan teaches just about anything web, video, or print related: HTML, CSS, JavaScript, Figma, Adobe XD, After Effects, Premiere Pro, Photoshop, Illustrator, InDesign, and more.

More articles by Dan Rodney

How to Learn JavaScript

Master JavaScript with hands-on training. JavaScript is one of the world's most widely-used coding languages. Learn JavaScript and its libraries to start creating interactive websites and mobile apps.

Yelp Facebook LinkedIn YouTube Twitter Instagram