131 lines
3.0 KiB
JavaScript
131 lines
3.0 KiB
JavaScript
(function(w) {
|
|
|
|
/**
|
|
* The main constructor function.
|
|
* @constructor
|
|
* @param {Function} onTick The tick function.
|
|
* @param {Number} interval The tick duration.
|
|
* @returns {Timer} The instance of timer.
|
|
*/
|
|
var Timer = function(onTick, interval) {
|
|
this.setInterval(interval);
|
|
this.setOnTick(onTick);
|
|
|
|
this._timer = null;
|
|
this._active = false;
|
|
|
|
this._startTime = 0;
|
|
};
|
|
|
|
|
|
/**
|
|
* Start the timer.
|
|
* The tick function is called with one argument, the drift amount (int).
|
|
* @returns {Timer} this.
|
|
*/
|
|
Timer.prototype.start = function() {
|
|
|
|
let drift = 0,
|
|
actual = 0,
|
|
ideal = 0,
|
|
counter = 0,
|
|
time = 0,
|
|
that = this,
|
|
now = performance.now;
|
|
|
|
|
|
function onTick() {
|
|
that._onTick(drift);
|
|
|
|
++counter;
|
|
|
|
ideal = that._interval * counter;
|
|
actual = now() - that._startTime;
|
|
drift = actual - ideal;
|
|
time = that._interval - drift;
|
|
|
|
|
|
|
|
if (that._active) setTimeout(onTick, time);
|
|
}
|
|
|
|
that._active = true;
|
|
that._startTime = now();
|
|
that._timer = setTimeout(onTick, that._interval);
|
|
|
|
return this;
|
|
};
|
|
|
|
|
|
/**
|
|
* Stop the timer.
|
|
* @returns {Timer} this.
|
|
*/
|
|
Timer.prototype.stop = function() {
|
|
this._active = false;
|
|
clearTimeout(this._timer);
|
|
return this;
|
|
};
|
|
|
|
|
|
/**
|
|
* Set the tick duration. Can be called whilst timer is running.
|
|
* @param {Number} ms The tick duration.
|
|
* @returns {Timer} this.
|
|
*/
|
|
Timer.prototype.setInterval = function(ms) {
|
|
if(isNaN(ms)) {
|
|
throw new Error('Timer.setInterval requires a number');
|
|
}
|
|
else if(ms < 10) {
|
|
ms = 10;
|
|
}
|
|
|
|
this._interval = ms;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Allow for replacement of the tick function, even whilst the timer
|
|
* is running.
|
|
* @param {Function} onTick The new tick function to be called on each cycle.
|
|
* @returns {Timer} this.
|
|
*/
|
|
Timer.prototype.setOnTick = function(onTick) {
|
|
this._onTick = onTick;
|
|
return this;
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
* Allow the `Timer` constructor to be used as a replacement for
|
|
* setInterval.
|
|
* @param {Function} tick The tick function to call every `interval` ms.
|
|
* @param {Number} interval The tick duration.
|
|
* @returns {Timer} A new instance of the `Timer` constructor.
|
|
*/
|
|
var setTimer = function(tick, interval) {
|
|
var timer = new Timer(tick, interval);
|
|
timer.start();
|
|
return timer;
|
|
};
|
|
|
|
|
|
/**
|
|
* Imitate the clearTimeout method...
|
|
* @param {Timer}
|
|
*/
|
|
var clearTimer = function(timer) {
|
|
timer.stop();
|
|
};
|
|
|
|
|
|
|
|
w.Timer = Timer;
|
|
w.setTimer = setTimer;
|
|
|
|
|
|
|
|
|
|
}(global)); |