Search code examples
javascriptanimationgsap

How to add dynamic number of animations, then run all in parallel Greensock


I'm trying to find a way to add an arbitrary number of elements to a Timeline and then after adding them, run them all starting at the same time. I have tried to call .pause() before I add to the timeline and play afterwards but it always starts before I call play.

What I'm running currently is below. I have 2 console logs to print out the time which may indicate that the code is actually doing what I want since the first console.log always prints 0. The second always prints 20. I'm not sure why we are at 0 on the first print because if the .pause() isn't working why doesn't it start as soon as I add a .to in the .each loop?

expand: function(elems) {
    var tl = new TimelineLite();
    tl.pause();
    elems.each(function() {
        this.style.height = 'auto';
        var Height = getComputedStyle(this).height;
        this.style.height = 0;
        tl.to(this, .1, {height:fullHeight}, 0);
        tl.to(this, .5, {opacity:1}, .2);
    });
    var currentTime = tl.time();
    console.log('the current tl time ' + currentTime);
    currentTime = tl.time();
    console.log('the current tl time 2' + currentTime);
    tl.play();

Solution

  • It's absolutely fine to use a TimelineLite/Max for a bunch of tweens that run concurrently - that gives you total control over all of those animations with one object. No problem at all.

    Also, there's no need to pause() and then play() on the same tick. GSAP is totally synchronized. It doesn't matter if a block of code takes a while to execute - GSAP maps times by its internal ticker.

    I'm confused by a few things in your code and question:

    1. Your second console.log() has a "2" hard-coded before the currentTime, thus you're getting expected results. In other words, currentTime was 0 on BOTH console.log() calls. Right?
    2. It looks like you're having the height animate from 0 to full height in 0.1 seconds, and waiting to animate the opacity until 0.2 seconds (so 0.1 seconds AFTER the full height has been reached). Was that intentional? I'm not sure if you've got opacity set to 0 somewhere, but if so, you may never see the height animate. Perhaps that's your plan, but I figured I'd ask.

    You could simplify things a bit by using a function-based value for the height tween like this:

    var tl = new TimelineLite();
    tl.fromTo(elems, 1, 
      {height:0}, 
      {height:function(i, e) {
          e.style.height = "auto";
          var fullHeight = window.getComputedStyle(e).height;
          e.style.height = "0px";
          return fullHeight;
        }
      });
    //we'll start the opacity tweens 0.2 seconds later.
    tl.to(elems, 1, {opacity:1}, 0.2);
    

    Here's a demo: https://codepen.io/GreenSock/pen/6e2cadb2764f2417366e7b87567d6002?editors=0010

    If you need any other help, feel free to swing by the forums at https://greensock.com/forums/

    Happy tweening!