Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
mattlabworks

Can't restart timelines (main or set via variables) gsap 3

Recommended Posts

Hi there! 

I have a question about how timelines are managed in GSAP 3.
While a timeline's animation is running, in the js console I seem to be able to use:

 

gsap.globalTimeline.restart();

If the animation has finished it ignores the restart completely.
I can only get it to restart if call it while it's running.

The project is a game, this is a particular scene, where I will need to restart the timeline and set a different player (between 1 and 4).
Also as we're looking to use VUE.js as a single page application I expect will need a master timeline per scene.
It's a bit complicated and a client/work related so I can't post it on codepen.
If I can get this working and convince the team to use it then definitely interested in becoming a green sock member.
There's nothing as powerful as GSAP for timeline management so definitely need to get this working. :)

It's also worth mentioning during the script I can log the variables for the timelines I've created (tl) when the script runs, but not after it's finished running.


Please ignore primarily what the animations are doing - as they're working well (it's a responsive scene of a player jumping over a bar then crying when they lose lol). It's mostly just being able to reset / rewind etc the main timeline and each other individual ones. As I can't seem to get either to work.
 

    $(document).ready(function () {
      var pCurrentPlayerNumber = 1;
      var currentplayer = ".player" + pCurrentPlayerNumber;
      var currentplayerwrapper = ".player" + pCurrentPlayerNumber + "-wrapper";
      console.log(currentplayer);
      console.log(currentplayerwrapper);

 

      var tlSetStage = gsap.timeline();
      tlSetStage.set(currentplayer, {className: "+=visible"})
      .set(currentplayerwrapper, {className: "+=centercenter"})
      .set(".currentplayername", {className: "+=p" + pCurrentPlayerNumber + "-bg"})
      .set(currentplayerwrapper, {transform: "translateZ(200px)"})
      .set(".highjump-set.fg", {transform: "translateZ(400px)"})
      .set(".highjump-set", {className: "+=centercenter"})
      .set(".highjump-set", {xPercent: 300});


      var tl = gsap.timeline();
      tl.set(currentplayerwrapper, {xPercent: -300, yPercent:-50})
      .set(".highjump-set", {xPercent: 300})
      .set(currentplayer, {className: "+=stancePlayerRunFast"})
      .to(currentplayerwrapper, {xPercent: "+=200", yPercent:-50, duration: 1, delay:1})
      .to(".highjump-set", {xPercent: "-=280", yPercent:-50, duration: 1, delay:0},1)
      .set(currentplayer, {className: "-=stancePlayerRunFast"})
      .set(currentplayer, {className: "+=stancePlayerJump"})
      .to(currentplayerwrapper, {xPercent: "+=50", rotationY:-180, yPercent:-50, duration: 0.5})
      .to(".highjump-set", {xPercent: "-=10", yPercent:-50, duration: 1, delay:0},2)
      .set(currentplayer, {className: "+=aniPlayerPaused"})
      .to(currentplayerwrapper, {xPercent: "+=10", rotationY:-180, yPercent: -80, rotationZ: 50, ease: "power4.Out", duration: 0.5})
      .to(".highjump-set", {xPercent: "-=20", yPercent:-50, duration: 1, delay:0},3)
      .to(".highjump-pole-hoz", {xPercent: "+=70", yPercent:"+=330", duration: 0.5, delay:0},3)
      .to(".highjump-pole-hoz", {yPercent:"-=190", duration: 0.5, delay:0},3.5)
      .to(".highjump-pole-hoz", {xPercent: "+=20", yPercent:"+=220", duration: 0.5, delay:0},4)
      .to(currentplayerwrapper, {xPercent: "+=20", rotationY:-180, yPercent: -20, rotationZ: 100, ease: "power4.Out", duration: 0.5},4)
      .to(".highjump-set", {xPercent: "-=20", yPercent:-50, duration: 1, delay:0},4)
      .to(currentplayerwrapper, {xPercent: "+=20", rotationY:-180, duration: 2})
      .set(currentplayer, {className: "-=stancePlayerJump"})
      .to(currentplayerwrapper, {xPercent: "+=20", rotationY:-180, rotationZ: 0, duration: 0.5})
      .set(currentplayer, {className: "-=aniPlayerPaused"})
      .set(currentplayer, {className: "+=stancePlayerCry"})
      .to(currentplayerwrapper, {rotationY:-180, rotationZ: 0, duration: 2});

      
      
      console.log(tl);

    });


If I try to restart them using the below command I get a not defined error. Should I be doing each timeline as a function?


tl.restart(); or tlSetStage.restart();

Ideally if I can at least just get the master timeline to reset at this stage it would be a win.
Being able to reset individual timelines would also be great.

Any help very much appreciated!

Screenshot 2020-07-21 at 18.54.15.png

Link to post
Share on other sites

Hey Matt and welcome to the GreenSock forums!

 

You can't access your timelines because you created them inside of a function. JavaScript scopes variables to the function that they're created in.

 

To access your timelines outside of the ready function, just initialize the variables beforehand:

var tl;
$(document).ready(function() {
  // Important: Don't have 'var' here
  tl = gsap.timeline();
});
// Now tl is accessible here after the ready function has been ran

By the way, if you are including your custom JS file at the bottom of the <body> (which is best for performance) then you can probably just remove the .ready callback and not have to worry about this.

 

Also note that we don't really recommend using className animations - it's cleaner and you have more control if you just animate elements directly with GSAP :) 

 

Additionally, you can create minimal demos for questions like this without including your assets (as my code above shows). It doesn't even have to resemble your actual project. But the demos can really help us understand what you're really asking about!

  • Like 2
Link to post
Share on other sites

Thanks for the swift reply! And help! Really appreciate it.

Have implemented - We've been moving towards calling / editing timelines in functions. 

I have seen the move from using classNames in GSAP 3 - which I think is a real shame.
The kind of functionality I'm using them for isn't possible in GSAP in the current format the game is in.

There are poses/animations of a whole rigged character (including limbs) that uses limb / clothing / sprite etc replacement based on it's class. Also doing some responsive viewport ui sizing combined with responsive SVG's for the sprites.

GSAP is great at animating the scene and controlling the timeline. But I can't imagine making each character's individual limb animations within GSAP and being able to switch between them in the same way.

When I saw the function had been removed then added as a custom one on the forums it did make me a bit sad. I guess it's becoming more edge cases and it would be difficult to manage the overlap. But removing features like that seems a bit overkill.  But then my html/css is a bit than my js so it's to be expected I'd think that. :) Maybe on the next project I can try doing things in gsap from the ground up. Found it half way through tooling/production.

The new script is running on this kind of basis.
 

      window.tl = gsap.timeline()
      // prepare animation
      function setup() {
        window.tl.set(currentplayer, {className: "+=visible"})
        .set(currentplayerwrapper, {className: "+=centercenter"})
        .set(".currentplayername", {className: "+=p" + pCurrentPlayerNumber + "-bg"})
        // .set(currentplayerwrapper, {transform: "translateZ(200px)"})
        .set(currentplayerwrapper, {xPercent:-300, yPercent:-50});
      }
      function start() {
        window.tl.to(currentplayerwrapper, {xPercent:-150, yPercent:-50});
        // window.tl.set('steps to make character run one question')
      }
      function trip() {
        window.tl.set(currentplayer, {className: "+=stancePlayerTrip"})
        .to(currentplayer, {rotate: -360})
        .set(currentplayer, {className: "-=stancePlayerTrip"});
      }
      function sprint() {
        window.tl.set(currentplayer, {className: "+=aniPlayerCorrect"})
        .to(currentplayerwrapper, {xPercent: "+=20", ease: "power4.Out"})
        .set(currentplayer, {className: "-=aniPlayerCorrect"});
      }
      function finish() {
        window.tl.set(currentplayer, {className: "+=aniPlayerCorrect"})
        .to(currentplayerwrapper, {xPercent:200, ease: "power4.Out"})
        .set(currentplayer, {className: "-=aniPlayerCorrect"});
      }

      setup()
      start()
      sprint()
      sprint()
      sprint()
      sprint()
      sprint()
      trip()
      sprint()
      sprint()
      sprint()
      trip()
      sprint()
      trip()
      sprint()
      finish()

 

(The calls are just examples at mo as there will be 10+ questions) The game logic will handle when to call what/when etc. But we're definitely a step forwards. Now all I've got to do is convert slowly all of animate.css effects into gsap. ;) (may be a slow side project!)
And the textilate effects into the textsplit plugin. lol.

It would be great to have some plugin that had some basic animate effects/presets (other than using the ease tool to just make every one from scratch).

Thanks again, I'm sure I'll be back soon!

Link to post
Share on other sites
10 hours ago, mattlabworks said:

I have seen the move from using classNames in GSAP 3 - which I think is a real shame.

If you ask me, className animations are less explicit, harder to manage, and give you less control over how things are animated. So much less preferable :) 

 

There's an unofficial className plugin if you really want this functionality.

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

 

10 hours ago, mattlabworks said:

There are poses/animations of a whole rigged character (including limbs) that uses limb / clothing / sprite etc replacement based on it's class. Also doing some responsive viewport ui sizing combined with responsive SVG's for the sprites.

All of this sounds possible using a data structure to declare the poses. What advantage does transitioning between them with CSS give you? Doing so just provides less control over how the property is transitioned.

 

10 hours ago, mattlabworks said:

It would be great to have some plugin that had some basic animate effects/presets (other than using the ease tool to just make every one from scratch).

Thanks for the input! It's something on our list of things to consider so you mentioning that you'd enjoy something like it is helpful.

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

×