(totalTime, suppressEvents, force)
| 1535 | } |
| 1536 | |
| 1537 | render(totalTime, suppressEvents, force) { |
| 1538 | let prevTime = this._time, |
| 1539 | tDur = this._dirty ? this.totalDuration() : this._tDur, |
| 1540 | dur = this._dur, |
| 1541 | tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime), // if a paused timeline is resumed (or its _start is updated for another reason...which rounds it), that could result in the playhead shifting a **tiny** amount and a zero-duration child at that spot may get rendered at a different ratio, like its totalTime in render() may be 1e-17 instead of 0, for example. |
| 1542 | crossingStart = (this._zTime < 0) !== (totalTime < 0) && (this._initted || !dur), |
| 1543 | time, child, next, iteration, cycleDuration, prevPaused, pauseTween, timeScale, prevStart, prevIteration, yoyo, isYoyo; |
| 1544 | this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur); |
| 1545 | if (tTime !== this._tTime || force || crossingStart) { |
| 1546 | if (prevTime !== this._time && dur) { //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump). |
| 1547 | tTime += this._time - prevTime; |
| 1548 | totalTime += this._time - prevTime; |
| 1549 | } |
| 1550 | time = tTime; |
| 1551 | prevStart = this._start; |
| 1552 | timeScale = this._ts; |
| 1553 | prevPaused = !timeScale; |
| 1554 | if (crossingStart) { |
| 1555 | dur || (prevTime = this._zTime); |
| 1556 | //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. |
| 1557 | (totalTime || !suppressEvents) && (this._zTime = totalTime); |
| 1558 | } |
| 1559 | if (this._repeat) { //adjust the time for repeats and yoyos |
| 1560 | yoyo = this._yoyo; |
| 1561 | cycleDuration = dur + this._rDelay; |
| 1562 | if (this._repeat < -1 && totalTime < 0) { |
| 1563 | return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); |
| 1564 | } |
| 1565 | time = _roundPrecise(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!) |
| 1566 | if (tTime === tDur) { // the tDur === tTime is for edge cases where there's a lengthy decimal on the duration and it may reach the very end but the time is rendered as not-quite-there (remember, tDur is rounded to 4 decimals whereas dur isn't) |
| 1567 | iteration = this._repeat; |
| 1568 | time = dur; |
| 1569 | } else { |
| 1570 | prevIteration = _roundPrecise(tTime / cycleDuration); // full decimal version of iterations, not the previous iteration (we're reusing prevIteration variable for efficiency) |
| 1571 | iteration = ~~prevIteration; |
| 1572 | if (iteration && iteration === prevIteration) { |
| 1573 | time = dur; |
| 1574 | iteration--; |
| 1575 | } |
| 1576 | time > dur && (time = dur); |
| 1577 | } |
| 1578 | prevIteration = _animationCycle(this._tTime, cycleDuration); |
| 1579 | !prevTime && this._tTime && prevIteration !== iteration && this._tTime - prevIteration * cycleDuration - this._dur <= 0 && (prevIteration = iteration); // edge case - if someone does addPause() at the very beginning of a repeating timeline, that pause is technically at the same spot as the end which causes this._time to get set to 0 when the totalTime would normally place the playhead at the end. See https://gsap.com/forums/topic/23823-closing-nav-animation-not-working-on-ie-and-iphone-6-maybe-other-older-browser/?tab=comments#comment-113005 also, this._tTime - prevIteration * cycleDuration - this._dur <= 0 just checks to make sure it wasn't previously in the "repeatDelay" portion |
| 1580 | if (yoyo && (iteration & 1)) { |
| 1581 | time = dur - time; |
| 1582 | isYoyo = 1; |
| 1583 | } |
| 1584 | /* |
| 1585 | make sure children at the end/beginning of the timeline are rendered properly. If, for example, |
| 1586 | a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which |
| 1587 | would get translated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there |
| 1588 | could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So |
| 1589 | we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must |
| 1590 | ensure that zero-duration tweens at the very beginning or end of the Timeline work. |
| 1591 | */ |
| 1592 | if (iteration !== prevIteration && !this._lock) { |
| 1593 | let rewinding = (yoyo && (prevIteration & 1)), |
| 1594 | doesWrap = (rewinding === (yoyo && (iteration & 1))); |
nothing calls this directly
no test coverage detected