Jump to content

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

Completing tween when target value is already reached upon start of animation

Recommended Posts

Depending on the user's interactions, there are times when a new `TweenLite.to()` target property is already reached, but the tween continues the full duration regardless. For instance:

TweenLite.to(el, 5, {opacity: 0, onComplete: () => IMPORTANT STUFF})

Let's say the user interacted with something causing this tween to be called, but the tweened element already has an opacity of 0. I would think the tween would assume it reached it's target value and fire it's `onComplete` callback. But instead it runs through the full duration, which results in what is perceived be a pause in animation. I logged out the values via `onUpdate` and the values are indeed equal.


I can think of a bunch of manual checks as a solution, but this is one of many animations that will run into this problem. Btw, the callbacks need to be fired, so I can't really bypass the tween. Is there a built in mechanism in GSAP to handle this?

Link to comment
Share on other sites

The quickest solution I came up with so far is:

onStart: tween => {
    if (currentOpacity === targetOpacity) {
onStartParams: ['{self}'],

But I'm not sure I should be meddling with the tween within onStart.

Link to comment
Share on other sites

Sorry, the engine doesn't and really can't work like that. 

An onComplete, by design, is fired when a tween has run for its full duration, not when a target value is reached.

Consider an Elastic ease where the target value is met 4 or more times BEFORE the tween is finished:




It would be very strange if an onComplete fired the instant the target value was reached. Same thing with a bounce.


Also developers often rely on the precise timing of an onComplete firing so that they can make certain assumptions about the state of their animations before certain events happen.


Assume you had 2 separate tweens that moved 2 boxes across the screen and you wanted them both to move down after 5 seconds

TweenLite.to(".red", 5, {x:200})
TweenLite.to(".blue", 5, {x:300, onComplete:moveAllDivsDown});

function moveAllDivsDown() {
  TweenLite.to(".red, .blue", 1, {y:200});


It would be very strange if some "outside force" set the ".blue" element to an x of 300 prematurely and then it called that tween's onComplete and forced both elements to move down before 5 seconds had transpired.




I think in your case the best solution is to just have your own checks in place using onUpdate, onStart or whenever necessary.

  • Like 4
Link to comment
Share on other sites

@Carl I see your point about the duration being the completion target and not the property value, specifically in the case of springs/bounces. I'm dealing with user-interruptible tweens/timelines, so it does look like my best bet is within onUpdate/onStart.

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