Skip to main content

TimelineLite: Free GreenSock Tutorial

Master Timeline Animation Sequencing with GreenSock

What You'll Master in This Tutorial

Timeline Sequencing

Learn to chain multiple tweens together without manually calculating delays. TimelineLite handles the timing automatically.

Position Parameters

Master precise timing control using absolute and relative positioning to create overlapping and staggered animations.

Labels & Navigation

Implement timeline labels for easy navigation and testing specific animation sequences during development.

Topics Covered in This GreenSock Tutorial:

Master the fundamentals of timeline-based animation with TimelineLite: sequencing tweens for complex animations, fine-tuning timing with the position parameter, organizing animations with labels, customizing easing functions with config(), navigating timelines relative to labels, and building dynamic progress indicators that scale with your content.

Exercise Preview

timelinelite preview

Photo courtesy of istockphoto: Image #11068094

Exercise Overview

TimelineLite revolutionizes how you orchestrate complex animations by eliminating the tedious math of calculating delays and durations. Instead of manually calculating when each tween should start based on previous animations, TimelineLite automatically sequences your tweens in the order you define them. This exercise will teach you to build sophisticated animation sequences with precise timing control—skills that are essential for creating professional web animations that engage users without overwhelming them.

You'll learn to chain multiple tweens together, create overlapping animations for natural motion, and implement visual feedback systems that keep users informed of loading progress. These techniques form the backbone of modern web animation workflows used by leading digital agencies and product teams.

TimelineLite Benefits

No longer do you have to make sure that each tween's delay somehow matches the durations and delays of all previous tweens; TimelineLite does that for you.

Previewing the Finished Animation

Before diving into the code, let's examine the complete animation sequence you'll be building. Understanding the end goal will help you grasp how each piece contributes to the overall user experience.

  1. Launch Google Chrome and open the preview file by pressing Cmd–O (Mac) or Ctrl–O (Windows). Navigate to Desktop > Class Files > yourname-GSAP Class > TimelineLite, then double-click finished.html.

  2. Observe the carefully choreographed sequence that unfolds:

    • The background fades in smoothly, establishing the stage for content

    • The word INTO slides in from the left while THE WIND enters from the right, creating visual balance

    • Main copy rises from below with a subtle upward motion that feels natural and inviting

    • Three red buttons swing into view with staggered timing, using a physics-based easing that mimics real-world motion

    • Throughout this sequence, a white progress bar advances across the top, providing users with visual feedback about the loading process

  3. Reload the page several times to internalize the timing and rhythm. Notice how each element's entrance feels purposeful rather than arbitrary—this is the hallmark of professional web animation.

Animation Sequence Breakdown

0.8s

Background Fade In

Initial background opacity animation

0.5s

INTO Text Slides

Text slides in from the left side

0.5s

THE WIND Text Slides

Text slides in from the right side

0.8s

Main Copy Rises

Body text slides up from bottom

0.7s

Buttons Stagger In

Three red buttons swing in staggered

Examining the DOM Structure & JavaScript Foundation

Understanding the underlying structure is crucial before building complex animations. Let's examine how the HTML and JavaScript work together to create our animation targets.

  1. Open start.html from the TimelineLite folder in your preferred code editor.

  2. Examine the HTML structure on lines 11–18. The DOM is organized logically with semantic elements: two <h2> tags for the headline text, a <p> element for body copy, and a <div> containing the interactive buttons. This clean structure makes it easy to target elements for animation without relying on excessive class names.

  3. Review the JavaScript variables on lines 35–41. These variables create references to DOM elements that we'll animate. Pay special attention to these highlighted techniques:

    var $bg = $("#bg"), 
        $into = $("h2").eq(0), //targets the first h2 element
        $theWind = $("h2").eq(1), //targets the second h2 element
        $mainCopy = $("p"), 
        $buttons = $(".button"), 
        $progress = $(".progress"), 
        tl; //our TimelineLite instance

    The tl variable will hold our TimelineLite instance—the master controller for our entire animation sequence.

    jQuery's .eq() method provides a clean way to target multiple elements of the same type without adding extra classes. The .eq(0) and .eq(1) selectors give us precise control over individual headline elements, demonstrating efficient DOM targeting techniques used in production environments.

jQuery's eq() Method: Precise Element Targeting

The .eq() method selects elements by their position within a matched set, using zero-based indexing. This approach is particularly valuable when working with repeated elements that share the same tag or class but need independent animation control. Unlike CSS nth-child selectors, .eq() refers to the element's position within the jQuery object, not its position in the DOM tree, giving you more predictable targeting behavior.

  • Prepare for 3D animations by adding perspective to all transformed elements. Insert this code after the variable declarations:

    $progress = $(".progress"), 
       tl;
    
    CSSPlugin.defaultTransformPerspective = 800;

    Transform perspective creates the illusion of depth by defining the distance between the viewer and the 3D plane. A value of 800 pixels provides subtle but noticeable depth without creating jarring distortion effects. This setting will apply to all 3D-transformed elements in your animation, ensuring visual consistency across the entire sequence.

  • jQuery Targeting Tip

    The eq() selector uses zero-based indexing and refers to the position within the jQuery object, not the DOM tree. Use eq(0) for first element, eq(1) for second element.

    Sequencing Tweens with TimelineLite

    Now we'll build the animation sequence step by step. TimelineLite's chaining methodology makes complex animations both readable and maintainable—crucial factors when working on team projects or returning to code months later.

    1. Create your TimelineLite instance by adding this code after the perspective setting:

      CSSPlugin.defaultTransformPerspective = 800; 
      
         tl = new TimelineLite();
      
      });
    2. Begin the sequence with the background fade-in. Add this code to create your first tween:

      tl = new TimelineLite();
      
      tl.from($bg, 0.8, {opacity:0})

      Important: Notice there's no semicolon at the end. TimelineLite's power comes from method chaining, and semicolons would break the chain. Save the semicolon for the final tween in your sequence.

    3. Save and preview in your browser. The 0.8-second background fade establishes a gentle, welcoming entry point for users. This duration feels natural—fast enough to avoid delays, slow enough to feel intentional rather than jarring.

    4. Chain the headline animation by adding the INTO text tween:

      tl = new TimelineLite();
      
      tl.from($bg, 0.8, {opacity:0}).from($into, 0.5, {opacity:0, x:-200})

      This tween moves the text from 200 pixels left of its final position while simultaneously fading in from transparency. The shorter 0.5-second duration creates snappy, energetic motion that contrasts nicely with the more measured background fade.

    5. Save and preview. Notice how the INTO text automatically begins when the background completes its fade—no manual delay calculations required. This is TimelineLite's core advantage: automatic sequencing that adapts as you modify individual tween durations.

    6. Format your code for readability by placing each chained tween on its own line. This practice becomes essential as animations grow in complexity:

      tl.from($bg, 0.8, {opacity:0})
        .from($into, 0.5, {opacity:0, x:-200})
    7. Add the complementary THE WIND animation to create visual balance:

      tl = new TimelineLite();
      
      tl.from($bg, 0.8, {opacity:0})
        .from($into, 0.5, {opacity:0, x:-200})
        .from($theWind, 0.5, {opacity:0, x:200})
    8. Save and preview. The opposing motion directions (left vs. right) create visual interest while maintaining symmetry. This technique is commonly used in hero sections and landing pages to create dynamic yet balanced presentations.

    9. Continue building the sequence with the main copy animation:

      tl.from($bg, 0.8, {opacity:0})
        .from($into, 0.5, {opacity:0, x:-200})
        .from($theWind, 0.5, {opacity:0, x:200})
        .from($mainCopy, 0.8, {opacity:0, y:50})
    10. Save and preview. The upward motion from 50 pixels below creates the impression of content "rising" into view—a subtle but effective way to guide the user's eye through the content hierarchy.

    11. Complete the content animation with staggered button entrances. Add this final content tween:

      tl.from($bg, 0.8, {opacity:0})
        .from($into, 0.5, {opacity:0, x:-200})
        .from($theWind, 0.5, {opacity:0, x:200})
        .from($mainCopy, 0.8, {opacity:0, y:50})
        .staggerFrom($buttons, 0.7, {rotationX:-90, opacity:0, transformOrigin:"center top", ease:Back.easeOut}, 0.2)

      The staggerFrom() method animates multiple elements with identical properties but offset timing. The 0.2-second stagger creates a cascading effect that feels organic. The rotationX:-90 and transformOrigin:"center top" combination creates a "flip down" motion that mimics physical objects falling into place.

    12. Save and preview the complete sequence. You now have a sophisticated, automatically-timed animation that would require complex delay calculations with traditional animation approaches.

    TimelineLite vs Manual Delays

    Pros
    Automatic sequencing without calculating delays
    Easy method chaining with periods
    Animations display in code order
    Clean, readable syntax structure
    Cons
    Requires learning TimelineLite API
    Additional library dependency

    Adjusting the Sequence's Timing with the Position Parameter

    While sequential animation works well, real-world projects often require more nuanced timing. The position parameter gives you surgical precision over when each tween begins, allowing for overlapping animations that create more natural, fluid motion.

    TimelineLite's position parameter system supports both absolute and relative timing. The syntax follows this pattern:

    tl.from(target, duration, {properties}, position)

    Let's enhance our animation by creating overlapping motion between the headline elements.

    1. Modify the THE WIND tween to begin before INTO completes its animation:

      .from($theWind, 0.5, {opacity:0, x:200}, "-=0.25")

      The string value "-=0.25" means "start this tween 0.25 seconds before the current timeline end." This creates a 0.25-second overlap where both headline elements animate simultaneously, producing more dynamic motion.

    Position Parameter Syntax Guide

    Master these position parameter formats for precise animation control:

    Absolute timing: Use numbers like 2 to place tweens at specific timeline positions.

    Relative to timeline end: Use "+=2" for gaps or "-=2" for overlaps relative to the current timeline end.

    Label-based positioning: Use "myLabel" to align with labels, or "myLabel+=2" and "myLabel-=3" for label-relative positioning.

  • Save and preview. The overlapping motion creates more sophisticated pacing that feels less mechanical than strict sequential timing.

  • Add a strategic pause before the main copy appears to create better rhythm:

    .from($mainCopy, 0.8, {opacity:0, y:50}, "+=0.5")

    The "+=0.5" value creates a half-second pause after the headline animations complete, giving users time to process the headline before introducing body content. This pause improves information hierarchy and reduces cognitive load.

  • Save and preview. Notice how the strategic pause makes the overall animation feel more thoughtful and user-friendly, rather than rushing through content presentation.

  • Using Labels in a TimelineLite

    Labels transform how you navigate and organize complex animations. Instead of calculating absolute times or guessing at relative positions, labels provide semantic anchors that make your animations more maintainable and easier to debug.

    Think of labels as bookmarks in your timeline—they mark important moments that you can reference by name rather than by time values that might change as you adjust animation durations.

    1. Add a label to mark the beginning of the button animation sequence:

      .staggerFrom($buttons, 0.7, {rotationX:-90, opacity:0, transformOrigin:"center top", ease:Back.easeOut}, 0.2, "buttons")

      The "buttons" label now marks the exact moment when the first button begins its entrance animation. This label remains accurate even if you modify earlier tweens in the sequence.

    2. Add a seek command to jump directly to the button animation for faster testing:

      .staggerFrom($buttons, 0.7, {rotationX:-90, opacity:0, transformOrigin:"center top", ease:Back.easeOut}, 0.2, "buttons")
      
      tl.seek("buttons");

      The seek() method instantly jumps the timeline to the specified label. This is invaluable during development when you're fine-tuning specific parts of long animation sequences—no more waiting through 10 seconds of animation to test a 1-second tweak.

    3. Save and preview. You'll now see only the button animation sequence, making it easier to focus on refining this specific part of the overall animation.

    Development Efficiency

    Labels allow you to jump to specific points in your timeline during development, bypassing the tedium of watching the whole animation when testing specific sequences.

    Using Config() to Modify the Back Ease

    Easing functions define the character of your animations, but many developers don't realize that GreenSock's easing functions are highly customizable. The config() method lets you fine-tune easing behaviors to match your design intent perfectly.

    1. Amplify the button swing animation by configuring the Back ease:

      .staggerFrom($buttons, 0.7, {rotationX:-90, opacity:0, transformOrigin:"center top", ease:Back.easeOut.config(12)}, 0.2, "buttons")

      The config(12) method dramatically increases the overshoot amount in the Back ease. Higher values create more pronounced "bounce-back" effects, while lower values produce subtler motion.

    2. Save and preview. The exaggerated overshoot creates a playful, attention-grabbing effect that might work well for gaming sites or creative portfolios.

    3. Dial back the effect to something more appropriate for professional contexts:

      .staggerFrom($buttons, 0.7, {rotationX:-90, opacity:0, transformOrigin:"center top", ease:Back.easeOut.config(3)}, 0.2, "buttons")
    4. Save and preview. This moderate overshoot adds personality without overwhelming the content—a good balance for most business applications.

    Back Ease Configuration Values

    Subtle (config 3)
    3
    Default
    7
    Dramatic (config 12)
    12

    Seeking a Position Relative to a Label

    Sometimes you need to see the context around a specific animation moment, not just the moment itself. Label-relative seeking gives you this flexibility while maintaining the organizational benefits of labels.

    1. Modify the seek command to show the animation leading up to the button sequence:

      tl.seek("buttons-=1");

      This positions the timeline 1 second before the buttons label, letting you see how the main copy animation flows into the button sequence.

    2. Save and preview. You can now evaluate the transition between animation sections, which is crucial for maintaining smooth, professional motion throughout the entire sequence.

    3. Remove the seek command entirely since the button animation is now refined:

      tl.seek("buttons-=1");

      With the animation polished, you no longer need the development aid of jumping to specific positions.

    Creating an Animated Progress Bar

    Progress indicators are essential UX elements that keep users informed during loading processes. A well-designed progress bar provides visual feedback, reduces perceived wait time, and creates professional polish that users associate with quality applications.

    1. Locate the progress bar element in the HTML around line 9:

      <div class="progress"></div>

      This div spans the full browser width and serves as our progress indicator. We'll animate its horizontal scale to create the progress effect.

    2. Add the progress bar animation to your timeline:

      .staggerFrom($buttons, 0.7, {rotationX:-90, opacity:0, transformOrigin:"center top", ease:Back.easeOut.config(3)}, 0.2, "buttons")
      .from($progress, 1, {scaleX:0, transformOrigin:"left", ease:Linear.easeNone})

      The scaleX:0 starts the bar with zero width, while transformOrigin:"left" ensures it grows from left to right. Linear.easeNone provides steady, consistent progress indication.

    3. Save and preview. The progress bar currently runs after all other animations complete, which defeats its purpose as a loading indicator.

    4. Fix the timing by starting the progress bar at the timeline's beginning:

      .from($progress, 1, {scaleX:0, transformOrigin:"left", ease:Linear.easeNone}, 0)

      The position parameter 0 (a number, not a string) specifies absolute time zero—the very start of the timeline.

    5. Save and preview. The progress bar now runs concurrently with the content animation, but its 1-second duration doesn't match the timeline length.

    6. Make the progress bar duration dynamic to automatically match the timeline length:

      .from($progress, tl.duration(), {scaleX:0, transformOrigin:"left", ease:Linear.easeNone}, 0)

      The tl.duration() method returns the timeline's total duration. This creates a self-maintaining progress bar that automatically adjusts if you modify the animation sequence.

    7. Save and preview. The progress bar now perfectly tracks the animation progress, providing accurate visual feedback throughout the entire sequence.

    8. Complete the progress bar experience by fading it out when the animation finishes:

      .from($progress, tl.duration(), {scaleX:0, transformOrigin:"left", ease:Linear.easeNone}, 0)
      .to($progress, 0.4, {opacity:0, y:-8});

      Remember: This is your final chained tween, so end with a semicolon. The slight upward motion (y:-8) combined with the fade creates a subtle "disappearing" effect that feels polished and intentional.

    9. Save and preview your completed animation. You now have a sophisticated, timeline-controlled animation with professional progress indication—a technique you'll use in loading screens, onboarding sequences, and interactive presentations.

    This exercise demonstrates the power of TimelineLite for creating complex, maintainable animations with precise timing control. The techniques you've learned—chaining, positioning, labeling, and progress tracking—form the foundation for professional web animation workflows used in modern digital experiences.

    Progress Bar Implementation Steps

    1

    Scale Animation

    Create tween to change scaleX from 0 to 1 with left transform origin

    2

    Timeline Start Position

    Set position parameter to 0 to start at timeline beginning

    3

    Dynamic Duration

    Use tl.duration() method for automatic duration matching

    4

    Fade Out Effect

    Add final tween to fade out progress bar when complete

    Key Takeaways

    1TimelineLite eliminates manual delay calculations by automatically sequencing chained tweens in the order they appear in code
    2Position parameters provide precise timing control using absolute times, relative offsets, and label-based positioning
    3jQuery's eq() method enables specific targeting of multiple similar elements without additional CSS classes
    4Labels mark specific timeline points for easy navigation during development and testing of complex animations
    5The Back ease's config() method allows customization of overshoot intensity for more dramatic or subtle effects
    6Dynamic duration values using tl.duration() create responsive progress bars that automatically adjust to timeline length
    7Method chaining with periods creates readable animation sequences while maintaining proper execution order
    8Transform perspective settings ensure consistent 3D animation rendering across all animated elements

    RELATED ARTICLES