MCPcopy
hub / github.com/greensock/GSAP / render

Method render

src/gsap-core.js:1537–1700  ·  view source on GitHub ↗
(totalTime, suppressEvents, force)

Source from the content-addressed store, hash-verified

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)));

Callers

nothing calls this directly

Calls 13

totalDurationMethod · 0.95
totalTimeMethod · 0.95
invalidateMethod · 0.95
pauseMethod · 0.80
timeScaleMethod · 0.80
_roundPreciseFunction · 0.70
_animationCycleFunction · 0.70
_callbackFunction · 0.70
_findNextPauseTweenFunction · 0.70
_isRevertWorthyFunction · 0.70
_setEndFunction · 0.70
_removeFromParentFunction · 0.70

Tested by

no test coverage detected