diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..79ba7a8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,25 @@ +# EditorConfig is awesome: http://EditorConfig.org +# Download a plugin for your favorite editor from http://editorconfig.org/#download + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true + +[*.{html}] +insert_final_newline = true +indent_style = tab + +[*.js] +insert_final_newline = true +indent_style = tab + +[*.json] +insert_final_newline = false +indent_style = tab + +[package.json] +indent_style = space +indent_size = 2 diff --git a/build/tina.js b/build/tina.js index 0dbd8f8..1c5561a 100644 --- a/build/tina.js +++ b/build/tina.js @@ -464,20 +464,21 @@ BriefExtension.prototype._moveTo = function (time, dt, playerOverflow) { } }; },{}],3:[function(require,module,exports){ -var inherit = require('./inherit'); -var Playable = require('./Playable'); -var BriefExtension = require('./BriefExtension'); - -function BriefPlayable() { - Playable.call(this); - BriefExtension.call(this); -} - -BriefPlayable.prototype = Object.create(Playable.prototype); -BriefPlayable.prototype.constructor = BriefPlayable; -inherit(BriefPlayable, BriefExtension); - +var inherit = require('./inherit'); +var Playable = require('./Playable'); +var BriefExtension = require('./BriefExtension'); + +function BriefPlayable() { + Playable.call(this); + BriefExtension.call(this); +} + +BriefPlayable.prototype = Object.create(Playable.prototype); +BriefPlayable.prototype.constructor = BriefPlayable; +inherit(BriefPlayable, BriefExtension); + module.exports = BriefPlayable; + },{"./BriefExtension":2,"./Playable":8,"./inherit":22}],4:[function(require,module,exports){ var inherit = require('./inherit'); var Player = require('./Player'); @@ -984,249 +985,250 @@ NestedTween.prototype._update = function () { } }; },{"./AbstractTween":1,"./BriefPlayable":3}],8:[function(require,module,exports){ -/** @class */ -function Playable() { - // Player component handling this playable - this._player = null; - - // Handle of the playable within its player - this._handle = null; - - // An inactive playable cannot run even within its time boundaries when its parent is running - this._active = true; - - // Starting time, is global (relative to its player time) - this._startTime = 0; - - // Current time, is local (relative to starting time) - // i.e this._time === 0 implies this._player._time === this._startTime - this._time = 0; - - // Playing speed of the playable - this._speed = 1; - - // Callbacks - this._onStart = null; - this._onPause = null; - this._onResume = null; - this._onUpdate = null; - this._onStop = null; -} - -module.exports = Playable; - -Object.defineProperty(Playable.prototype, 'speed', { - get: function () { return this._speed; }, - set: function (speed) { - this.setSpeed(speed); - } -}); - -Object.defineProperty(Playable.prototype, 'time', { - get: function () { return this._time; }, - set: function (time) { - this.goTo(time); - } -}); - -Playable.prototype.onStart = function (onStart) { this._onStart = onStart; return this; }; -Playable.prototype.onUpdate = function (onUpdate) { this._onUpdate = onUpdate; return this; }; -Playable.prototype.onStop = function (onStop) { this._onStop = onStop; return this; }; -Playable.prototype.onPause = function (onPause) { this._onPause = onPause; return this; }; -Playable.prototype.onResume = function (onResume) { this._onResume = onResume; return this; }; - -Playable.prototype.tweener = function (tweener) { - if (tweener === null || tweener === undefined) { - console.warn('[Playable.tweener] Given tweener is invalid:', tweener); - return this; - } - - this._player = tweener; - return this; -}; - -Playable.prototype.setSpeed = function (speed) { - if (speed < 0) { - console.warn('[Playable.speed] This playable cannot have negative speed'); - return; - } - - if (speed === 0) { - if (this._speed !== 0) { - // Setting timeStart as if new speed was 1 - this._startTime += this._time / this._speed - this._time; - } - } else { - if (this._speed === 0) { - // If current speed is 0, - // it corresponds to a virtual speed of 1 - // when it comes to determing where the starting time is - this._startTime += this._time - this._time / speed; - } else { - this._startTime += this._time / this._speed - this._time / speed; - } - } - - this._speed = speed; - if (this._player !== null) { - this._player._onPlayableChanged(this); - } -}; - -Playable.prototype.goTo = function (timePosition, iteration) { - if (this._iterations === 1) { - if(this._speed === 0) { - // Speed is virtually 1 - this._startTime += this._time - timePosition; - } else { - // Offsetting starting time with respect to current time and speed - this._startTime += (this._time - timePosition) / this._speed; - } - } else { - iteration = iteration || 0; - if(this._speed === 0) { - // Speed is virtually 1 - this._startTime += this._time - timePosition - iteration * this._duration; - } else { - // Offsetting starting time with respect to current time and speed - this._startTime += (this._time - timePosition - iteration * this._duration) / this._speed; - } - } - - this._time = timePosition; - if (this._player !== null) { - this._player._onPlayableChanged(this); - } - return this; -}; - -Playable.prototype.goToBeginning = function () { - return this.goTo(0, 0); -}; - -Playable.prototype.getDuration = function () { - return Infinity; -}; - -Playable.prototype._getEndTime = function () { - return Infinity; -}; - -Playable.prototype._setStartTime = function (startTime) { - this._startTime = startTime; -}; - -Playable.prototype._getStartTime = function () { - return this._startTime; -}; - -Playable.prototype._isWithin = function (time) { - return this._startTime < time; -}; - -Playable.prototype._overlaps = function (time0, time1) { - return (time0 - this._startTime) * (time1 - this._startTime) <= 0; -}; - -Playable.prototype.rewind = function () { - this.goTo(0, 0); - return this; -}; - -Playable.prototype.delay = function (delay) { - return this.start(-delay); -}; - -Playable.prototype.start = function (timeOffset) { - if (this._player === null) { - this._player = TINA._startDefaultTweener(); - } - - if (this._validate() === false) { - // Did not pass validation - return this; - } - - if (timeOffset === undefined || timeOffset === null) { - timeOffset = 0; - } - - this._time = timeOffset; - this._startTime = this._player._time - timeOffset; - - if (this._player._reactivate(this) === false) { - // Could not be added to player - return this; - } - - return this; -}; - -Playable.prototype._start = function () { - if (this._onStart !== null) { - this._onStart(); - } -}; - -Playable.prototype.stop = function () { - if (this._player === null) { - return this; - } - - // Stopping playable without performing any additional update nor completing - if (this._player._remove(this) === false) { - // Could not be removed - return this; - } - - if (this._onStop !== null) { - this._onStop(); - } - return this; -}; - -Playable.prototype.resume = function () { - if (this._player === null || this._player._reactivate(this) === false) { - // Could not be resumed - return this; - } - - // Resetting starting time so that the playable starts off where it left off - this._startTime = this._player._time - (this._time + (this._duration * this._currentIterations)) / this._speed; - - if (this._onResume !== null) { - this._onResume(); - } - return this; -}; - -Playable.prototype.pause = function () { - if (this._player === null || this._player._inactivate(this) === false) { - // Could not be paused - return this; - } - - if (this._onPause !== null) { - this._onPause(); - } - - return this; -}; - -Playable.prototype._moveTo = function (time, dt) { - dt *= this._speed; - - this._time = (time - this._startTime) * this._speed; - this._update(dt); - - if (this._onUpdate !== null) { - this._onUpdate(this._time, dt); - } -}; - -// Overridable methods -Playable.prototype._update = function () {}; +/** @class */ +function Playable() { + // Player component handling this playable + this._player = null; + + // Handle of the playable within its player + this._handle = null; + + // An inactive playable cannot run even within its time boundaries when its parent is running + this._active = true; + + // Starting time, is global (relative to its player time) + this._startTime = 0; + + // Current time, is local (relative to starting time) + // i.e this._time === 0 implies this._player._time === this._startTime + this._time = 0; + + // Playing speed of the playable + this._speed = 1; + + // Callbacks + this._onStart = null; + this._onPause = null; + this._onResume = null; + this._onUpdate = null; + this._onStop = null; +} + +module.exports = Playable; + +Object.defineProperty(Playable.prototype, 'speed', { + get: function () { return this._speed; }, + set: function (speed) { + this.setSpeed(speed); + } +}); + +Object.defineProperty(Playable.prototype, 'time', { + get: function () { return this._time; }, + set: function (time) { + this.goTo(time); + } +}); + +Playable.prototype.onStart = function (onStart) { this._onStart = onStart; return this; }; +Playable.prototype.onUpdate = function (onUpdate) { this._onUpdate = onUpdate; return this; }; +Playable.prototype.onStop = function (onStop) { this._onStop = onStop; return this; }; +Playable.prototype.onPause = function (onPause) { this._onPause = onPause; return this; }; +Playable.prototype.onResume = function (onResume) { this._onResume = onResume; return this; }; + +Playable.prototype.tweener = function (tweener) { + if (tweener === null || tweener === undefined) { + console.warn('[Playable.tweener] Given tweener is invalid:', tweener); + return this; + } + + this._player = tweener; + return this; +}; + +Playable.prototype.setSpeed = function (speed) { + if (speed < 0) { + console.warn('[Playable.speed] This playable cannot have negative speed'); + return; + } + + if (speed === 0) { + if (this._speed !== 0) { + // Setting timeStart as if new speed was 1 + this._startTime += this._time / this._speed - this._time; + } + } else { + if (this._speed === 0) { + // If current speed is 0, + // it corresponds to a virtual speed of 1 + // when it comes to determing where the starting time is + this._startTime += this._time - this._time / speed; + } else { + this._startTime += this._time / this._speed - this._time / speed; + } + } + + this._speed = speed; + if (this._player !== null) { + this._player._onPlayableChanged(this); + } +}; + +Playable.prototype.goTo = function (timePosition, iteration) { + if (this._iterations === 1) { + if(this._speed === 0) { + // Speed is virtually 1 + this._startTime += this._time - timePosition; + } else { + // Offsetting starting time with respect to current time and speed + this._startTime += (this._time - timePosition) / this._speed; + } + } else { + iteration = iteration || 0; + if(this._speed === 0) { + // Speed is virtually 1 + this._startTime += this._time - timePosition - iteration * this._duration; + } else { + // Offsetting starting time with respect to current time and speed + this._startTime += (this._time - timePosition - iteration * this._duration) / this._speed; + } + } + + this._time = timePosition; + if (this._player !== null) { + this._player._onPlayableChanged(this); + } + return this; +}; + +Playable.prototype.goToBeginning = function () { + return this.goTo(0, 0); +}; + +Playable.prototype.getDuration = function () { + return Infinity; +}; + +Playable.prototype._getEndTime = function () { + return Infinity; +}; + +Playable.prototype._setStartTime = function (startTime) { + this._startTime = startTime; +}; + +Playable.prototype._getStartTime = function () { + return this._startTime; +}; + +Playable.prototype._isWithin = function (time) { + return this._startTime < time; +}; + +Playable.prototype._overlaps = function (time0, time1) { + return (time0 - this._startTime) * (time1 - this._startTime) <= 0; +}; + +Playable.prototype.rewind = function () { + this.goTo(0, 0); + return this; +}; + +Playable.prototype.delay = function (delay) { + return this.start(-delay); +}; + +Playable.prototype.start = function (timeOffset) { + if (this._player === null) { + this._player = TINA._startDefaultTweener(); + } + + if (this._validate() === false) { + // Did not pass validation + return this; + } + + if (timeOffset === undefined || timeOffset === null) { + timeOffset = 0; + } + + this._time = timeOffset; + this._startTime = this._player._time - timeOffset; + + if (this._player._reactivate(this) === false) { + // Could not be added to player + return this; + } + + return this; +}; + +Playable.prototype._start = function () { + if (this._onStart !== null) { + this._onStart(); + } +}; + +Playable.prototype.stop = function () { + if (this._player === null) { + return this; + } + + // Stopping playable without performing any additional update nor completing + if (this._player._remove(this) === false) { + // Could not be removed + return this; + } + + if (this._onStop !== null) { + this._onStop(); + } + return this; +}; + +Playable.prototype.resume = function () { + if (this._player === null || this._player._reactivate(this) === false) { + // Could not be resumed + return this; + } + + // Resetting starting time so that the playable starts off where it left off + this._startTime = this._player._time - (this._time + (this._duration * this._currentIterations)) / this._speed; + + if (this._onResume !== null) { + this._onResume(); + } + return this; +}; + +Playable.prototype.pause = function () { + if (this._player === null || this._player._inactivate(this) === false) { + // Could not be paused + return this; + } + + if (this._onPause !== null) { + this._onPause(); + } + + return this; +}; + +Playable.prototype._moveTo = function (time, dt) { + dt *= this._speed; + + this._time = (time - this._startTime) * this._speed; + this._update(dt); + + if (this._onUpdate !== null) { + this._onUpdate(this._time, dt); + } +}; + +// Overridable methods +Playable.prototype._update = function () {}; Playable.prototype._validate = function () {}; + },{}],9:[function(require,module,exports){ var Playable = require('./Playable'); var DoublyList = require('./DoublyList'); diff --git a/src/BriefPlayable.js b/src/BriefPlayable.js index c7f0769..b59d34f 100644 --- a/src/BriefPlayable.js +++ b/src/BriefPlayable.js @@ -1,14 +1,14 @@ -var inherit = require('./inherit'); -var Playable = require('./Playable'); -var BriefExtension = require('./BriefExtension'); - -function BriefPlayable() { - Playable.call(this); - BriefExtension.call(this); -} - -BriefPlayable.prototype = Object.create(Playable.prototype); -BriefPlayable.prototype.constructor = BriefPlayable; -inherit(BriefPlayable, BriefExtension); - -module.exports = BriefPlayable; \ No newline at end of file +var inherit = require('./inherit'); +var Playable = require('./Playable'); +var BriefExtension = require('./BriefExtension'); + +function BriefPlayable() { + Playable.call(this); + BriefExtension.call(this); +} + +BriefPlayable.prototype = Object.create(Playable.prototype); +BriefPlayable.prototype.constructor = BriefPlayable; +inherit(BriefPlayable, BriefExtension); + +module.exports = BriefPlayable; diff --git a/src/Playable.js b/src/Playable.js index afe41d1..e8ddbe5 100644 --- a/src/Playable.js +++ b/src/Playable.js @@ -1,243 +1,243 @@ -/** @class */ -function Playable() { - // Player component handling this playable - this._player = null; - - // Handle of the playable within its player - this._handle = null; - - // An inactive playable cannot run even within its time boundaries when its parent is running - this._active = true; - - // Starting time, is global (relative to its player time) - this._startTime = 0; - - // Current time, is local (relative to starting time) - // i.e this._time === 0 implies this._player._time === this._startTime - this._time = 0; - - // Playing speed of the playable - this._speed = 1; - - // Callbacks - this._onStart = null; - this._onPause = null; - this._onResume = null; - this._onUpdate = null; - this._onStop = null; -} - -module.exports = Playable; - -Object.defineProperty(Playable.prototype, 'speed', { - get: function () { return this._speed; }, - set: function (speed) { - this.setSpeed(speed); - } -}); - -Object.defineProperty(Playable.prototype, 'time', { - get: function () { return this._time; }, - set: function (time) { - this.goTo(time); - } -}); - -Playable.prototype.onStart = function (onStart) { this._onStart = onStart; return this; }; -Playable.prototype.onUpdate = function (onUpdate) { this._onUpdate = onUpdate; return this; }; -Playable.prototype.onStop = function (onStop) { this._onStop = onStop; return this; }; -Playable.prototype.onPause = function (onPause) { this._onPause = onPause; return this; }; -Playable.prototype.onResume = function (onResume) { this._onResume = onResume; return this; }; - -Playable.prototype.tweener = function (tweener) { - if (tweener === null || tweener === undefined) { - console.warn('[Playable.tweener] Given tweener is invalid:', tweener); - return this; - } - - this._player = tweener; - return this; -}; - -Playable.prototype.setSpeed = function (speed) { - if (speed < 0) { - console.warn('[Playable.speed] This playable cannot have negative speed'); - return; - } - - if (speed === 0) { - if (this._speed !== 0) { - // Setting timeStart as if new speed was 1 - this._startTime += this._time / this._speed - this._time; - } - } else { - if (this._speed === 0) { - // If current speed is 0, - // it corresponds to a virtual speed of 1 - // when it comes to determing where the starting time is - this._startTime += this._time - this._time / speed; - } else { - this._startTime += this._time / this._speed - this._time / speed; - } - } - - this._speed = speed; - if (this._player !== null) { - this._player._onPlayableChanged(this); - } -}; - -Playable.prototype.goTo = function (timePosition, iteration) { - if (this._iterations === 1) { - if(this._speed === 0) { - // Speed is virtually 1 - this._startTime += this._time - timePosition; - } else { - // Offsetting starting time with respect to current time and speed - this._startTime += (this._time - timePosition) / this._speed; - } - } else { - iteration = iteration || 0; - if(this._speed === 0) { - // Speed is virtually 1 - this._startTime += this._time - timePosition - iteration * this._duration; - } else { - // Offsetting starting time with respect to current time and speed - this._startTime += (this._time - timePosition - iteration * this._duration) / this._speed; - } - } - - this._time = timePosition; - if (this._player !== null) { - this._player._onPlayableChanged(this); - } - return this; -}; - -Playable.prototype.goToBeginning = function () { - return this.goTo(0, 0); -}; - -Playable.prototype.getDuration = function () { - return Infinity; -}; - -Playable.prototype._getEndTime = function () { - return Infinity; -}; - -Playable.prototype._setStartTime = function (startTime) { - this._startTime = startTime; -}; - -Playable.prototype._getStartTime = function () { - return this._startTime; -}; - -Playable.prototype._isWithin = function (time) { - return this._startTime < time; -}; - -Playable.prototype._overlaps = function (time0, time1) { - return (time0 - this._startTime) * (time1 - this._startTime) <= 0; -}; - -Playable.prototype.rewind = function () { - this.goTo(0, 0); - return this; -}; - -Playable.prototype.delay = function (delay) { - return this.start(-delay); -}; - -Playable.prototype.start = function (timeOffset) { - if (this._player === null) { - this._player = TINA._startDefaultTweener(); - } - - if (this._validate() === false) { - // Did not pass validation - return this; - } - - if (timeOffset === undefined || timeOffset === null) { - timeOffset = 0; - } - - this._time = timeOffset; - this._startTime = this._player._time - timeOffset; - - if (this._player._reactivate(this) === false) { - // Could not be added to player - return this; - } - - return this; -}; - -Playable.prototype._start = function () { - if (this._onStart !== null) { - this._onStart(); - } -}; - -Playable.prototype.stop = function () { - if (this._player === null) { - return this; - } - - // Stopping playable without performing any additional update nor completing - if (this._player._remove(this) === false) { - // Could not be removed - return this; - } - - if (this._onStop !== null) { - this._onStop(); - } - return this; -}; - -Playable.prototype.resume = function () { - if (this._player === null || this._player._reactivate(this) === false) { - // Could not be resumed - return this; - } - - // Resetting starting time so that the playable starts off where it left off - this._startTime = this._player._time - (this._time + (this._duration * this._currentIterations)) / this._speed; - - if (this._onResume !== null) { - this._onResume(); - } - return this; -}; - -Playable.prototype.pause = function () { - if (this._player === null || this._player._inactivate(this) === false) { - // Could not be paused - return this; - } - - if (this._onPause !== null) { - this._onPause(); - } - - return this; -}; - -Playable.prototype._moveTo = function (time, dt) { - dt *= this._speed; - - this._time = (time - this._startTime) * this._speed; - this._update(dt); - - if (this._onUpdate !== null) { - this._onUpdate(this._time, dt); - } -}; - -// Overridable methods -Playable.prototype._update = function () {}; -Playable.prototype._validate = function () {}; \ No newline at end of file +/** @class */ +function Playable() { + // Player component handling this playable + this._player = null; + + // Handle of the playable within its player + this._handle = null; + + // An inactive playable cannot run even within its time boundaries when its parent is running + this._active = true; + + // Starting time, is global (relative to its player time) + this._startTime = 0; + + // Current time, is local (relative to starting time) + // i.e this._time === 0 implies this._player._time === this._startTime + this._time = 0; + + // Playing speed of the playable + this._speed = 1; + + // Callbacks + this._onStart = null; + this._onPause = null; + this._onResume = null; + this._onUpdate = null; + this._onStop = null; +} + +module.exports = Playable; + +Object.defineProperty(Playable.prototype, 'speed', { + get: function () { return this._speed; }, + set: function (speed) { + this.setSpeed(speed); + } +}); + +Object.defineProperty(Playable.prototype, 'time', { + get: function () { return this._time; }, + set: function (time) { + this.goTo(time); + } +}); + +Playable.prototype.onStart = function (onStart) { this._onStart = onStart; return this; }; +Playable.prototype.onUpdate = function (onUpdate) { this._onUpdate = onUpdate; return this; }; +Playable.prototype.onStop = function (onStop) { this._onStop = onStop; return this; }; +Playable.prototype.onPause = function (onPause) { this._onPause = onPause; return this; }; +Playable.prototype.onResume = function (onResume) { this._onResume = onResume; return this; }; + +Playable.prototype.tweener = function (tweener) { + if (tweener === null || tweener === undefined) { + console.warn('[Playable.tweener] Given tweener is invalid:', tweener); + return this; + } + + this._player = tweener; + return this; +}; + +Playable.prototype.setSpeed = function (speed) { + if (speed < 0) { + console.warn('[Playable.speed] This playable cannot have negative speed'); + return; + } + + if (speed === 0) { + if (this._speed !== 0) { + // Setting timeStart as if new speed was 1 + this._startTime += this._time / this._speed - this._time; + } + } else { + if (this._speed === 0) { + // If current speed is 0, + // it corresponds to a virtual speed of 1 + // when it comes to determing where the starting time is + this._startTime += this._time - this._time / speed; + } else { + this._startTime += this._time / this._speed - this._time / speed; + } + } + + this._speed = speed; + if (this._player !== null) { + this._player._onPlayableChanged(this); + } +}; + +Playable.prototype.goTo = function (timePosition, iteration) { + if (this._iterations === 1) { + if(this._speed === 0) { + // Speed is virtually 1 + this._startTime += this._time - timePosition; + } else { + // Offsetting starting time with respect to current time and speed + this._startTime += (this._time - timePosition) / this._speed; + } + } else { + iteration = iteration || 0; + if(this._speed === 0) { + // Speed is virtually 1 + this._startTime += this._time - timePosition - iteration * this._duration; + } else { + // Offsetting starting time with respect to current time and speed + this._startTime += (this._time - timePosition - iteration * this._duration) / this._speed; + } + } + + this._time = timePosition; + if (this._player !== null) { + this._player._onPlayableChanged(this); + } + return this; +}; + +Playable.prototype.goToBeginning = function () { + return this.goTo(0, 0); +}; + +Playable.prototype.getDuration = function () { + return Infinity; +}; + +Playable.prototype._getEndTime = function () { + return Infinity; +}; + +Playable.prototype._setStartTime = function (startTime) { + this._startTime = startTime; +}; + +Playable.prototype._getStartTime = function () { + return this._startTime; +}; + +Playable.prototype._isWithin = function (time) { + return this._startTime < time; +}; + +Playable.prototype._overlaps = function (time0, time1) { + return (time0 - this._startTime) * (time1 - this._startTime) <= 0; +}; + +Playable.prototype.rewind = function () { + this.goTo(0, 0); + return this; +}; + +Playable.prototype.delay = function (delay) { + return this.start(-delay); +}; + +Playable.prototype.start = function (timeOffset) { + if (this._player === null) { + this._player = TINA._startDefaultTweener(); + } + + if (this._validate() === false) { + // Did not pass validation + return this; + } + + if (timeOffset === undefined || timeOffset === null) { + timeOffset = 0; + } + + this._time = timeOffset; + this._startTime = this._player._time - timeOffset; + + if (this._player._reactivate(this) === false) { + // Could not be added to player + return this; + } + + return this; +}; + +Playable.prototype._start = function () { + if (this._onStart !== null) { + this._onStart(); + } +}; + +Playable.prototype.stop = function () { + if (this._player === null) { + return this; + } + + // Stopping playable without performing any additional update nor completing + if (this._player._remove(this) === false) { + // Could not be removed + return this; + } + + if (this._onStop !== null) { + this._onStop(); + } + return this; +}; + +Playable.prototype.resume = function () { + if (this._player === null || this._player._reactivate(this) === false) { + // Could not be resumed + return this; + } + + // Resetting starting time so that the playable starts off where it left off + this._startTime = this._player._time - (this._time + (this._duration * this._currentIterations)) / this._speed; + + if (this._onResume !== null) { + this._onResume(); + } + return this; +}; + +Playable.prototype.pause = function () { + if (this._player === null || this._player._inactivate(this) === false) { + // Could not be paused + return this; + } + + if (this._onPause !== null) { + this._onPause(); + } + + return this; +}; + +Playable.prototype._moveTo = function (time, dt) { + dt *= this._speed; + + this._time = (time - this._startTime) * this._speed; + this._update(dt); + + if (this._onUpdate !== null) { + this._onUpdate(this._time, dt); + } +}; + +// Overridable methods +Playable.prototype._update = function () {}; +Playable.prototype._validate = function () {};