Jump to content

Robert Wildling

The role of "index" in function-based values

Recommended Posts

GSAP 1.19 ships with the ability to work with function-based values as the youtube tutorial explains (see below).


There are to attributes: index and target.

Whereas "target" is clear and can be logged out to the console, I have still no idea, how index is supposed to be used.


In the codepen I try to get a numeric value from the length of the div containers involved. But without success.


I'd be most grateful, if somebody could explain me how to think about that "index" value.

And maybe show me even a way, how to assign an decreasing scale value to those div (which eventually shall become water ripples... again...)






See the Pen amOBAO by rowild (@rowild) on CodePen

Link to comment
Share on other sites

Hello Robert Wildling,


Based on the ModifiersPlugin Docs:




Parameters: value, target


The modifier functions are passed two parameters:

  1. value (number | string) - the about-to-be-applied value from the regular tween. This is often a number, but could be a string based on whatever the property requires. For example if you're animating the x property, it would be a number, but if you're animating the left property it could be something like "212px", or for the boxShadow property it could be "10px 5px 10px rgb(255,0,0)".
  2. target (object) - the target itself

The first parameter is the value, even though it has a name of index in your codepen


You can also use the GSAP set() method to apply your initial transform: scale(1.3) .. so this way GSAP can apply the transform property cross browser.. since webkit based browsers like Chrome and Safari require -webkit-transfom instead of transform:


Add this right after line 16 so GSAP can add the right vendor prefixes so you dont have to add in stylesheet. And comment out your one in the stylesheet.

// GSAP sets the transform scale cross browser for vendor prefix's
TweenLite.set(PRELOADER.waves, {scale:0.3});

Does that make sense?



GSAP set() method : http://greensock.com/docs/#/HTML5/GSAP/TweenLite/set/

  • Like 2
Link to comment
Share on other sites

Thank you for your response, Jonathan!


I am confused, though, about some things.And it seems I didn't explain well enough, what I wanted to achieve. Please let me try again.


But first - the CSS prefixing: 

Since I usually have a gulp-workflow and stylesheets are read earlier than javascripts, I thought all the prefixes are available, anyway. No need to make GSAP do more work than necessary. Or am I thinking wrong here? Is it better for GSAP itself to set the values?


Then - the index... again:

How can I find out, what value it transfers? I still have no idea how I can change it or use it. It should hold the scale value, right? The scale-value-to-be according to the modifiers' docs, right? But, unlike the rotation-example given, I cannot log the "content" of index...


The idea is that the circles start out at scale(0.3) (or so, will be set by CSS), and then should individually scale to their own values.

So the first circle should scale from 0.3->2, 

the second: 0.3 -> 1.5,

the third:      0.3 -> 1

(The higher the index of the circle is, the less it should expand...)


Using a function-based value seemed the way to go. But I am still stuck...


Anymore hints?

Thank you!

Link to comment
Share on other sites

Hi Robert,


You're in a bit of a tricky spot :) let me try to help.


Try to forget about the ModifiersPlugin that Jonathan suggested. I see why he mentioned it, but that is better for values that change while a tween is running.


Function-based values are helpful when you are creating a single tween with multiple targets.

Here is a super simple example of getting the index of each target of a tween using a simplified version of your setup:

var tween = TweenLite.to(".circle", 1, {scale:function(index, target){  console.log(index); //0, 1, 2
  return (index+1) * 2;

console.log(tween); // a tween object 

//this can work
document.getElementById("restart").onclick = function() {



In the example above TweenLite.to() creates a single tween with multiple targets being animated to multiple values.

You can reference the tween and control with methods like restart(). It's pretty crazy.

The one downside of function-based values for a single tween with multiple targets is that you can not give each animation a unique delay. Each target must start animating at the same time for the same duration. This is where staggerTo() will help you out as you can stagger the start times.



So it's good that you are using staggerTo() but it's necessary to understand that staggerTo() creates an ARRAY of individual tweens for each target that you pass in (which is why they can all start at different times).



This demo shows how TweenMax.staggerTo() creates an Array of tweens


var tweens = TweenMax.staggerTo(".circle", 1, {scale:1}, 0.1)

console.log(tweens); // an Array!!!

//this won't work because an Array doesn't have a restart() method
document.getElementById("restart").onclick = function() {



The problem with mixing staggerTo() and function-based values is that you were creating a bunch of individual tweens that all had only 1 target. That is why the index never incremented and was always 0. For each circle there was a new tween created and that tween only had 1 target. 


Before we introduced function-based values we had a cycle property for staggered tweens which I think is exactly what will help you here.


Below is very simple demo of the cycle property with TimelineMax.staggerTo(). TimelineMax.staggerTo() still works similarly to TweenMax.staggerTo() in that it creates a bunch of tweens, it just puts them in a timeline for you (not a loose array of tweens). 

var tweens = new TimelineMax();

tweens.staggerTo(".circle", 1, {scale:1, cycle:{
  scale:function(index, target){
    return (index + 1) * 1;
}}, 0.5);



The cycle feature also allows you to specify an array of values like [0.3, 1, 2] which each target will "cycle through".


Watch the video about using cycle with staggers here: http://greensock.com/gsap-1-18-0


Hopefully this helps clear things up. I'm confident staggerTo() with cycle will give you all the flexibility you need.

  • Like 4
Link to comment
Share on other sites

Thank you so much, Carl, for taking the time to provide such an excellent, detailed answer! It is as if a light was turned on in my head :-)


I'll get to work now, looking forward to explore new possibilities!


Thanks to all of you!

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.