TopGUN121

Refresh Timeline without hitting browser refresh button

Recommended Posts

Hi everyone,

 

I have been trying to find out a way to refresh a timeline without having to reload the whole page.   This is for my development tools so i don't have to always hit the browser refresh button and drag my slider to the last location i was editing to see my new css updates.   So here is what i'm doing and hoping you can help me out.

 

So i have my developer tools i have created for my greensock projects to help me with my projects.  We have a slider bar to move me along in the timeline we have created.  (my projects tend to be like learning videos).   Whenever i make an update to my css i have to hit reload on the browser and drag my slider to the position i am working in.   I do this like a thousand times a day and i'm getting a little tired of this. lol.   I have been able to get the browser to read my saved css edits without refreshing the whole browser.  But when i do that my greensock timeline is still going off of the old styles i had before i updated them.  I'm looking for a way in code that i could also have greensock recalculate the timeline without refreshing the whole page.   I want the inline css styles to update to match the updated css i just pulled in.    I would love something like mytimeline.refresh(); but i don't think we have anything like that.  

My main goal i want is when i'm working on the timeline and i need to move a div up 100 px i can hit my own reload button and it will update the greensock timeline to know that i moved my div up and make the animation correct and update the inline style.  I hope this makes sense to everyone and there is a solution out there to help me.  I just want to hit my own reload button and see the new css and the updated timeline properties show up without hitting the browser refresh button.

 

Thanks,

Brad

Share this post


Link to post
Share on other sites

Hello TopGUN121, and Welcome to the GreenSock Forum!

 

There are different ways to wipe out old values set or animated by GSAP. Like using invalidate()  before restarting your tween using restart(), or using one of the available  kill()  methods.

 

But to better help you, do you have a codepen example so we can see your code in action!

 

Here is a nice video tut by GreenSock on how to create a codedpen demo example.

 

By seeing your code in a live editable environment we will be able to offer available solutions.

 

Thank You! :)

  • Like 1

Share this post


Link to post
Share on other sites

Hi Brad,

 

I'm not completely sure I'm following you in this one, at least some part of your question.

 

What I can tell you is that in order to scrub the timeline's playhead at certain point, you can use any of the playback or position-adjusting methods. You have play(), pause(), seek(), time(), progress(), etc. And to make it very easy, you can use labels in your timeline and then take the timeline to that label and start playing from that position and update the slider:

var tl = new TimelineLite();

tl
  .to(el1, 1, {vars})
  .to(el2, 1, {vars})
  .add("label1")
  .to(el3, 1, {vars})
  .to(el4, 1, {vars});

//then move the playhead to the label's position
tl.pause("label1");
//or
tl.play("label1");
//or
tl.seek("label1");

You should definitely check this tutorial and video Carl made some time ago:

 

http://greensock.com/sequence-video

 

Now in terms of CSS updating, my guess is that you're updating the styles in dev tools and changing the css file at the same time, right?. In that scenario Jonathan's suggestion is the best way to go, is far better and less complicated to use a function to create the tween/timeline, kill the current one and call the function in order to create it again.

Share this post


Link to post
Share on other sites

I don't know if i could create a codepen to show you my projects since they are very big projects with tons of parts.   Rodrigo you are right, i'm update my local dev tools css in the browser, then take that and put it in my css file which i then save.   Then i have a button that will reload the just saved css file.   The browser shows the new css but greensock does not read the new css.  I do not want to restart the whole timeline since these projects can get to be about 10 min long to run once coded up.  I'm tired of having to find my position over and over again in my timeline.  I just want to be on the same section of the timeline i'm editing and have greensock read the new css i have without having to restart the timeline.

 

 I'm looking for it to refresh the greensock calculations with the new css file.   I have tried invalidate and restart and that doesn't do at all what i'm looking for since it is forcing me to move my slider bar to the position i was last editing.  (also doesn't read my saved css file at all for some reason)   I just want to stay at the same point on my timeline, without restarting it, and have it take in the updated css info from my file. That way i don't have to move my slider on my timeline to get to the position i was editing in the timeline.   I just want greensock to go rework the positions and styles base on the new css file.  A timeline refresh and recalculate without changing the position i am on in my timeline.

Share this post


Link to post
Share on other sites

Hi,

 

The point is that GSAP reads and stores the starting values of the properties being tweened for performance purposes, therefore if you make a change in the CSS styles without recreating the instances, GSAP won't know about it. That's why my suggestion is to kill() the timeline, then create it again (through a function) and seek to a specific label. You could extend your GSAP project tools by creating buttons that take the timeline to specific labels. All you have to do is retrieve the timeline's labels and their times (the times are unnecessary since you can pass the label name), for this you'll need to use TimelineMax though. YOu can call the getLabelsArray() method, then loop through the labels and create the buttons to either, seek(), play(), pause() to that particular position.

var tl = new TimelineLite()
    tlLabels;

tl
  .to(el1, 1, {vars})
  .add("label1")
  .to(el2, 1, {vars})
  .add("label2")
  .to(el3, 1, {vars})
  .add("label3")
  .to(el4, 1, {vars})
  .add("label4")
  .to(el5, 1, {vars});

//then get the labels
tlLabels = tl.getLabelsArray();

for(var i = 0; i < tlLabels.length; i++)
{
  var button = $("<div />", {id:tlLabels[i].name}).appendTo("#buttonContainer");

  button.on("click", function()
  {
    tl.pause(tlLabels[i].name);
  });
}

Like that, you can create the timeline again, after updating the CSS and then jump to the needed label later.

  • Like 1

Share this post


Link to post
Share on other sites

To add to Rodrigos excellent advice.. if you are using to() tweens? .. what about using a fromTo() tween? ..  so this way you can control the initial from and to CSS values. Then when you insert the new style tag in the DOM, you can then do your checks to get the new CSS value , store it in a variable, and then apply it to your fromTo() vars object. So when the tween runs, it will run with the new values you feed to GSAP like Rodrigo had suggested :)

Share this post


Link to post
Share on other sites

I have tried invalidate and restart and that doesn't do at all what i'm looking for since it is forcing me to move my slider bar to the position i was last editing.

 

invalidate() should be exactly what you need here, so I'm confused why you say it's not working. Are you waiting for the new CSS file to be downloaded before invalidate()ing the timeline? Calling myMasterTimeline.invalidate() will invalidate all initialisation values it recorded in any child timelines and tweens, so it can pick up any updated styles.

 

Are you just worried that you have to move your slider bar afterwards? Seems like you could just record the current time before invalidating then restore it e.g.

var restore = timeline.time();
timeline.restart().invalidate().time(restore);
  • Like 1

Share this post


Link to post
Share on other sites

I have an addition to the previous excellent advice.

 

invalidate() only clears out the recorded values in the TimelineLite/Max object. It does not remove inline styling that has been set on the targets of the tween in the timeline.

 

So even after you invalidate(), your DOM elements will have inline still have inline styles applied which can certainly mess up the starting values in to() tweens the next time the timeline is run or the ending values in from() tweens. 

 

So in addition to invalidating the timeline you also will probably need to run a bunch of set()s that the clear the inline styles like

TweenLite.set(elementA, {clearProps:"all"});
TweenLite.set(elementB, {clearProps:"all"});

Perhaps there is a jQuery selector that will select all nested children recursively of a DOM element so you can blast out the styles in a single blow.

 

- note setting timeline.progress(0) will rewind to() tweens to their pre-tweened states, but will not remove the inline styles.

- in order to get from() tweens to there pre-tweened states you could set timeline.progress(1) but again they will still retain their inline styles.

Share this post


Link to post
Share on other sites

Thanks for this additional advice and i will try some of this out today at work.   I'll let you know if this works for me. Thanks again!

Share this post


Link to post
Share on other sites

Ok, i have tried these and they don't work for me.   I can get it to clear the inline css, but it doesn't read the css correctly after i hit my refresh button.  Does not like the .from i'm using and it set's the inline style not to where it should be after the animation is suppose to happen.  (it's setting it to the inline style to the starting position, but not the ending position it should be)  It's also forcing it to stay display none and opacity 0.   I have been able to create a quick code pen to show you these issues.   I can get it to read the new css, but it doesn't take those values and apply them correctly to the invalidated restarted timeline.  I could be missing something simple, but i'm not sure what my issue is.  

 

http://codepen.io/anon/pen/nwfxs

 

So I have a simple timeline set up.   I have it set to auto play right away with a pause in the timeline.  When it pause go click the refresh button.   You will see that it does clear the inline css style, but then it give's me just the starting position ( i guess) but doesn't give me the correct end position.  Also the display none and opacity are back to what is in the .from i have set.  It doesn't seem like it's reading the timeline to run the animation to the end point. So am i going about this all wrong?   

Share this post


Link to post
Share on other sites

Ok I was scratching my head for a bit on this one, but it seems to be working pretty well with this setup http://codepen.io/jamiejefferson/pen/hEusH?editors=001. I modified all the classes and things just so I could get my head around it, but it should be basically the same.

 

There's still some edge cases that cause weirdness (e.g. run the pen and then press refresh twice) and it seems to work better without lazy rendering, but for the most part you can click refresh as much as you want and it will invalidate the timeline then restore the last position without breaking. Hopefully one of the masters can shed some light on what's going on here.

Share this post


Link to post
Share on other sites

Thanks for doing the leg work on this, Jamie. Nice solution. 

Frankly I'm stumped about the lazy setting in this context.

I'll have to kick this one to the guy on the top floor. 

Share this post


Link to post
Share on other sites

There were indeed a few tweaks that were necessary under the hood. Sorry about that. I think I've got them worked out, and I have attached a preview of the upcoming 1.13.2 release. Would you mind taking a peek and making sure everything works for you as expected? Thanks gentlemen. 

 

[zip updated 2014-08-19]

GSAP_1.13.2_preview2.zip

  • Like 1

Share this post


Link to post
Share on other sites

I dropped the latest 1.13.2 into a fork of Jamie's example and it is holding up quite well.

http://codepen.io/GreenSock/full/uhKAH/

 

I can hit refresh at any time and the timeline invalidates and seeks to the restore time without any visual glitches.

 

Will test it in a some more scenarios. If anyone else can hammer on it bit that would be helpful too!

 

TopGun,

please let us know if this works for you.

 

Thx!

Share this post


Link to post
Share on other sites

When I made the demo I found I had to set progress to 1, and it would only reset properly if I used seek, and not restart or time.

 

With this update it's definitely working well now, and also works with the following 'refresh' function (similar to the original suggestion)

 

var restore = tl.time();
var paused = tl.paused();

// clear all styles so that new values can be computed from the stylesheet only
TweenMax.set("#textbox1, #textbox2", {clearProps:"all" });

tl.invalidate()   // clear timeline values
  .restart()      // set time to start so that initial values can be recorded
  .time(restore)  // set time to same position as before
  .pause(paused); // restore the previous paused state
  • Like 2

Share this post


Link to post
Share on other sites

Thanks, Jamie. Great to hear.

 

Also, for the record, I tested both lazy:false and lazy:true without any fail. 

  • Like 2

Share this post


Link to post
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.