Jump to content
Search Community

Update tween duration on nested timeline

ajhalls 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

I am making a simple GUI timeline for working with Greensock (https://ajhalls.github.io/Simple-Animation-Timeline-for-Greensock/) that users can use when building a more comprehensive tool. Most of the heavy lifting is done (I think), but I was trying to figure out how to update a child timeline element when I update the width of the element by dragging it's div.

 

It has been a while since I was playing with Greensock and I can't remember how to dump the timeline info and update it. For example on the link above, you can apply multiple effects to the element $("#exampleAnimation"). Those timelines are created by the following code which will create an array of timelines called "elementTL[timelineItems]" which then get added to mainTL.

$("#AddManual").on("click", function(){
    var formAnimationX = $("#formAnimationX").val();
    var formAnimationY = $("#formAnimationY").val();
    var formAnimationDuration = $("#formAnimationDuration").val();
    greenAni(targetthing,  {"duration": formAnimationDuration, "x": formAnimationX, "y": formAnimationY, "ease": "Elastic.easeOut"});
    reInit();
});

function greenAni(targetItem, sequence) {
    var assembledTimeline = ""
    var greenAniArray = {options:{}};
      if ($.isArray(sequence))
      {         
          for (S = 0; S < sequence.length; S++) {
             for (var setting in sequence[S]) {
                if (setting == "duration")
                {
                    greenAniArray["duration"] = sequence[S][setting];
                }else{
                    greenAniArray["options"][setting] = sequence[S][setting];
                }
              }
                animationSequence = greenAniArray["options"];
                animationDuration = greenAniArray["duration"];
                assembledTimeline += '.to(' + targetItem + ', ' + animationDuration + ', ' + JSON.stringify(animationSequence) + ')';
          }
      }
      else
      {
        for (var setting in sequence) {
            if (setting == "duration") {greenAniArray["duration"] = sequence[setting];}
            else {greenAniArray["options"][setting] = sequence[setting];}
        }
        animationSequence = greenAniArray["options"];
        animationDuration = greenAniArray["duration"];
        assembledTimeline += '.to($(' + targetItem + '), ' + animationDuration + ', ' + JSON.stringify(animationSequence) + ')';
      }
                  
    elementTL[timelineItems] = new TimelineLite();
    var TLcurrent = elementTL[timelineItems];
    var TL = "TLcurrent" + assembledTimeline;
    eval(TL);
    timelineItems++;
};

function reInit() {
    mainTL.clear();
    mainTL = new TimelineLite({onUpdate:updateSlider, paused: true});
    for(i=0; i<elementTL.length; i++){
        var startTime = ($("#draggbleElement-"+ (i+1)).position().left)/ZoomValue+12;
        mainTL.add(elementTL[i], startTime/1000);
    }
}

So I would imagine I need to either modify the original timeline `elementTL[timelineItems]`, or the `mainTL` that it was appended to, but I can't find any info by doing `console.log(mainTL)` or on the other.

 

Is there a way to dump the current animations to JSON that would give me a better way of visualizing what I am working with?

 

 

 

Link to comment
Share on other sites

I can't really figure out what all that code is supposed to do, but to directly answer your question, clear() will remove all animations from a timeline. In your code I see you are calling mainTL.clear() but I don't see a where mainTL is defined prior to that. My guess is that you would want to define mainTL outside of any functions so that it isn't locked inside of a function scope somewhere and inaccessible. 

  • Like 2
Link to comment
Share on other sites

Here, lets look at it in a simplified codepen:

See the Pen EZwvdj by ajhalls (@ajhalls) on CodePen

 

Here you can add a bunch of effects to the object, and you can specify the start time of each animation using the text field. Each time you click a button, the sequence is added to it's own timeline 'elementTL[timelineItems]' where 'timelineItems' is a autoincrementing number each time you click the button.

 

Then it adds that timeline to a parent timeline called mainTL. As more timelines are added, it uses the "reInit()" function to clear the main timeline and then adds them all back in one by one.

 

Now on my timeline GUI (https://ajhalls.github.io/Simple-Animation-Timeline-for-Greensock/) that I am building, I want to be able to click and drag the child timelines around, modify durations and so on. What I am wondering is how to access the existing timeline to update existing values, rather than destroying and re initializing the timeline a hundred times per second as I am dragging things around.

 

I have tried all the things I can think of using the documentation, but for example, all of these commands:

elementTL[0].getTweensOf(target:*, onlyActive:Boolean = false):Array
mainTL.getTweensOf(target:*, onlyActive:Boolean = false):Array
mainTL.getTweensOf(target:$("#exampleAnimation"), onlyActive:Boolean = false):Array
TimelineLite.getTweensOf(target:*, onlyActive:Boolean = false):Array

give me the error:

SyntaxError: missing ) after argument list

Trying to use the .set() function (https://www.greensock.com/asdocs/com/greensock/TimelineLite.html#set()) doesn't seem to be accessing the right things as I don't get an error, but it doesn't update the object as I think it should.

 

Is there a way to export / dump the info that the different timelines have so I can know better how to direct my .set() function knowing I am accessing the right timelines, and then can re-export / dump to see that those changes took effect?

Link to comment
Share on other sites

Hello ajhalls,

 

Have you looked into the exportRoot() method

 

https://greensock.com/docs/#/HTML5/GSAP/TimelineMax/exportRoot/

 

exportRoot()

  • Seamlessly transfers all tweens, timelines, and [optionally] delayed calls from the root timeline into a new TimelineLite so that you can perform advanced tasks on a seemingly global basis without affecting tweens/timelines that you create after the export.

:)

  • Like 1
Link to comment
Share on other sites

So spending some more time in the documentation and it isn't looking pretty. While Greensock certainly is powerful in it's way, it seems to be greatly lacking in the ability to manipulate any existing events.

 

I did finally figure out how to get the "getTweensOf" to work:

mainTL.getTweensOf($("#exampleAnimation"), true)

Once I figured that out, the rest of the documentation started making more sense, sort of... For example,  in the documentation you have:

public function getTweensOf(target:Object, nested:Boolean = true):Array
or 
public function remove(value:*):*

I have no idea what :Array is supposed to mean, or :*, so that doesn't really help to have it in the documentation without actually explaining it, at least not for a self educated programmer, maybe if I had taken classes that would make more sense. As you can see in the above post, I really got confused by the "target:Object, nested:Boolean = true" trying such things as:

mainTL.getTweensOf({target:*, onlyActive:Boolean = false})
mainTL.getTweensOf({"target":*, "onlyActive":"Boolean = false"})
mainTL.getTweensOf({"target":$("#exampleAnimation"), "onlyActive":"Boolean = false"})
mainTL.getTweensOf({"target":"$("#exampleAnimation")", "onlyActive":"Boolean = false"})

Ok, so I digress on my actual topic, sorry.

 

The object that stores everything is very convoluted and circular with things buried in so many layers without actually identifying anything such as the target that it makes accessing that info almost useless. For example, once I add a tween, the target gets stored as something like "jQuery3110143163648180085761" which doesn't give me any information on what I am targeting.

 

Now on that codepen:

See the Pen EZwvdj by ajhalls (@ajhalls) on CodePen

, if I wanted to add 3 effects at various times to the same object, there doesn't seem to be any way of removing just one of them. I tried to add my tweens with labels such as "Animation-1", "Animation-2" that could then be used to use the remove() function, but that only seems able to remove the label, not the tween I was trying to associate with it. Now using the .remove() function might be useful, IF I could get a list of tweens that exist, but instead I get back something like this:

SONStringify(mainTL.getTweensOf($("#exampleAnimation"), true))
"[
    {
        "vars": {
            "ease": "Power1.easeInOut",
            "css": {
                "rotationY": "+=360"
            }
        },
        "_totalDuration": 2,
        "_duration": 2,
        "_delay": 0,
        "_timeScale": 1,
        "_active": false,
        "_reversed": false,
        "_startTime": 0,
        "_timeline": {
            "vars": {},
            "_totalDuration": 2,
            "_duration": 2,
            "_delay": 0,
            "_timeScale": 1,
            "_active": false,
            "_reversed": false,
            "_startTime": 0.177,
            "_timeline": {
                "vars": {
                    "paused": true
                },
                "_totalDuration": 0,
                "_duration": 0,
                "_delay": 0,
                "_timeScale": 1,
                "_active": false,
                "_reversed": false,
                "_startTime": 15.397,
                "_timeline": {
                    "vars": {},
                    "_totalDuration": 0,
                    "_duration": 0,
                    "_delay": 0,
                    "_timeScale": 1,
                    "_active": true,
                    "_reversed": false,
                    "smoothChildTiming": true,
                    "autoRemoveChildren": true,
                    "_startTime": 0,
                    "_first": {
                        "vars": {
                            "paused": true
                        },
                        "_totalDuration": 0,
                        "_duration": 0,
                        "_delay": 0,
                        "_timeScale": 1,
                        "_active": false,
                        "_reversed": false,
                        "_startTime": 3.993,
                        "_next": {
                            "vars": {
                                "paused": true
                            },
                            "_totalDuration": 0,
                            "_duration": 0,
                            "_delay": 0,
                            "_timeScale": 1,
                            "_active": false,
                            "_reversed": false,
                            "_startTime": 7.384,
                            "_pauseTime": 8.034,
                            "_paused": true,
                            "smoothChildTiming": false,
                            "autoRemoveChildren": false,
                            "_labels": {},
                            "_sortChildren": true,
                            "_first": null,
                            "_last": null,
                            "_recent": null,
                            "_dirty": true,
                            "_forcingPlayhead": false,
                            "_rawPrevTime": 0.65,
                            "_time": 0,
                            "_totalTime": 0,
                            "_initted": true
                        },
                        "_prev": null,
                        "_pauseTime": 4.133,
                        "_paused": true,
                        "smoothChildTiming": false,
                        "autoRemoveChildren": false,
                        "_labels": {},
                        "_sortChildren": true,
                        "_first": null,
                        "_last": null,
                        "_recent": null,
                        "_dirty": true,
                        "_forcingPlayhead": false,
                        "_rawPrevTime": 0.14,
                        "_time": 0,
                        "_totalTime": 0,
                        "_initted": true
                    },
                    "_rawPrevTime": 16.464,
                    "_time": 16.464,
                    "_totalTime": 16.464,
                    "_dirty": true
                },
                "_next": null,
                "_pauseTime": 15.397,
                "_paused": true,
                "smoothChildTiming": false,
                "autoRemoveChildren": false,
                "_labels": {},
                "_sortChildren": true,
                "_first": {
                    "vars": {},
                    "_totalDuration": 2,
                    "_duration": 2,
                    "_delay": 0,
                    "_timeScale": 1,
                    "_active": false,
                    "_reversed": false,
                    "_startTime": 0.1745,
                    "_prev": null,
                    "smoothChildTiming": false,
                    "autoRemoveChildren": false,
                    "_labels": {
                        "item-": 0
                    },
                    "_sortChildren": true,
                    "_first": {
                        "vars": {
                            "ease": "Power2.easeOut",
                            "css": {
                                "rotationX": "+=360"
                            }
                        },
                        "_totalDuration": 2,
                        "_duration": 2,
                        "_delay": 0,
                        "_timeScale": 1,
                        "_active": false,
                        "_reversed": false,
                        "_startTime": 0,
                        "_next": null,
                        "_prev": null,
                        "target": {
                            "0": {
                                "jQuery311073036382391618031": {
                                    "events": {
                                        "mousedown": [
                                            {
                                                "type": "mousedown",
                                                "origType": "mousedown",
                                                "data": null,
                                                "guid": 42,
                                                "namespace": ""
                                            }
                                        ]
                                    }
                                },
                                "_gsTweenID": "t1",
                                "_gsTransform": {
                                    "perspective": 0,
                                    "force3D": "auto",
                                    "svg": false,
                                    "skewType": "compensated",
                                    "rotationX": 200.56091259937503,
                                    "rotationY": 40.27122000000001
                                }
                            },
                            "length": 1
                        },
                        "_overwrite": 2,
                        "_targets": [
                            null
                        ],
                        "_propLookup": [
                            {
                                "rotationX": {
                                    "_next": null,
                                    "t": {
                                        "_overwriteProps": [
                                            "rotationX",
                                            "rotationX"
                                        ],
                                        "_propName": "css",
                                        "_priority": 0,
                                        "_super": {
                                            "_firstPT": null
                                        },
                                        "_transformType": 3,
                                        "_firstPT": {
                                            "p": "rotationX",
                                            "s": 0,
                                            "c": 360,
                                            "n": "rotationX",
                                            "type": 0,
                                            "b": 0,
                                            "e": 360,
                                            "xs0": 0,
                                            "_next": {
                                                "p": "transform",
                                                "s": 0,
                                                "c": 0,
                                                "n": "transform",
                                                "type": 2,
                                                "b": 0,
                                                "e": 0,
                                                "_next": null,
                                                "pr": -1
                                            }
                                        }
                                    },
                                    "p": "setRatio",
                                    "s": 0,
                                    "c": 1,
                                    "f": 1,
                                    "n": "css",
                                    "pg": 1,
                                    "pr": 0,
                                    "m": 0
                                }
                            }
                        ],
                        "_siblings": [
                            [
                                {
                                    "vars": {
                                        "rotationX": "+=360",
                                        "ease": "Power2.easeOut"
                                    },
                                    "_totalDuration": 2,
                                    "_duration": 2,
                                    "_delay": 0,
                                    "_timeScale": 1,
                                    "_active": false,
                                    "_reversed": false,
                                    "_startTime": 0,
                                    "_timeline": {
                                        "vars": {},
                                        "_totalDuration": 2,
                                        "_duration": 2,
                                        "_delay": 0,
                                        "_timeScale": 1,
                                        "_active": false,
                                        "_reversed": false,
                                        "_startTime": 0.687,
                                        "_next": null,
                                        "smoothChildTiming": false,
                                        "autoRemoveChildren": false,
                                        "_labels": {
                                            "item-": 0
                                        },
                                        "_sortChildren": true,
                                        "_dirty": false
                                    },
                                    "_next": null,
                                    "_prev": null,
                                    "target": {
                                        "length": 1
                                    },
                                    "_overwrite": 2,
                                    "_targets": [
                                        null
                                    ],
                                    "_propLookup": [],
                                    "_siblings": [
                                        null
                                    ]
                                },
                                null,
                                null
                            ]
                        ],
                        "_gc": false,
                        "_time": 0.47550000000000003,
                        "_totalTime": 0.47550000000000003,
                        "ratio": 0.5571136461093751,
                        "_ease": {
                            "_func": null,
                            "_type": 1,
                            "_power": 2,
                            "_params": [
                                0,
                                0,
                                1,
                                1
                            ]
                        },
                        "_easeType": 1,
                        "_easePower": 2,
                        "_initted": true,
                        "_rawPrevTime": -1,
                        "_lazy": false
                    },
                    "_dirty": false,
                    "_gc": false,
                    "_rawPrevTime": 0.47550000000000003,
                    "_time": 0.47550000000000003,
                    "_totalTime": 0.47550000000000003,
                    "_initted": true
                },
                "_dirty": true
            },
            "smoothChildTiming": false,
            "autoRemoveChildren": false,
            "_labels": {
                "item-": 0
            },
            "_sortChildren": true,
            "_dirty": false,
            "_rawPrevTime": 0.47300000000000003,
            "_time": 0.47300000000000003,
            "_totalTime": 0.47300000000000003,
            "_initted": true,
            "_gc": false
        },
        "_next": null,
        "_prev": null,
        "target": {
            "length": 1
        },
        "_overwrite": 2,
        "_targets": [
            null
        ],
        "_propLookup": [
            {
                "rotationY": {
                    "_next": null,
                    "t": {
                        "_overwriteProps": [
                            "rotationY",
                            "rotationY"
                        ],
                        "_propName": "css",
                        "_priority": 0,
                        "_transformType": 3,
                        "_firstPT": {
                            "p": "rotationY",
                            "s": 0,
                            "c": 360,
                            "n": "rotationY",
                            "type": 0,
                            "b": 0,
                            "e": 360,
                            "xs0": 0,
                            "_next": {
                                "p": "transform",
                                "s": 0,
                                "c": 0,
                                "n": "transform",
                                "type": 2,
                                "b": 0,
                                "e": 0,
                                "_next": null,
                                "pr": -1
                            }
                        }
                    },
                    "p": "setRatio",
                    "s": 0,
                    "c": 1,
                    "f": 1,
                    "n": "css",
                    "pg": 1,
                    "pr": 0,
                    "m": 0
                }
            }
        ],
        "_siblings": [
            null
        ],
        "_time": 0.47300000000000003,
        "_totalTime": 0.47300000000000003,
        "ratio": 0.11186450000000002,
        "_ease": {
            "_func": null,
            "_type": 3,
            "_power": 1
        },
        "_easeType": 3,
        "_easePower": 1,
        "_initted": true,
        "_rawPrevTime": -1,
        "_lazy": false,
        "_gc": false
    },
    null,
    null
]"

Now I don't see anything useful in there that can be used to identify something to modify / remove / kill / replace.

 

Maybe I am prematurely aggravated, but I purchased a business perpetual license specifically to design this timeline tool after working with Velocity.JS which would have required wrapping objects inside objects to apply multiple animations, which Greensock can do without any problem, but can't seem to make any headway on modifying things, which might explain the lack of GUI interfaces.

 

Can this be done in a round about way, yes. I could store everything in my own JSON object and then keep clearing / re-initializing the timeline every time I make a change, but that seems like overkill for what I expected to be able to do with a product as mature as Greensock, and seems like it would have a lot more user lag than simply modifying a few values here and there as you work.

Link to comment
Share on other sites

Thanks for the reply Jonathan, my super long reply was being typed while you were responding :). TimeLineLite.exportRoot() gives me pretty much the exact same info as before with an extra layer above. I still don't see any way to give a tween a name which can be accessed to update or alternately to remove and then re add it in again. It would be helpful if they were given names, ids, or something to work with.

{
    "vars": {
        "smoothChildTiming": true
    },
    "_totalDuration": 0,
    "_duration": 0,
    "_delay": 0,
    "_timeScale": 1,
    "_active": false,
    "_reversed": false,
    "_startTime": 0,
    "_timeline": {
        "vars": {},
        "_totalDuration": 0,
        "_duration": 0,
        "_delay": 0,
        "_timeScale": 1,
        "_active": true,
        "_reversed": false,
        "smoothChildTiming": true,
        "autoRemoveChildren": true,
        "_startTime": 0,
        "_rawPrevTime": 15.611,
        "_time": 15.611,
        "_totalTime": 15.611,
        "_dirty": true
    },
    "_next": null,
    "_prev": null,
    "smoothChildTiming": true,
    "autoRemoveChildren": false,
    "_labels": {},
    "_sortChildren": true,
    "_totalTime": 15.611,
    "_time": 15.611,
    "_rawPrevTime": 15.611,
    "_first": {
        "vars": {
            "smoothChildTiming": true
        },
        "_totalDuration": 3.3565,
        "_duration": 3.3565,
        "_delay": 0,
        "_timeScale": 1,
        "_active": true,
        "_reversed": false,
        "_startTime": 11.031,
        "_next": {
            "vars": {
                "paused": true
            },
            "_totalDuration": 0,
            "_duration": 0,
            "_delay": 0,
            "_timeScale": 1,
            "_active": false,
            "_reversed": false,
            "_startTime": 15.611,
            "_next": null,
            "_pauseTime": 15.611,
            "_paused": true,
            "smoothChildTiming": false,
            "autoRemoveChildren": false,
            "_labels": {},
            "_sortChildren": true,
            "_first": {
                "vars": {},
                "_totalDuration": 2,
                "_duration": 2,
                "_delay": 0,
                "_timeScale": 1,
                "_active": false,
                "_reversed": false,
                "_startTime": 0.012,
                "_next": {
                    "vars": {},
                    "_totalDuration": 2,
                    "_duration": 2,
                    "_delay": 0,
                    "_timeScale": 1,
                    "_active": false,
                    "_reversed": false,
                    "_startTime": 0.4595,
                    "_next": null,
                    "smoothChildTiming": false,
                    "autoRemoveChildren": false,
                    "_labels": {
                        "item-1": 0
                    },
                    "_sortChildren": true,
                    "_first": {
                        "vars": {
                            "rotationX": "+=360",
                            "ease": "Power2.easeOut"
                        },
                        "_totalDuration": 2,
                        "_duration": 2,
                        "_delay": 0,
                        "_timeScale": 1,
                        "_active": false,
                        "_reversed": false,
                        "_startTime": 0,
                        "_next": null,
                        "_prev": null,
                        "target": {
                            "0": {
                                "jQuery31107172755050163471": {
                                    "events": {
                                        "mousedown": [
                                            {
                                                "type": "mousedown",
                                                "origType": "mousedown",
                                                "data": null,
                                                "guid": 42,
                                                "namespace": ""
                                            }
                                        ]
                                    }
                                },
                                "_gsTweenID": "t1",
                                "_gsTransform": {
                                    "perspective": 0,
                                    "force3D": "auto",
                                    "svg": false,
                                    "skewType": "compensated",
                                    "rotationY": 30.331844999999994
                                }
                            },
                            "length": 1
                        },
                        "_overwrite": 2,
                        "_targets": [
                            null
                        ],
                        "_propLookup": [],
                        "_siblings": [
                            [
                                null,
                                {
                                    "vars": {
                                        "ease": "Power1.easeInOut",
                                        "css": {
                                            "rotationY": "+=360"
                                        }
                                    },
                                    "_totalDuration": 2,
                                    "_duration": 2,
                                    "_delay": 0,
                                    "_timeScale": 1,
                                    "_active": false,
                                    "_reversed": false,
                                    "_startTime": 0,
                                    "_next": null,
                                    "_prev": null,
                                    "target": {
                                        "length": 1
                                    },
                                    "_overwrite": 2,
                                    "_targets": [
                                        null
                                    ],
                                    "_propLookup": [
                                        {
                                            "rotationY": {
                                                "_next": null,
                                                "t": {
                                                    "_overwriteProps": [
                                                        "rotationY",
                                                        "rotationY"
                                                    ],
                                                    "_propName": "css",
                                                    "_priority": 0,
                                                    "_super": {
                                                        "_firstPT": null
                                                    },
                                                    "_transformType": 3,
                                                    "_firstPT": {
                                                        "p": "rotationY",
                                                        "s": 0,
                                                        "c": 360,
                                                        "n": "rotationY",
                                                        "type": 0,
                                                        "b": 0,
                                                        "e": 360,
                                                        "xs0": 0,
                                                        "_next": {
                                                            "p": "transform",
                                                            "s": 0,
                                                            "c": 0,
                                                            "n": "transform",
                                                            "type": 2,
                                                            "b": 0,
                                                            "e": 0,
                                                            "_next": null,
                                                            "pr": -1
                                                        }
                                                    }
                                                },
                                                "p": "setRatio",
                                                "s": 0,
                                                "c": 1,
                                                "f": 1,
                                                "n": "css",
                                                "pg": 1,
                                                "pr": 0,
                                                "m": 0
                                            }
                                        }
                                    ],
                                    "_siblings": [
                                        null
                                    ],
                                    "_time": 0.4105,
                                    "_totalTime": 0.4105,
                                    "ratio": 0.08425512499999999,
                                    "_ease": {
                                        "_func": null,
                                        "_type": 3,
                                        "_power": 1,
                                        "_params": [
                                            0,
                                            0,
                                            1,
                                            1
                                        ]
                                    },
                                    "_easeType": 3,
                                    "_easePower": 1,
                                    "_initted": true,
                                    "_rawPrevTime": -1,
                                    "_lazy": false,
                                    "_gc": false
                                }
                            ]
                        ]
                    },
                    "_dirty": false
                },
                "_prev": null,
                "smoothChildTiming": false,
                "autoRemoveChildren": false,
                "_labels": {
                    "item-0": 0
                },
                "_sortChildren": true,
                "_dirty": false,
                "_rawPrevTime": 0.4105,
                "_time": 0.4105,
                "_totalTime": 0.4105,
                "_initted": true,
                "_gc": false
            },
            "_dirty": true
        },
        "_prev": null,
        "smoothChildTiming": true,
        "autoRemoveChildren": false,
        "_labels": {},
        "_sortChildren": true,
        "_totalTime": 3.3565,
        "_time": 3.3565,
        "_rawPrevTime": 4.58,
        "_first": {
            "vars": {
                "paused": true
            },
            "_totalDuration": 0,
            "_duration": 0,
            "_delay": 0,
            "_timeScale": 1,
            "_active": false,
            "_reversed": false,
            "_startTime": 1.3445,
            "_next": null,
            "_prev": null,
            "_pauseTime": 1.767,
            "_paused": true,
            "smoothChildTiming": false,
            "autoRemoveChildren": false,
            "_labels": {},
            "_sortChildren": true,
            "_first": null,
            "_last": null,
            "_recent": null,
            "_dirty": true,
            "_forcingPlayhead": false,
            "_rawPrevTime": 0.4225,
            "_time": 0,
            "_totalTime": 0,
            "_initted": true
        },
        "_dirty": true,
        "_initted": true,
        "_forcingPlayhead": false
    },
    "_dirty": true
}
Link to comment
Share on other sites

Sorry to hear you have had problems reading the docs. We try to follow some fairly standard practices for documenting methods.

Every method has a "method signature" which allows you to see"

 

  • the name of the method
  • the parameters the method can receive
  • the type of parameters the method can receive
  • the type of data the method will return when called.

In simple terms the method signature tells you what you can send in and what it will give back. 

 

Suppose you had a function that multiplied any number by 2. The actual code for the function might be

 

function multiplyBy2(number) {

  return number * 2;

}

 

However, the end user of our code does not need to know all the internal stuff that the function does, like "return number * 2;" If they do they can read the source code. In the documentation we just show the method signature to show how to use the function. The multiplyBy2() function would have a method signature like this

 

multiplyBy2(number:Number):Number

 

By reading the method signature above you can learn that the method takes one parameter called number which should be an actual Number (not a String, Array, or Object) and the function will return a single value of type: Number

 

so you would use that function by writing

console.log(multiplyBy2(4));

and you would be returned the value of 8

 

Think of the method signature as describing what the method takes in and returns back. It is not showing you the syntax for using the method.

 

 

Now suppose you had another function that added a bunch of numbers together? It would most likely have a method signature like this

 

addAllNumber(numbers:Array):Number

 

This method signature says this method takes one parameter called numbers which will be an Array.  It will return a Number. So in use you might write code that looks like

myArray = [2, 3, 2];

console.log(addAllNumbers(myArray));

and that function would return a single Number of 7

 

The method signature for that method however does not tell you that the numbers Array that you pass in as the first parameter should actually contain numbers. 

That would have to be detailed in the parameter description somewhere else in the documentation. 

 

 

Circling back to the method signature of getTweensOf()

 

getTweensOf( target:Object, nested:Boolean ) : Array

 

This tells you that the function expects 2 parameters: The object you want the tweens of and whether or not it should look in nested timelines for those tweens. 

Since an object can be the target of many tweens, the return type is :Array so that the function can return multiple items in one data container.

 

Usage of getTweensOf would look like

getTweensOf("#myDiv", false);

Back to your question about modifying tweens or finding them. We are working on a way of allowing you to give them an id when you create them so that you can easily find them later.

 

 

You can attach any data to a tween that you want. So if you wanted to give your tween a name you could do:

 

var green = TweenLite.to(".green", 1, {y:200, data:{name:"greenTween"}});
console.log(green.vars.data.name)

You could then do a getChildren() call on your timeline to get an Array of all the tweens in the timeline and search for a tween with that name.

 

 

 

Another route is you can start by creating your own references to them prior to adding them to a timeline. Something like

 

var green = TweenLite.to(".green", 1, {y:200});
var orange = TweenLite.to(".orange", 1, {y:200});


var mainTimeline = new TimelineLite();
mainTimeline.add(green);
mainTimeline.add(orange, 5)// add at a time of 5 seconds.


//Later you could change the duration of the green tween by doing


green.duration(5);

However, I really don't think finding the tween and modifying it is going to be the right way to go. 

 

For performance reasons, every tween in a timeline has its starting and ending values recorded internally after the first time they render. This makes things super fast each time the animations play. GSAP puts huge emphasis on run-time performance. So although right now you are very focused on updating the properties of one tween on one object. You should consider that if you have 2 tweens on the SAME OBJECT that run like this:
 
timeline.to(red, 1, {x:200}) //tween1
timeline.to(red, 2, {x:300}) //tween2
 
the first time that timeline plays:
 
  • tween1 will move red from wherever it is to an x of 200
  • tween2 will have a starting x value of 200 because that is where tween1 ended.
 
If you allow the user to monkey with the end value of tween1 by dragging the red thing to end at an x value of 400 in the GUI then tween2 is not going to automatically update its start value to be 400 the next time the animation plays. You would have to manage that tween as well or invalidate() the timeline. See the dilemma?

 

I think you may ultimately find the easiest route to manage is what you already tried: destroy and create the main timeline every time you need to run an animation showing a recent change. Keep in mind that tween creation is relatively cheap. You can create 1000 tweens in just a few milliseconds. 

 

Regarding doing it 100s of times per second. I'm having trouble understanding when that would be necessary. If it had to be done during some user-interaction like dragging you could definitely throttle it, but I would think the only time a new timeline would be be needed is when the user wanted to play the animation after a change was made or moved the playhead somewhere else (if that is supported).

  • Like 3
Link to comment
Share on other sites

Thanks Carl, like the others I too appreciate the thorough reply. Knowing that the tweens can be destroyed and recreated without too much of a hit on performance gives me this solution:

function compileAnimations(targetItem,sequence) {
    startTime = insertTime/ZoomValue;
    compiledAnimations.push({"itemID" : timelineItems+1, "target":targetItem, "animationSequence":JSON.stringify(animationSequence)});   
    compiledAnimations[timelineItems]["startTime"] = startTime;
    compiledAnimations[timelineItems]["animationDuration"] = animationDuration;

};

function rebuildTimeline() {
    if ($.isArray(compiledAnimations))
      {           
    mainTL.clear();
    mainTL = new TimelineLite({onUpdate:updateSlider, paused: true});
    var assembledTimeline = "";
    var TL = [];
          for (S = 0; S < compiledAnimations.length; S++) {
                assembledTimeline = '.to(' + compiledAnimations[S].target + ', ' + compiledAnimations[S].animationDuration + ', ' + compiledAnimations[S].animationSequence + ')';
                elementTL[timelineItems] = new TimelineLite();
                var TLcurrent = elementTL[S];
                TL[S] ={};
                TL[S].startTime = compiledAnimations[S].startTime;
                TL[S].timeline = "TLcurrent" + assembledTimeline;
                
                eval(TL[S].timeline);
            }
        for(i=0; i<TL.length; i++){
         console.log(TL[i]);
           mainTL.add(TL[i].timeline, TL[i].startTime/1000);
        }
      }
};

the compileAnimations() gives me an array like this:

[
    {
        "itemID": 1,
        "target": "$("#exampleAnimation")",
        "animationSequence": "{"rotationX":"+=360","ease":"Power2.easeOut"}",
        "startTime": 270,
        "animationDuration": "2"
    },
    {
        "itemID": 2,
        "target": "$("#exampleAnimation")",
        "animationSequence": "{"rotationY":"+=360","ease":"Power1.easeInOut"}",
        "startTime": 877.5,
        "animationDuration": "2"
    }
]

That way I can modify my array / object and then just call the rebuildTimeline() function as often as needed. I can throttle it as you say to not updating it till the user does a mouseup, rather than on drag. I will think on your idea of creating named timelines like this:

var green = TweenLite.to(".green", 1, {y:200});
var orange = TweenLite.to(".orange", 1, {y:200});

It gets a little trickier to me to setup a lot of variables with variable names. The end product will have so many animations tied to different objects, keeping it in JSON seemed easier, at least for now :)

 

I know these snippets may not explain everything I am doing in the background, but will push some updates to github once I get the drag and drop working.

Link to comment
Share on other sites

First of all, thanks for being a Club GreenSock member. Your support means a lot. 

 

Sorry to hear about the frustration. I'm pretty confident that we can help you get whatever hooks you need to make this GUI thing you're attempting. The more familiar you get with the API, the more I bet you'll find that GSAP is absolutely ideal for building a GUI around. 

 

There are quite a few things we've had to engineer GSAP around like performance and memory management. We can't just store a permanent reference to every tween ever created because that'd just cause memory to climb and prevent things from being GC'd. That being said, since around version 1.18.4 we've had a protected "id" property you can add to the vars object and it'll be preserved (not treated like a property that should be tweened). You could leverage that if you'd like, or use the "data" property that's always existed. Here are two functions I whipped together for you that'll let you search for things by "id" and it'll find anything that hasn't completed and made available for GC:

function getChildById(timeline, id) {
  var tween = timeline._first,
      sub;
  while (tween) {
    if (tween.vars.id === id) {
      return tween;
    } else if (!(tween instanceof TweenLite)) {
      sub = getChildById(tween, id);
      if (sub) {
        return sub;
      }
    }
    tween = tween._next;
  }
}
function getAnimationById(id) {
  return getChildById(com.greensock.core.Animation._rootTimeline, id);
}

So it should be as simple as getAnimationById("yourID")

 

Does that help? 

 

Instead of having GSAP manage all the references, though, you could do that yourself just like Carl indicated. That way, you have total control over when/how things are dumped and made available for GC. The point is you've got a lot of options with GSAP. :) 

  • Like 1
Link to comment
Share on other sites

Great Jack, I will look into using your 'id' solution as well. I am sure eventually we can find a solution.

 

Also BTW, I did learn from https://greensock.com/forums/topic/7381-getting-dom-elements-out-of-timeline/ that using .getChildren() will give you the DOM elements back. I am not sure yet what to do with that info, but it is related to the topic so I will tie them together.

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...