Jump to content
GreenSock

MarcoBarbosa

How to position tweens in random start order in a timeline?

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

If you get this example:

 

See the Pen ywJFi by GreenSock (@GreenSock) on CodePen

 

I'd like to see the letters animating in a random order.

 

For example: the second letter appears 0.2s before the first one, the third one 0.3s and so on.

 

I guess I could use delay but I'd like to learn the "proper" way with Greensock.

Would that be the stagger function? or use .add() with random positions?

 

Here's an example of what I want to achieve exactly (slight NSFW): 

http://www.shockblast.net/

 

 

Link to comment
Share on other sites

Hi and welcome to the forums.

 

Lately I've been working in populating timelines randomly with DOM elements arrays, and is quite simple.

First create the array, for that you can use a simple JQuery selector or any other tool or library of your choice, then you create an empty array and a function to generate a random number to select from the elements array; at the same time you add that number to the empty array (so you don't select the same element more than once) and finally add the particular tween instance to the main timeline. Something like this:

var elements = $(".elementClass"),//create an JQuery object with all the DOM elements
    elementsAmount = elements.length,//amount of elements in the array
    selected = [],//empty array
    count = 0,//how many elements are selected
    num,
    tl = new TimelineMax();//your master timeline

function populateTimeline()//function to add the tweens in the timeline
{
    if(count < elementsAmount)//are all elements selected?
    {
        var getNum = getNumber(elementsAmount)//get a random number
        
        if($.inArray(getNum, selected) < 0)//check if the number has been selected already
        {
            selected.push(getNum);
            tl.to(elements[getNum], time, {/*tween vars*/});
            count++;//one more element has been selected
            populateTimeline();//execute the function again
        }
        else//the number has been selected
        {
            populateTimeline();//execute the function again
        }
    }
}

populateTimeline();

function getNumber(number)//function to get the random number
{
	num = Math.round(Math.random() * (number-1));
	return num;
}

And that should do it, give it a try and let us know how it went.

 

Hope this helps,

Cheers,

Rodrigo.

Link to comment
Share on other sites

Yeah, when I create something randomized like that, I usually do a simple loop like this:

var tl = new TimelineLite(),
    elements = $(".myClass"),
    randomGap = 1, //use whatever you want here to space things out more/less
    i;
for (i = 0; i < elements.length; i++) {
    tl.from(elements[i], 1, {rotation:180, autoAlpha:0}, Math.random() * randomGap);
}

Notice that last part of the from() tween - that's the absolute time I'm inserting it into the timeline. It's randomized in this case so that everything will start tweening sometime between 0 and 1 seconds. 

 

Is that what you were looking for? 

Link to comment
Share on other sites

Thanks for the replies guys!

 

The random gap trick is neat!

 

I was trying shuffling the array first, then a for loop like yours and then "tl.add()" each item instead of from().

 

The add calls a function that returns a TweenLite:

var tl = new TimelineLite(),
    letters = $("#boxWrapper div"),
    randomGap = 0.5, 
    i;

// Shuffle here before the loop
for (i = 0; i < letters.length; i++) {
    // ??? 
    //tl.add( tween(letters[i]), "-=0.7", "start");

    //     
    tl.add( tween(letters[i]), Math.random() * randomGap);
              
    // This is awesome:
    //tl.from(letters[i], 1, {rotation:180, autoAlpha:0}, Math.random() * randomGap);
}


function tween($el) {
  return TweenLite.from($el, 1, {
    rotation: 180,
    autoAlpha: 0
  })
}

 

Then I was trying to get my around around position vs stagger. I don't seem to grasp the "stagger" concept (I'm not from a flash background).

 

From my understanding if the duration is 1 second and I want the next ones to overlap, I'd stagger them with "-=0.5" so they'd start half way through the previous one?

 

But "position" seems to be exactly what I'm looking for:

See the Pen JbxHi by marcobarbosa (@marcobarbosa) on CodePen

 

This "random gap" is a more neat, less code and probably more performant way than shuffling arrays. I'm happy :)

Link to comment
Share on other sites

The stagger methods are just a convenient way to apply the same animation to multiple elements with a consistent offset in start times. You can configure stagger tweens to 

 

  • overlap (stagger value less than duration)
  • play in direct sequence (stagger value equal to duration)
  • play with timing gaps between the end of one tween and start of next (stagger value greater than duration)

When using the timeline stagger methods you also have a position parameter that dictates where the group of tweens is placed in the timeline

 

timeline.staggerTo(objectsArray, duration, {vars}, stagger, position);

 

Glad you found a suitable solution. Hopefully this extra info helps clear things up.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×