Jump to content
Search Community

Changing duration mid repeat

FARIOA test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

I was trying to change how long a tween runs for in a timeline in between the repeats of itself. I couldn't figure out how to, and ended up just breaking it up into separate tweens. Is there a way that I am missing? 

 

pointerTimeline.to(".pointer", { //Bounces back and forth
        duration: time/ (2 * pointerTimeline.repeat()),
        rotation: "-=" + pointerMaxDegree,
        ease: "linear",
        yoyo: true,
        repeat: 3,
    });

^ Me playing around with the repeat

 

This is what I ended up doing.

    pointerTimeline.to(".pointer", { 
        duration: time/ (6),
        rotation: "-=" + 170,
        ease: "linear",
    });
    pointerTimeline.to(".pointer", { 
        duration: time/ (5),
        rotation: "+=" + 170,
        ease: "linear",
    });
    pointerTimeline.to(".pointer", { 
        duration: time/ (4),
        rotation: "-=" + 170,
        ease: "linear",
    });
    pointerTimeline.to(".pointer", { 
        duration: time/ (3),
        rotation: "+=" + 170,
        ease: "linear",
    });
Link to comment
Share on other sites

I'm a bit confused about what you're asking here, @FARIOA. It almost looks like you're expecting the duration to re-calculate every time it repeats? That's not how JavaScript works - duration: time/ (2 * pointerTimeline.repeat()) would evaluate to a specific number and there's nothing that'd cause that chunk of code to re-execute anytime in the future. 

 

There are a bunch of ways to get the effect you're after (if I understand it correctly). 

  1. Use keyframes
  2. Use a CustomWiggle
  3. Create a paused timeline that has your pointer animating its rotation back and forth, equally spaced...but then TWEEN the playhead of that timeline with an ease like "power1.out". 

If you need some help, just provide a minimal demo (like a CodePen) with your attempt so we can fork it and offer a solution. 

Link to comment
Share on other sites

Hi @GreenSock, my apologies for not making a codepen originally. I just wanted to know if there was a specific method or something similar that would do what my code did. Regarding the duration recalculation, I was playing around with stuff to see if gsap would recalculate when the tween repeated. Obviously, I know now that it doesn't. 

After doing a whole lot of research into keyframes and tweening the playheads of timelines, I ended up figuring it out from a very old forum post titled, "The ease can work on timeline whole animation?" . I attached the working codepen at the bottom of this reply to clear up everything.

Thanks a bunch for offering me those solutions, the last one certainly did the trick. 

 

Sidenote: Can you explain why I need the "time: pointerTimeline.duration()," when I tween the timeline?

 

See the Pen bGLmpGX by gstops (@gstops) on CodePen

 

Link to comment
Share on other sites

12 minutes ago, FARIOA said:

Sidenote: Can you explain why I need the "time: pointerTimeline.duration()," when I tween the timeline?

A timeline's "time" is basically describing where its playhead is. So it starts at 0 of course, and then when it plays the "time" would be 1 after 1 second, 2 after 2 seconds, etc. So if you created a 10-second timeline and then you called yourTimeline.time(5) that would make the playhead jump to the 5-second spot. 

 

So the whole concept here is that your timeline is paused (so its playhead doesn't start moving on its own) and then you're using another tween to control its "time" (playhead). In other words, roughly 60 times per second it is setting it to a new value (tweening it). 

 

Obviously you need to tell the tween what to animate that "time" value to. So again, let's say you have a 10-second timeline and its playhead is at 0 (paused). Where would you need to tween its "time" to in order to play the whole timeline? Answer: 10. It's a 10-second timeline, so when its "time" reaches 10, it's done. That's the "duration", hence: 

 

gsap.to(tl, { time: tl.duration() });

 

Which in our example would resolve to: 

gsap.to(tl, { time: 10 })

 

Which animates the playhead to the end. But notice I didn't put any duration in the tween above, and the default duration is 0.5 so it would make that timeline move the playhead all the way to 10 over the course of 0.5 seconds, meaning it would look like it's playing at 20 times the normal speed! This would make it play at normal speed (assuming the playhead is at 0 when we call this): 

gsap.to(tl, {
  time: tl.duration(),
  duration: tl.duration(),
  ease: "none"
});

 

Once you understand the concept, it's super powerful. You're animating another animation, and you can apply an ease across the whole thing. Fun!

 

Does that clear things up? 

Link to comment
Share on other sites

Yep! That's a really interesting concept, and VERY useful now that I know how to pull it off. However, I now have a new issue due to making that change. I have two additional buttons, one that doubles the speed of the timeline, and one that instantly finishes the timeline. (I didn't include these buttons in the earlier codepen because it was minimal). I fixed the one that doubles the speed by doubling the globalTimeline timescale, but I can't figure out how to fix the instant finish button. I added it to the codepen so you can see how it worked previously. 

^^ Possible solution: Using a global variable as a helper, setting the tween to that helper so that I can call seek on the tween. Is there any other solution?

 

 

Once again, thank you for all of your help. I will edit this is if I figure out a fix before someone gets to it. 

 

See the Pen bGLmpGX by gstops (@gstops) on CodePen

Edited by FARIOA
Found a solution
Link to comment
Share on other sites

  • Solution

There are several problems:

  1. .endTime() describes the time on the PARENT timeline when the animation ends, so that's not what you want here. I assume you meant pointerTimeline.duration() because you want to push the playhead to the end...right? 
  2. An easier way to do that is just pointerTimeline.progress(1)
  3. But if you just do that while it's being tweened, it'll seem like it doesn't work (even though it does) because the tween will keep moving the playhead. In other words, maybe the playhead is at 2 (in the middle of being tweened), and you call pointerTimeline.progress(1) which makes it immediately jump to 10 (assuming a 10-second timeline of course)...but on the very next tick the tween sets it right back to something like 2.0474 (whatever...just continuing on in the tween). So it's important that you kill() the tween to prevent that.

Solution: 

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

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