Jump to content
Search Community

staggering

iconofsyn test
Moderator Tag

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

Use of the stagger timeline functions can be compared to a straight line on a graph because the amount of time between each stagger is always the same.
 

Is it possible so have a stagger which if represented on a graph would be a curve, and is automatically calculated based on some control point values similar to how bezier works?

if not
is it possible to put a lot of objects on a timeline and automatically calculate their start time based on some control point values similar to how bezier works?

if not
is there any way to automatically define start times for a list of animated objects in any way other than writing my own function (or using a bezier calculator) to calculate the list start times and passing these values into the line line objects start property (say by using a loop)

Link to comment
Share on other sites

The short answer is, yes!

 

This isn't necessarily a single feature, but a combination of tricks that will get you what you need (i think).

My solution hinges on CustomEase which allows you to use any SVG <path> as an ease curve. Read the CustomEase page for all you need to know about easing and CustomEase. The reasons I am tapping into CustomEase are 2-fold.

 

  1. CustomEase allows you to draw any curve you want (assuming it doesn't cross over itself)
  2. All eases have a getRatio() method which gives you a value based on progress

For my example I created a custom ease that looks like this:

 

Screen Shot 2017-06-21 at 9.29.12 PM.png

 

EDIT curve here: https://greensock.com/ease-visualizer?CustomEase="M0,0 C0.083,0.294 0.214,0.596 0.468,0.82 0.588,0.926 0.752,1 1,1"

 

 

I wrote some code that uses that ease curve to plot the x coordinate of 50 boxes that are stacked vertically

I basically loop through each ".box" and use getRatio(index/numBoxes) to get a value between 0 and 1. 

I multiply that value by 250px so that the boxes actually move more than 1 pixel :)

 

var curve = CustomEase.create("curve", "M0,0,C0.083,0.294,0.214,0.596,0.468,0.82,0.588,0.926,0.752,1,1,1");
var numBoxes = $(".box").length;
$(".box").each(function(index, element){
    TweenLite.set(element, {x:curve.getRatio(index/numBoxes) * 250})
  }
)

 

Since I'm modifying the x (horizontal) of the boxes you will have to tilt your head 90 degrees to the right to see how the curve matches the ease curve

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

 

Now that I know that I can get a value along a path, I'm going to use the same technique to use that value for the absolute position (start time) of tweens in a timeline:

 

$(".box").each(function(index, element){
   tl.to(element, 1, {x:500, ease:Linear.easeNone}, curve.getRatio(index/numBoxes) * 4);
  }
)

 

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

 

You should be able to see that the startTimes of the boxes towards the bottom (end of animation) are much closer together just as the ease curve flattens out at the end.

 

That pen has a block of code commented out showing that you could cycle the delay property of tweens in a staggerTo() but I find the loop easier to digest in this case

 

tl.staggerTo(".box", 1, {x:500, ease:Linear.easeNone, cycle:{
  delay:function(index){
    return curve.getRatio(index/numBoxes) * 4
  }
}}, 0)

 

Hopefully this gets you on the right path.

  • Like 4
Link to comment
Share on other sites

On 6/22/2017 at 2:36 AM, Carl said:

var curve = CustomEase.create("curve", "M0,0,C0.083,0.294,0.214,0.596,0.468,0.82,0.588,0.926,0.752,1,1,1"); var numBoxes = $(".box").length; $(".box").each(function(index, element){     TweenLite.set(element, {x:curve.getRatio(index/numBoxes) * 250})   } )


would i be correct to believe that

 

1) you are creating a custom ease object.

2) you are using this in place of the "value" field in X:value
3) I could do the same in my staggerTo by placing the ease object in place of the stagger time 

Link to comment
Share on other sites

1) Yes, I'm creating a CustomEase

2) I am using the getRatio() function to figure out the x value based on the current index / numBoxes. This code is in a loop so index gets incremented on each iteration.

3) I provided code above in the demo showing how to use this value as the delay for each tween in a staggerTo(). The stagger amount is a fixed value that gets applied equally for each tween generated by the staggerTo(). By using it as the delay I can use the cycle property to update the delay for each tween individually. Here is a fork that shows it working:

 

See the Pen BZwomW?editors=0010 by anon (@anon) on CodePen

 

Link to comment
Share on other sites

I have been studying your demo, comparing it with the greensock documentation and attempting to understand it

 

the line
delay:function(index)

is confusing, the index variable does not get mentioned before this
so where does it come from? is it automatically available because it is inside a tween?
and is it the index of the current object being animated?

Link to comment
Share on other sites

I have implemented your sameple custom.ease code 

before my code was
 

for(;i>=0; i--){
	tweenStartTime = tweenStartTime + 0.002;
	squezeTimeLine.add( TweenLite.to(b[i], this.settings.firstStageSpeed, {scaleX:0.05, transformOrigin:"50 50"}),tweenStartTime);
}

 

now my code is
 

for(;i>=0; i--){
	squezeTimeLine.add( TweenLite.to(b[i], this.settings.firstStageSpeed, {scaleX:0.05, transformOrigin:"50 50"}),
	this.curve.getRatio(i/b.length) * 0.4);
}


This gives an effect similat to what i want
BUT
The objects now appear to get animated in the wrong order, im guessing this is down to the start-delay increasing as you go up the list of objects.
How can I "invert" it back so that things animate in the right order which still keeping the easing effect

I apologize that my maths is not very good

Link to comment
Share on other sites

11 hours ago, Carl said:

i suspect if you iterated through the objects in b in a positive manner by incrementing i in your loop (i++) instead of (i--) you would have things animate in the right order.

Very tough to say though by just seeing the code you supplied. CodePens or other demos in a live and editable environment are much better for us to work with.


It was difficult because the items needed to be animated in one order
but the bezzier supplied needed to go through them in the opposite order (because the delay got shorter each time effectivly causing the first item animated to appear to move last)

in the end i simply made a reverse version of the array.
since only the index is needed in the reverse version (not the object itself) i could make it more efficient by not copying the normal array at all. instead i could make an empty array of the same length and reverse that

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.
×
×
  • Create New...