Jump to content
Search Community

Bug: Timeline getting paused() at the position of an addPause()

RolandSoos test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

While debugging my code I used the timeline.paused() method without parameters to get if the timeline paused or not. I have strange results when the playhead was paused at the exact position of an addPause callback, so I checked GSAP source code and I think I found the cause.

 

Timeline

p.paused = function (value) {
  if (!value) { //if there's a pause directly at the spot from where we're unpausing, skip it.
    var tween = this._first,
        time = this._time;
    while (tween) {
      if (tween._startTime === time && tween.data === "isPause") {
        tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire.
      }
      tween = tween._next;
    }
  }
  return Animation.prototype.paused.apply(this, arguments);
};

 

Animation

    p.paused = function (value) {
        if (!arguments.length) {
            return this._paused;
        }
        var tl = this._timeline,
            raw, elapsed;
        if (value != this._paused) if (tl) {
            if (!_tickerActive && !value) {
                _ticker.wake();
            }
            raw = tl.rawTime();
            var raw2 = raw;
            elapsed = raw - this._pauseTime;
            if (!value && tl.smoothChildTiming) {
                if (this._totalDuration === 3.203) {
                    //console.log('elapsed', raw, this._pauseTime);
                    console.error('new start time', this._startTime, 'Ez OK:',this._pauseTime);
                }
                this._startTime += elapsed;
                this._uncache(false);
            }
            this._pauseTime = value ? raw : null;
            this._paused = value;
            this._active = this.isActive();
            if (!value && elapsed !== 0 && this._initted && this.duration()) {
                raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale;
                if (this._totalDuration === 3.203) {
                    console.log('start1', this._startTime, 'ticker time', raw2, 'Raw = _totalTime', raw,);
                    window.abcd = true;
                }
                this.render(raw, (raw === this._totalTime), true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render.
            }
        }
        if (this._gc && !value) {
            this._enabled(true, false);
        }
        return this;
    };

When I call timeline.paused() without arguments, the value will be undefined, which evaluates as false, so it goes into the if statement. Your comment says: //if there's a pause directly at the spot from where we're unpausing, skip it.

So based on the comment, it should run when it is called with value:false.

 

So probably it should be:

Timeline

p.paused = function (value) {
  if (arguments.length && !value) { //if there's a pause directly at the spot from where we're unpausing, skip it.
    var tween = this._first,
        time = this._time;
    while (tween) {
      if (tween._startTime === time && tween.data === "isPause") {
        tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire.
      }
      tween = tween._next;
    }
  }
  return Animation.prototype.paused.apply(this, arguments);
};

 

 

Ps.: Sorry, I currently do not have time to create a CodePen which illustrates the bug I had.

Link to comment
Share on other sites

There might be one other change needed, but I'm not sure. Checking if the value not equal with the current _paused property.

 

Timeline

p.paused = function (value) {
  if (arguments.length && !value && value != this._paused) { //if there's a pause directly at the spot from where we're unpausing, skip it.
    var tween = this._first,
        time = this._time;
    while (tween) {
      if (tween._startTime === time && tween.data === "isPause") {
        tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire.
      }
      tween = tween._next;
    }
  }
  return Animation.prototype.paused.apply(this, arguments);
};

 

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