UNPKG

25.4 kBJavaScriptView Raw
1/*!
2 * VERSION: 2.1.3
3 * DATE: 2019-05-17
4 * UPDATES AND DOCS AT: http://greensock.com
5 *
6 * @license Copyright (c) 2008-2019, GreenSock. All rights reserved.
7 * This work is subject to the terms at http://greensock.com/standard-license or for
8 * Club GreenSock members, the software agreement that was issued with your membership.
9 *
10 * @author: Jack Doyle, jack@greensock.com
11 */
12/* eslint-disable */
13
14import TweenLite, { _gsScope, globals, Ease, Animation } from "./TweenLite.js";
15import TimelineLite from "./TimelineLite.js";
16
17_gsScope._gsDefine("TimelineMax", ["TimelineLite","TweenLite","easing.Ease"], function() {
18
19 var TimelineMax = function(vars) {
20 TimelineLite.call(this, vars);
21 this._repeat = this.vars.repeat || 0;
22 this._repeatDelay = this.vars.repeatDelay || 0;
23 this._cycle = 0;
24 this._yoyo = !!this.vars.yoyo;
25 this._dirty = true;
26 },
27 _tinyNum = 0.00000001,
28 TweenLiteInternals = TweenLite._internals,
29 _lazyTweens = TweenLiteInternals.lazyTweens,
30 _lazyRender = TweenLiteInternals.lazyRender,
31 _globals = _gsScope._gsDefine.globals,
32 _easeNone = new Ease(null, null, 1, 0),
33 p = TimelineMax.prototype = new TimelineLite();
34
35 p.constructor = TimelineMax;
36 p.kill()._gc = false;
37 TimelineMax.version = "2.1.3";
38
39 p.invalidate = function() {
40 this._yoyo = !!this.vars.yoyo;
41 this._repeat = this.vars.repeat || 0;
42 this._repeatDelay = this.vars.repeatDelay || 0;
43 this._uncache(true);
44 return TimelineLite.prototype.invalidate.call(this);
45 };
46
47 p.addCallback = function(callback, position, params, scope) {
48 return this.add( TweenLite.delayedCall(0, callback, params, scope), position);
49 };
50
51 p.removeCallback = function(callback, position) {
52 if (callback) {
53 if (position == null) {
54 this._kill(null, callback);
55 } else {
56 var a = this.getTweensOf(callback, false),
57 i = a.length,
58 time = this._parseTimeOrLabel(position);
59 while (--i > -1) {
60 if (a[i]._startTime === time) {
61 a[i]._enabled(false, false);
62 }
63 }
64 }
65 }
66 return this;
67 };
68
69 p.removePause = function(position) {
70 return this.removeCallback(TimelineLite._internals.pauseCallback, position);
71 };
72
73 p.tweenTo = function(position, vars) {
74 vars = vars || {};
75 var copy = {ease:_easeNone, useFrames:this.usesFrames(), immediateRender:false, lazy:false},
76 Engine = (vars.repeat && _globals.TweenMax) || TweenLite,
77 duration, p, t;
78 for (p in vars) {
79 copy[p] = vars[p];
80 }
81 copy.time = this._parseTimeOrLabel(position);
82 duration = (Math.abs(Number(copy.time) - this._time) / this._timeScale) || 0.001;
83 t = new Engine(this, duration, copy);
84 copy.onStart = function() {
85 t.target.paused(true);
86 if (t.vars.time !== t.target.time() && duration === t.duration() && !t.isFromTo) { //don't make the duration zero - if it's supposed to be zero, don't worry because it's already initting the tween and will complete immediately, effectively making the duration zero anyway. If we make duration zero, the tween won't run at all.
87 t.duration( Math.abs( t.vars.time - t.target.time()) / t.target._timeScale ).render(t.time(), true, true); //render() right away to ensure that things look right, especially in the case of .tweenTo(0).
88 }
89 if (vars.onStart) { //in case the user had an onStart in the vars - we don't want to overwrite it.
90 vars.onStart.apply(vars.onStartScope || vars.callbackScope || t, vars.onStartParams || []); //don't use t._callback("onStart") or it'll point to the copy.onStart and we'll get a recursion error.
91 }
92 };
93 return t;
94 };
95
96 p.tweenFromTo = function(fromPosition, toPosition, vars) {
97 vars = vars || {};
98 fromPosition = this._parseTimeOrLabel(fromPosition);
99 vars.startAt = {onComplete:this.seek, onCompleteParams:[fromPosition], callbackScope:this};
100 vars.immediateRender = (vars.immediateRender !== false);
101 var t = this.tweenTo(toPosition, vars);
102 t.isFromTo = 1; //to ensure we don't mess with the duration in the onStart (we've got the start and end values here, so lock it in)
103 return t.duration((Math.abs( t.vars.time - fromPosition) / this._timeScale) || 0.001);
104 };
105
106 p.render = function(time, suppressEvents, force) {
107 if (this._gc) {
108 this._enabled(true, false);
109 }
110 var self = this,
111 prevTime = self._time,
112 totalDur = (!self._dirty) ? self._totalDuration : self.totalDuration(),
113 dur = self._duration,
114 prevTotalTime = self._totalTime,
115 prevStart = self._startTime,
116 prevTimeScale = self._timeScale,
117 prevRawPrevTime = self._rawPrevTime,
118 prevPaused = self._paused,
119 prevCycle = self._cycle,
120 tween, isComplete, next, callback, internalForce, cycleDuration, pauseTween, curTime, pauseTime;
121 if (prevTime !== self._time) { //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).
122 time += self._time - prevTime;
123 }
124 if (time >= totalDur - _tinyNum && time >= 0) { //to work around occasional floating point math artifacts.
125 if (!self._locked) {
126 self._totalTime = totalDur;
127 self._cycle = self._repeat;
128 }
129 if (!self._reversed) if (!self._hasPausedChild()) {
130 isComplete = true;
131 callback = "onComplete";
132 internalForce = !!self._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
133 if (self._duration === 0) if ((time <= 0 && time >= -_tinyNum) || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time && self._first) {
134 internalForce = true;
135 if (prevRawPrevTime > _tinyNum) {
136 callback = "onReverseComplete";
137 }
138 }
139 }
140 self._rawPrevTime = (self._duration || !suppressEvents || time || self._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, 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. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
141 if (self._yoyo && (self._cycle & 1)) {
142 self._time = time = 0;
143 } else {
144 self._time = dur;
145 time = dur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. We cannot do less then 0.0001 because the same issue can occur when the duration is extremely large like 999999999999 in which case adding 0.00000001, for example, causes it to act like nothing was added.
146 }
147
148 } else if (time < _tinyNum) { //to work around occasional floating point math artifacts, round super small values to 0.
149 if (!self._locked) {
150 self._totalTime = self._cycle = 0;
151 }
152 self._time = 0;
153 if (time > -_tinyNum) {
154 time = 0;
155 }
156 if (prevTime !== 0 || (dur === 0 && prevRawPrevTime !== _tinyNum && (prevRawPrevTime > 0 || (time < 0 && prevRawPrevTime >= 0)) && !self._locked)) { //edge case for checking time < 0 && prevRawPrevTime >= 0: a zero-duration fromTo() tween inside a zero-duration timeline (yeah, very rare)
157 callback = "onReverseComplete";
158 isComplete = self._reversed;
159 }
160 if (time < 0) {
161 self._active = false;
162 if (self._timeline.autoRemoveChildren && self._reversed) {
163 internalForce = isComplete = true;
164 callback = "onReverseComplete";
165 } else if (prevRawPrevTime >= 0 && self._first) { //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
166 internalForce = true;
167 }
168 self._rawPrevTime = time;
169 } else {
170 self._rawPrevTime = (dur || !suppressEvents || time || self._rawPrevTime === time) ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, 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. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
171 if (time === 0 && isComplete) { //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
172 tween = self._first;
173 while (tween && tween._startTime === 0) {
174 if (!tween._duration) {
175 isComplete = false;
176 }
177 tween = tween._next;
178 }
179 }
180 time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
181 if (!self._initted) {
182 internalForce = true;
183 }
184 }
185
186 } else {
187 if (dur === 0 && prevRawPrevTime < 0) { //without this, zero-duration repeating timelines (like with a simple callback nested at the very beginning and a repeatDelay) wouldn't render the first time through.
188 internalForce = true;
189 }
190 self._time = self._rawPrevTime = time;
191 if (!self._locked) {
192 self._totalTime = time;
193 if (self._repeat !== 0) {
194 cycleDuration = dur + self._repeatDelay;
195 self._cycle = (self._totalTime / cycleDuration) >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but it gets reported as 0.79999999!)
196 if (self._cycle) if (self._cycle === self._totalTime / cycleDuration && prevTotalTime <= time) {
197 self._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
198 }
199 self._time = self._totalTime - (self._cycle * cycleDuration);
200 if (self._yoyo) if (self._cycle & 1) {
201 self._time = dur - self._time;
202 }
203 if (self._time > dur) {
204 self._time = dur;
205 time = dur + 0.0001; //to avoid occasional floating point rounding error
206 } else if (self._time < 0) {
207 self._time = time = 0;
208 } else {
209 time = self._time;
210 }
211 }
212 }
213 }
214
215 if (self._hasPause && !self._forcingPlayhead && !suppressEvents) {
216 time = self._time;
217 if (time > prevTime || (self._repeat && prevCycle !== self._cycle)) {
218 tween = self._first;
219 while (tween && tween._startTime <= time && !pauseTween) {
220 if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && self._rawPrevTime === 0)) {
221 pauseTween = tween;
222 }
223 tween = tween._next;
224 }
225 } else {
226 tween = self._last;
227 while (tween && tween._startTime >= time && !pauseTween) {
228 if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
229 pauseTween = tween;
230 }
231 tween = tween._prev;
232 }
233 }
234 if (pauseTween) {
235 pauseTime = self._startTime + (self._reversed ? self._duration - pauseTween._startTime : pauseTween._startTime) / self._timeScale;
236 if (pauseTween._startTime < dur) {
237 self._time = self._rawPrevTime = time = pauseTween._startTime;
238 self._totalTime = time + (self._cycle * (self._totalDuration + self._repeatDelay));
239 }
240 }
241 }
242
243 if (self._cycle !== prevCycle) if (!self._locked) {
244 /*
245 make sure children at the end/beginning of the timeline are rendered properly. If, for example,
246 a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
247 would get translated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there
248 could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So
249 we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must
250 ensure that zero-duration tweens at the very beginning or end of the TimelineMax work.
251 */
252 var backwards = (self._yoyo && (prevCycle & 1) !== 0),
253 wrap = (backwards === (self._yoyo && (self._cycle & 1) !== 0)),
254 recTotalTime = self._totalTime,
255 recCycle = self._cycle,
256 recRawPrevTime = self._rawPrevTime,
257 recTime = self._time;
258
259 self._totalTime = prevCycle * dur;
260 if (self._cycle < prevCycle) {
261 backwards = !backwards;
262 } else {
263 self._totalTime += dur;
264 }
265 self._time = prevTime; //temporarily revert _time so that render() renders the children in the correct order. Without this, tweens won't rewind correctly. We could arhictect things in a "cleaner" way by splitting out the rendering queue into a separate method but for performance reasons, we kept it all inside this method.
266
267 self._rawPrevTime = (dur === 0) ? prevRawPrevTime - 0.0001 : prevRawPrevTime;
268 self._cycle = prevCycle;
269 self._locked = true; //prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render()
270 prevTime = (backwards) ? 0 : dur;
271 self.render(prevTime, suppressEvents, (dur === 0));
272 if (!suppressEvents) if (!self._gc) {
273 if (self.vars.onRepeat) {
274 self._cycle = recCycle; //in case the onRepeat alters the playhead or invalidates(), we shouldn't stay locked or use the previous cycle.
275 self._locked = false;
276 self._callback("onRepeat");
277 }
278 }
279 if (prevTime !== self._time) { //in case there's a callback like onComplete in a nested tween/timeline that changes the playhead position, like via seek(), we should just abort.
280 return;
281 }
282 if (wrap) {
283 self._cycle = prevCycle; //if there's an onRepeat, we reverted this above, so make sure it's set properly again. We also unlocked in that scenario, so reset that too.
284 self._locked = true;
285 prevTime = (backwards) ? dur + 0.0001 : -0.0001;
286 self.render(prevTime, true, false);
287 }
288 self._locked = false;
289 if (self._paused && !prevPaused) { //if the render() triggered callback that paused this timeline, we should abort (very rare, but possible)
290 return;
291 }
292 self._time = recTime;
293 self._totalTime = recTotalTime;
294 self._cycle = recCycle;
295 self._rawPrevTime = recRawPrevTime;
296 }
297
298 if ((self._time === prevTime || !self._first) && !force && !internalForce && !pauseTween) {
299 if (prevTotalTime !== self._totalTime) if (self._onUpdate) if (!suppressEvents) { //so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
300 self._callback("onUpdate");
301 }
302 return;
303 } else if (!self._initted) {
304 self._initted = true;
305 }
306
307 if (!self._active) if (!self._paused && self._totalTime !== prevTotalTime && time > 0) {
308 self._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
309 }
310
311 if (prevTotalTime === 0) if (self.vars.onStart) if (self._totalTime !== 0 || !self._totalDuration) if (!suppressEvents) {
312 self._callback("onStart");
313 }
314
315 curTime = self._time;
316 if (curTime >= prevTime) {
317 tween = self._first;
318 while (tween) {
319 next = tween._next; //record it here because the value could change after rendering...
320 if (curTime !== self._time || (self._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
321 break;
322 } else if (tween._active || (tween._startTime <= self._time && !tween._paused && !tween._gc)) {
323 if (pauseTween === tween) {
324 self.pause();
325 self._pauseTime = pauseTime; //so that when we resume(), it's starting from exactly the right spot (the pause() method uses the rawTime for the parent, but that may be a bit too far ahead)
326 }
327 if (!tween._reversed) {
328 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
329 } else {
330 tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
331 }
332 }
333 tween = next;
334 }
335 } else {
336 tween = self._last;
337 while (tween) {
338 next = tween._prev; //record it here because the value could change after rendering...
339 if (curTime !== self._time || (self._paused && !prevPaused)) { //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
340 break;
341 } else if (tween._active || (tween._startTime <= prevTime && !tween._paused && !tween._gc)) {
342 if (pauseTween === tween) {
343 pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
344 while (pauseTween && pauseTween.endTime() > self._time) {
345 pauseTween.render( (pauseTween._reversed ? pauseTween.totalDuration() - ((time - pauseTween._startTime) * pauseTween._timeScale) : (time - pauseTween._startTime) * pauseTween._timeScale), suppressEvents, force);
346 pauseTween = pauseTween._prev;
347 }
348 pauseTween = null;
349 self.pause();
350 self._pauseTime = pauseTime; //so that when we resume(), it's starting from exactly the right spot (the pause() method uses the rawTime for the parent, but that may be a bit too far ahead)
351 }
352 if (!tween._reversed) {
353 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
354 } else {
355 tween.render(((!tween._dirty) ? tween._totalDuration : tween.totalDuration()) - ((time - tween._startTime) * tween._timeScale), suppressEvents, force);
356 }
357 }
358 tween = next;
359 }
360 }
361
362 if (self._onUpdate) if (!suppressEvents) {
363 if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
364 _lazyRender();
365 }
366 self._callback("onUpdate");
367 }
368 if (callback) if (!self._locked) if (!self._gc) if (prevStart === self._startTime || prevTimeScale !== self._timeScale) if (self._time === 0 || totalDur >= self.totalDuration()) { //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
369 if (isComplete) {
370 if (_lazyTweens.length) { //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
371 _lazyRender();
372 }
373 if (self._timeline.autoRemoveChildren) {
374 self._enabled(false, false);
375 }
376 self._active = false;
377 }
378 if (!suppressEvents && self.vars[callback]) {
379 self._callback(callback);
380 }
381 }
382 };
383
384 p.getActive = function(nested, tweens, timelines) {
385 var a = [],
386 all = this.getChildren(nested || (nested == null), tweens || (nested == null), !!timelines),
387 cnt = 0,
388 l = all.length,
389 i, tween;
390 for (i = 0; i < l; i++) {
391 tween = all[i];
392 if (tween.isActive()) {
393 a[cnt++] = tween;
394 }
395 }
396 return a;
397 };
398
399
400 p.getLabelAfter = function(time) {
401 if (!time) if (time !== 0) { //faster than isNan()
402 time = this._time;
403 }
404 var labels = this.getLabelsArray(),
405 l = labels.length,
406 i;
407 for (i = 0; i < l; i++) {
408 if (labels[i].time > time) {
409 return labels[i].name;
410 }
411 }
412 return null;
413 };
414
415 p.getLabelBefore = function(time) {
416 if (time == null) {
417 time = this._time;
418 }
419 var labels = this.getLabelsArray(),
420 i = labels.length;
421 while (--i > -1) {
422 if (labels[i].time < time) {
423 return labels[i].name;
424 }
425 }
426 return null;
427 };
428
429 p.getLabelsArray = function() {
430 var a = [],
431 cnt = 0,
432 p;
433 for (p in this._labels) {
434 a[cnt++] = {time:this._labels[p], name:p};
435 }
436 a.sort(function(a,b) {
437 return a.time - b.time;
438 });
439 return a;
440 };
441
442 p.invalidate = function() {
443 this._locked = false; //unlock and set cycle in case invalidate() is called from inside an onRepeat
444 return TimelineLite.prototype.invalidate.call(this);
445 };
446
447
448//---- GETTERS / SETTERS -------------------------------------------------------------------------------------------------------
449
450 p.progress = function(value, suppressEvents) {
451 return (!arguments.length) ? (this._time / this.duration()) || 0 : this.totalTime( this.duration() * ((this._yoyo && (this._cycle & 1) !== 0) ? 1 - value : value) + (this._cycle * (this._duration + this._repeatDelay)), suppressEvents);
452 };
453
454 p.totalProgress = function(value, suppressEvents) {
455 return (!arguments.length) ? (this._totalTime / this.totalDuration()) || 0 : this.totalTime( this.totalDuration() * value, suppressEvents);
456 };
457
458 p.totalDuration = function(value) {
459 if (!arguments.length) {
460 if (this._dirty) {
461 TimelineLite.prototype.totalDuration.call(this); //just forces refresh
462 //Instead of Infinity, we use 999999999999 so that we can accommodate reverses.
463 this._totalDuration = (this._repeat === -1) ? 999999999999 : this._duration * (this._repeat + 1) + (this._repeatDelay * this._repeat);
464 }
465 return this._totalDuration;
466 }
467 return (this._repeat === -1 || !value) ? this : this.timeScale( this.totalDuration() / value );
468 };
469
470 p.time = function(value, suppressEvents) {
471 if (!arguments.length) {
472 return this._time;
473 }
474 if (this._dirty) {
475 this.totalDuration();
476 }
477 var duration = this._duration,
478 cycle = this._cycle,
479 cycleDur = cycle * (duration + this._repeatDelay);
480 if (value > duration) {
481 value = duration;
482 }
483 return this.totalTime((this._yoyo && (cycle & 1)) ? duration - value + cycleDur : this._repeat ? value + cycleDur : value, suppressEvents);
484 };
485
486 p.repeat = function(value) {
487 if (!arguments.length) {
488 return this._repeat;
489 }
490 this._repeat = value;
491 return this._uncache(true);
492 };
493
494 p.repeatDelay = function(value) {
495 if (!arguments.length) {
496 return this._repeatDelay;
497 }
498 this._repeatDelay = value;
499 return this._uncache(true);
500 };
501
502 p.yoyo = function(value) {
503 if (!arguments.length) {
504 return this._yoyo;
505 }
506 this._yoyo = value;
507 return this;
508 };
509
510 p.currentLabel = function(value) {
511 if (!arguments.length) {
512 return this.getLabelBefore(this._time + _tinyNum);
513 }
514 return this.seek(value, true);
515 };
516
517 return TimelineMax;
518
519 }, true);
520
521export var TimelineMax = globals.TimelineMax;
522export { TimelineLite, TimelineMax as default };
\No newline at end of file