Jump to content
Search Community

How to interrupt and reset a Timeline object

sigmundsquirrel 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 have a problem with a relatively simple animation that may be interrupted by interactivity. When it is, it needs to reset itself and play again. I'm able to do this except for the Timeline object, which is acting weird, sending wrong x/y values to the tweens. It is an animation of a mouse moving through a maze. The maze walls build on stage, then the mouse fades in, and on 'click' it will tween through the maze using a preset Timeline object. The last tween needs a dynamic x/y value because the mouse hole can move during the mouse animation. The solution to that was provided in these Greensock forums (calling another function to get the x/y and insert them into the Timeline object).

Everything works. Except when I try to interrupt the animation while it's running, reset it and run it again. Then the mouse does funny things. At first it would sit before moving for as long as was left un-run from the previous Timeline object sequence. So I set it to the end using totalProgress(1) in my reset function before calling the init again. That seems to work. But when the mouse gets to the spot where it updates the x/y for the last tween, it goes haywire.

The basic question is: How can I cleanly interrupt a Timeline sequence and then reset that Timeline so it can run again from the beginning. And is there a special solution required because of my special getXY function at the end of the Timeline?

I've made a simplified version of the code here. I wanted to keep it robust enough to show the potential problems with complexity. I hope I didn't make it too long.

var distanceX;
var distanceY;
var mousetween = new TimelineMax();


function initAnimation() {
       //set some other variables
       loadWalls();
}


function loadWalls() {
       var mazetween = new TimelineMax({onComplete:loadMouse});
       //this is simplified:
       mazetween.to("#wall1", .2, {opacity:1});
       mazetween.to("#wall2", .3, {opacity:1});
       mazetween.to("#wall3", .4, {opacity:1});
}
    
function loadMouse() {
    //fade in mouse and set as button
    TweenMax.set($("#mouse"), {opacity:0, left:80, top:100, display:"block"});
    TweenMax.to($("#mouse"), 2, {opacity:1});
    $("#mouse").css('cursor', 'pointer');
    //the callback startMouse begins the animation that causes trouble on replay
    $("#mouse").on('click', startMouse);
}
    
//this is a set of tweens, with the last tween being updated dynamically
function startMouse() {
   var mouse = $("#mouse");
   mousetween.to(mouse, 1, {left:410});
    mousetween.to(mouse, .25, {rotation:90});
    mousetween.to(mouse, .5, {top:320});
    mousetween.to(mouse, .25, {rotation:0});
    mousetween.to(mouse, .5, {left:480});
    mousetween.to(mouse, .25, {rotation:90});
    mousetween.to(mouse, .5, {top:376});
    mousetween.to(mouse, .25, {rotation:180});
           
    //... omitted more movements through the maze to simplify ...
    
    //I call getMouseHole because the x/y of the mousehole is dynamic
    mousetween.call(getMouseHole);
    mousetween.to(mouse, 1, {top: distanceY}, "label1");
    mousetween.to(mouse, .25, {rotation:0}, "label2");
    mousetween.to(mouse, .5, {left:distanceX}, "label3");
    mousetween.to(mouse, 2, {alpha:0}, "label4");
}
       
function getMouseHole() {
    //get Y value of mousehole
    //there are calculations here, based on windowSize and scalePercent of graphics
    distanceY=400;
    distanceX=600;
    //this creates new tweens with updated x/y and inserts them into the pre-existing Timeline sequence
    var mouse = $("#mouse");
    mousetween.to(mouse, 1, {top: distanceY}, "label1");
    mousetween.to(mouse, .25, {rotation:0}, "label2");
    mousetween.to(mouse, .5, {left:distanceX}, "label3");
    mousetween.to(mouse, 2, {alpha:0}, "label4");
}


function resetAnimation() {
    //reset various properties:
    $("#wall1, #wall2, #wall3").css("opacity", 0);
    $("#mouse").css("opacity", 0);
    //Here I'm finishing the Timeline before trying to run it again:
    mousetween.totalProgress(1);
    TweenMax.set($("#mouse"), {rotation:0});
    //this waits a moment, then calls init again to start over
    setTimeout(initAnimation, 1000);
}
 

 

 

Link to comment
Share on other sites

Let's say you have a timeline that is 2 seconds long. At 1 second in you have a callback.

 

If at a time of 0.5 seconds you set timeline.progress(1) the playhead will jump over the callback at the 1 second mark AND the callback will fire. So even though you thought you were bypassing the callback... you weren't.

 

If you use the seek() method, that let's you jump to any time in the timeline and optionally suppress events. http://api.greensock.com/js/com/greensock/TimelineLite.html#seek()

 

When your timeline went haywire maybe that callback was firing more often than you thought.

 

I think the best thing for you to do on reset is set the progress to 0, which will place the mouse back in its starting position, clear() the timeline and then re-populate it with tweens / callbacks.

 

Something like

 

 

 

mouseTween.progress(0)
mouseTween.clear();
startMouse();
 
  • Like 2
Link to comment
Share on other sites

Ah -- the clear() method.

 

I was looking for something like that but didn't see it in the API docs at api.greensock.com/js  (In fact, I was having a hard time finding some stuff. A note in the TimelineMax section mentioned the totalProgress(x) method, but I couldn't find it until I looked in the TweenMax section. A comprehensive cross-category index would be a huge help!

 

mousetween.progress(0);
mousetween.clear();
startMouse();
 

This is the kind of simple efficient solution I was sure existed, but couldn't find. Thanks in advance. I'll apply it and run it around the block a few times.

 

If it works, thanks again. If it doesn't, I'll be back!

Link to comment
Share on other sites

Hi Sigmund, I think the trouble with finding the clear() method has to do with the fact that you can optionally hide methods that are inherited when viewing the docs. In the case of TimelineMax, clear() and many other methods are inherited from TimelineLite. When viewing the docs, make sure you click the "show inherited public methods link" as shown below:

 

Screen Shot 2013-03-01 at 7.57.32 PM.png

 

When you click on that link you will see all methods. And don't worry, I've totally missed things because of that myself.

 

Take a look at the TimelineMax page again and give it a shot: http://api.greensock.com/js/com/greensock/TimelineMax.html#methodSummary

  • Like 1
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...