Jump to content
Search Community

Variable timeScale for Nested Timeline?

Creek test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

I've been trying this every possible way, and I can't figure out how to code it correctly?

 

function bodyAni(speed){
  let tl = gsap.timeline(

{ 
  // bodyAni:timeScale(speed)
  // defaults: {
  //   timeScale: speed
  // }
} )

tl.timeScale( speed )

// timeline I'm animating, for instance: 
  
.to("#catfish", { rotate: "random(-5, 5)", yPercent: "random(-5, 5)", xPercent: "random(-5, 5)", repeatRefresh: true, yoyoEase:true, duration: 10, repeat:-1 }, 0)
  
  return tl
}

The last one finally works, but once I call it a couple of times:

 

master

.add(bodyAni(1))

.add(faceAni(start), 0)

.add(pupilAni(1), 0)

.add(faceAni(perturbed), "+=1")

.add(faceAni(quiz), "-=3")

.add(faceAni(normal), "+=2")

.add(faceAni(happy), "+=1")

.add(bodyAni(5))

.add(faceAni(quiz), "+=2")

.add(bodyAni(1))

//followed by other stuff - I'm obviously trying to increase the speed with 
//happy, decrease with sad, keep it normal otherwise. 

Once I switch it to 5, the animation just gets stuck? The happy animation just keeps playing at the 5x speed. The quiz animation never happens.

 

The CodePen doesn't ever speed up - so I have no clue - but guessing I'm "calling" it incorrectly? But the CodePen fails to actually present the same problem. I was doing my best to "isolate" the issue, but... ?

 

See the Pen NWgVaMz by tibbeecode (@tibbeecode) on CodePen

Link to comment
Share on other sites

That's because you put INFINITELY REPEATING animations into each cycle, so you're never actually getting to the 2nd one:

.add(bodyAni(1)) // <- this one has a CRAZY long duration
.add(bodyAni(5), "+=1") // this places the new animation AFTER the end of the previous one (plus 1 second), so basically WAAAAAAAY in the future

Are you trying to just make the animation go 5x faster for a while? 

let tl = bodyAni(1);
// after 1 second, instantly speed up to 5x
gsap.delayedCall(1, () => tl.timeScale(5));
// after 10 seconds (from now), go back to 1x speed
gsap.delayedCall(10, () => tl.timeScale(1));

You can even animate it to the faster/slower speed: 

let tl = bodyAni(1);
// after 1 second, gradually speed up to 5x
gsap.delayedCall(1, () => gsap.to(tl, {timeScale: 5}));
// after 10 seconds (from now), animate back to 1x speed
gsap.delayedCall(10, () => gsap.to(tl, {timeScale: 1}));

I'm not sure that's what you're after, but hopefully something here helps. 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I don't understand code well enough to explain it - but logically

 

There are "expressions" - A, B, C, D, etc. Each are called with their own variable that's an array.

 

Then there's the body with what it's doing. As you related, it's on infinite repeat. 

 

I don't know how to tell the infinitely repeating body - "Hey, I'm calling C - I want you to speed up now. Then slow back down when I call D."

 

There's no set time for when C happens? But when C is called, bodyAni needs to speed up, then slow back down for D.

 

I have NO IDEA how to pull that off. Heck, I was crazy proud of myself for sticking an array in a function ;)

 

But absolutely no clue what it is you're explaining? I know the arrow functions are really cool, but that's about it. They're self-referencing self-enclosed things that forbid the outside world to mess with them?

 

But there's a master timeline. Then there's the nested timelines. No nested nested timelines - so all of the nesters are equals. They held a parade about it. I teared up - it was so amazing...

 

I finally got it working by assigning +=x to the bodyAni calls, followed immediately by < for D, so this actually works:

 

.add(bodyAni(1.5))


.add(faceAni(start), 0)

.add(pupilAni(1), 0)

.add(faceAni(perturbed), "+=1")

.add(faceAni(quiz), "+=3")

.add(faceAni(normal), "+=2")

.add(bodyAni(4), "+=1")

.add(faceAni(happy), "<")

.add(bodyAni(1), "+=2")

.add(faceAni(quiz), "<")

But I'm guessing it's not very good as far as correct programming?

Link to comment
Share on other sites

It looks to me like you may be placing some of the animations waaaay far into the future (you'll never see them) or you might be creating conflicting animations, but I'm not totally sure. I find myself pretty confused as I read through your posts. Perhaps that's because I'm sleep-deprived. Based on how new you are to coding maybe it's best to consider hiring someone to help you accomplish the effects you're after(?)

 

We're happy to answer any GSAP-specific questions you may have but parsing through all your logic and solving other general issues is beyond the scope of help we can offer for free in these forums. 

 

Good luck with the project! I'm glad to hear you made some headway. 🙌 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

The guidance here on GreenSock and from Carl at CCC have been SUPREME!

 

I can promise you that I don't know where GSAP ends and javascript begins. The only reason I'm using javascript is to implement GSAP.

 

But I do try to steer clear of "stuff" like this? I just thought maybe timeScale was special - that I wasn't allowed to call it on nested timelines?

 

As far as hiring someone, I have to learn enough javascript to use GSAP. I look for examples and learn from how you gurus have put things together. I can take a code snippet, learn from it, rearrange it to get the job done.

 

So I am very honestly trying my best to try to keep my questions to GSAP. If I screw up, I'm very sorry?

 

From what little I understand, and I'm probably completely wrong? But I thought GSAP has its own special language that lives within javascript while allowing me to avoid javascript for the most part? So I promise that I don't know where I'm getting outside GSAP and falling into javascript world? But I promise I search and search and do my best to learn on my own before posting here.

 

So is it cool if I post - and if it's off in javascript world beyond GSAP - then the moderators could just delete it or whatnot? Again, I promise I'm already trying to limit myself from posting here as much as possible. Only "brick wall" level stuff where I've been through it for hours and no solution. Mostly because of the possibly wrong concept I have about GSAP requiring GSAP coding and me mixing in javascript at my own peril? So I do my best to avoid doing that?

 

Basically, hopefully obviously the very last thing I would wish to do is further annoy everyone ;)

Link to comment
Share on other sites

Thanks! He is most definitely awesome!


And sorry, I know I'm communicating everything completely wrong ;) If anyone's even interested, I'll try to explain better why it is I can't explain better?

 

Here's the basic situation I've found myself in -


How awesome is GSAP? Pretty awesome. So I'll commit to learning it. I'll use it for my project.


Then... DAMN IT! How do I DO that? Hunt hunt hunt... OH! Cool! That's really awesome! Not really sure WHY that works - but... IT WORKS!!! Sweet!


And so I'm ever deeper into my project. I wish to continue with my project.

 

BUT I obviously need to quit my project and take 4 semesters of javascript, then find out that I really need to learn C to understand javascript, and binary to really understand C?  And THEN, many years later, come back to my project ;) But... screw that, right? FORWARD! This stuff is SO COOL!


And that's how I've ended up annoying everyone.


For instance - "random(1, 3)" - randomly picks a number between 1 and 3. And, even better, repeatRefresh: True, does exactly what's expected - fresh new randoms.


But I think those are special GSAP parameters(?)  I can't just declare let randomNum = random(1, 3). It can't exist outside a .to statement? That's where it "lives"?


So, in the case of my randomly moving fish, I have a left and a right, and they need to be in sync. So I need the SAME random number for each, only reversed. Given that's a very likely scenario, my guess is that I just haven't yet found the GSAP parameter and method for that ;) And look at me, saying words like parameter and method, as if I know what they mean.


But is that a javascript question or is it a GSAP question? I very obviously have NO IDEA. So that's what I mean when I'm relating that - to me, GSAP is its own language? If I find myself "hunting" javascript to solve a problem, I'm most likely screwing up.


And I did take the beginner javascript course that Carl recommended at CCC. The major stumbling block for me seems to be figuring out what these parameter things are and what order and why or if they're coded differently?


GSAP is awesome regardless. But I honestly got into it thinking I didn't have to know that much javascript. Then it turns out that pretty much all of my problems aren't GSAP problems - they're... javascript problems?


Again, just very honestly relating that I am still too ignorant to understand where one begins and the other ends. And whining that the only reason I'm dealing with javascript is to use GSAP. The world just ain't fair ;)


All of this to hopefully better relate - I PROMISE I'm not doing it on purpose.

Link to comment
Share on other sites

26 minutes ago, Creek said:

But I think those are special GSAP parameters(?)  I can't just declare let randomNum = random(1, 3). It can't exist outside a .to statement? That's where it "lives"?

 

You can use the utility function for random values. 

https://greensock.com/docs/v3/GSAP/UtilityMethods/random()

 

34 minutes ago, Creek said:

But is that a javascript question or is it a GSAP question?

 

A JavaScript question would be like "How do I ___ when someone clicks this button?" or "How do I calculate x?"  A GSAP question would be something related to GSAP's API, meaning it would be related to something that GSAP library provides. 

 

 

  • Thanks 1
Link to comment
Share on other sites

var random = gsap.utils.random(-200, 500, 10, true);

AWESOME!!!! And very cool to know about the utility methods! Now I know which stuff can be set through variables?

 

But, on the original topic I posted here, I still don't get why it is that - within a master timeline - I can't just tell it to speed up one of it's nested timelines with timeScale?

 

I honestly still don't get WHY that's a javascript question? The reason *I* thought it was GSAP specific was because I'm trying to specify WHEN the speedup and slowdowns happen within the timeline?

 

And if I set the timeScale as a variable WITHIN the nested timeline, and then call it again from the master - I get a "jank" because it's infinitely repeating. The repeat begins anew (which is logical yeah?) whenever I "call" it "afresh" again.

 

So I'm not asking about a button or setting x - I'm asking how to apply timeScale to a nested timeline from the master timeLine.

 

I have faceAni(happy), with faceAni being the nested expression timeline. And bodyAni with no variables, being the nested random body movement timeline. The two are sisters.

 

Anyhow, when I call faceAni(happy) relatively at "+=2" within the master timeline, then I would like to increase the timeScale of the already running bodyAni nested timeline at that same time, then slow it back down to "normal" again when I call the next expression - for instance, faceAni(normal).

 

But there is no "set time" for when any of these things happen. It would even be BETTER if I could set the timeScale of bodyAni from within it's sister timeline faceAni - but I hopefully "get" that I am most definitely then asking a javascript question? Because javascript has the rules about variable scope that likely prevent the sisters from sharing variables.

 

My HOPE is that timeScale can be applied to a nested timeline from the master timeline and the timing of the "call" can be specified with "<" to match. ie faceAni(happy) at "+=2", immediately followed by bodyAni:timeScale(1.2) at "<".

 

Anyhow, thus is my confuzzlement.

 

And again, THANK YOU SO MUCH for pointing out the utility methods!!!!

Link to comment
Share on other sites

  • Solution

Keeping the questions as succinct as possible would be super helpful. 

 

"how do I change the timeScale of a nested timeline smoothly?" - perfect. Even better if you provide a minimal demo like this: 

 

See the Pen 185ba8fbcc2d66a4891beeba4308142e?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Notice I enabled smoothChildTiming on the master. Why? Let's say the child's startTime is 1 second into the master timeline, but then when the master's playhead hits 3 seconds, we alter timeScale to 5, imagine where that child's endTime is now - if the duration is 15 seconds, that means the endTime was originally at 16 on the master but now that it's 5x faster, the endTime would be at 4 seconds, thus you'd see a jump. smoothChildTiming basically says "when you change a property on a child, like timeScale, automatically shift its startTime so that the playhead stays aligned with wherever it is at that moment." In this example, it'd set the startTime to about 2.6 so that it's smooth. 

 

I hope that helps. 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

6 minutes ago, Creek said:

But the second time I call the same arrow function(?), to return the speed to normal:

 

.add(() => bodyAni.timeScale(1), "<")

 

It's hard to say what's going on without a minimal demo

 

7 minutes ago, Creek said:

And I do understand possibly I'm now presenting a javascript problem? Because I don't know how to "unarrow" a function to understand what it's doing and how I might be screwing up?

 

An arrow function is just a function. Feel free to write like it this.

.add(function() {
  bodyAni.timeScale(1)
}, "<")

 

Don't think in terms of JavaScript vs GSAP problems. Everything is a JavaScript problem as that's the language you are using and what GSAP is written in. We're more than happy help you solve GSAP related issues, but you need to keep the questions focused on one thing at time, and provide a simple demo showing just the issue, kind of like the demo Jack posted with a simple box animation. 

 

See the forums guidelines for the type of questions that don't belong here.

 

Quote

As much as we love solving problems, the following types of questions are beyond the scope of what we generally provide here for free:

  • Logic issues. JavaScript and application logic, CSS setup, and generic troubleshooting that isn’t directly related to GreenSock tools. 
  • Third party tools. Frameworks (React, Angular), other JavaScript libraries (LocomotiveScroll, Barba), build tools, etc. We’re happy to help with the GSAP part of things if you strip out as much irrelevant code as possible and provide a minimal demo.
  • “How do I do this cool effect I saw on a trendy website?” Someone here may point you in the right direction but please don't expect a full tutorial on how to create and effect you saw on a slick web site.

 

14 minutes ago, Creek said:

Possibly unrelated - but in one of Carl's videos, he related that nested timelines can only be called once for whatever reason? 'Cuz they're over and done with once you call them? That's why I set up everything as functions, and then I could call them as many times as I like?

 

Not sure what he meant by that. It was probably specific to something he was doing at the time. You can call whatever you want as many times as you want. If that animation has ended, then changing the timeScale won't do anything.

 

See the Pen 037b2869b6fbc6413f2de5a5104cee3c by GreenSock (@GreenSock) on CodePen

 

20 minutes ago, Creek said:

But if I have bodyAni instead as a function, like in my original here, then it's illegal for me to call bodyAni.timeScale because it's undefined?

 

Again, hard to say without seeing what you did. If you need to reference a timeline, then you're going to have to put it inside a variable first. Every

time you call a function it's creating a new animation.

 

let ani1 = bodyAnim(1.5)
let ani2 = bodyAnim(4)
let ani3 = bodyAnim(1)

master.add(1)
  .add(faceAni(start), 0)
  .add(pupilAni(1), 0)
  .add(faceAni(perturbed), "+=1")
  .add(faceAni(quiz), "+=3")
  .add(faceAni(normal), "+=2")
  .add(ani2, "+=1")
  .add(faceAni(happy), "<")
  .add(ani3, "+=2")
  .add(faceAni(quiz), "<")

 

 

 

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I'm having to do my best to try to work through and digest all of this. I don't wish to not respond given everyone's been so helpful - but it could take me some time to work through it?

 

I just have to delve through my code. Then I hopefully eventually find where it is I screwed up and have my Fred G Sanford "Ya BIG DUMMY!" moment with myself ;) 

Link to comment
Share on other sites

1 minute ago, Creek said:

I just have to delve through my code. Then I hopefully eventually find where it is I screwed up and have my Fred G Sanford "Ya BIG DUMMY!" moment with myself ;) 

 

That's all it takes. Right now it might be confusing, but eventually you will have an AHA! Moment and everything will start clicking. It's happened to all us. 😁

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Just making a note - and it's probably common knowledge not to use GSDevTools on infinite repeats 'cuz it makes no sense to use it 'cuz the timeline is a thousand seconds. Duhr...

 

But once I turned OFF ye olde GSDevTools, everything stopped freaking out? You can see it tripping out here ;) And comment out GSDevTools and happiness returns. Oh, learning (how incredibly ignorant I am) is just SO MUCH FUN!!!! Yeah that's 3 hours of my life I'm never getting back ;)

 

Fred G is just laying into me HARD right now - "Ya BIG DUMMY!!!!!!"

 

See the Pen dyRBRYv by tibbeecode (@tibbeecode) on CodePen

Link to comment
Share on other sites

On 10/5/2021 at 12:21 AM, GreenSock said:

Notice I enabled smoothChildTiming on the master. Why? Let's say the child's startTime is 1 second into the master timeline, but then when the master's playhead hits 3 seconds, we alter timeScale to 5, imagine where that child's endTime is now - if the duration is 15 seconds, that means the endTime was originally at 16 on the master but now that it's 5x faster, the endTime would be at 4 seconds, thus you'd see a jump. smoothChildTiming basically says "when you change a property on a child, like timeScale, automatically shift its startTime so that the playhead stays aligned with wherever it is at that moment." In this example, it'd set the startTime to about 2.6 so that it's smooth. 

 

I hope that helps. 

 

The timeScale function is SO VERY AWESOME!!!

 

The only hiccup now is that I'd prefer to ease into it? The abrupt change can be a bit too jolting?

 

I tried setting a duration and ease, but either I did it wrong or it's just ignoring it? But no javascript error?

 

.add(() => finAni.timeScale(12, {duration: 1, ease: "circ"}), "+=2")

 

The slight changes aren't that noticeable really - but there's a "furious" bit - with the 12x - and it's just too abrupt?

 

See the Pen GREVvXa by tibbeecode (@tibbeecode) on CodePen

Link to comment
Share on other sites

25 minutes ago, Creek said:

The only hiccup now is that I'd prefer to ease into it? The abrupt change can be a bit too jolting?

 

I tried setting a duration and ease, but either I did it wrong or it's just ignoring it? But no javascript error?

 

.add(() => finAni.timeScale(12, {duration: 1, ease: "circ"}), "+=2")

 

 

I already showed you how to do that (scroll up):

// gradually speed up to 12x
.add(() => gsap.to(finAni, {timeScale: 12, duration: 1}), "+=2");
// animate back to 1x speed
.add(() => gsap.to(finAni, {timeScale: 1, duration: 1}), "+=5");

👍

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