import Radio from './Radio';
/**
* @class Ticker
* @description Executes callback based on given fps and requestAnimationFrame
* @author Chris Peters
* @requires Radio
*
* @param {Boolean} [start] Whether to start on instantiate. Default is true
* @param {Object} [opts] Options
* @param {Object} [opts.window] window object for testing
* @param {Object} [opts.document] document object for testing
*/
export default class Ticker {
constructor(start = true, opts = {}) {
this._window = opts.window || window;
this._document = opts.document || document;
this._then = Date.now();
this._ticks = 0;
this._update = this._update.bind(this);
if (start) {
this._then = Date.now();
this.start();
}
}
/**
* Calculates whether or not to call {@link Ticker#onTick} based on {@link Ticker#_fps}.
* If the correct amount of time has passed the {@link Ticker#onTick} callback will fire and
* the <code>tick</code> event will be dispatched via the <code>document</code> object.
*
* @method Ticker#_update
*/
_update() {
const now = Date.now();
const delta = (now - this._then) / 1000;
this._then = now;
this._ticks += 1;
const evtObject = {
delta: delta,
ticks: this._ticks
};
// fire tick events and execute callbacks
this.onPreTick(delta, this._ticks);
Radio.broadcast(this._document, 'pretick', evtObject);
this.onTick(delta, this._ticks);
Radio.broadcast(this._document, 'tick', evtObject);
this.onPostTick(delta, this._ticks);
Radio.broadcast(this._document, 'posttick', evtObject);
requestAnimationFrame(this._update);
}
/**
* A callback executed pre each tick.
*
* @method Ticker#onPreTick
* @param {Integer} delta The time elapsed between ticks.
* Multiply against gameplay elements for consistent
* movement.
* @param {Integer} ticks The amount of ticks that have accumulated
*/
onPreTick() {}
/**
* A callback executed on each tick.
*
* @method Ticker#onTick
* @param {Integer} delta The time elapsed between ticks.
* Multiply against gameplay elements for consistent
* movement.
* @param {Integer} ticks The amount of ticks that have accumulated
*/
onTick() {}
/**
* A callback executed post tick.
*
* @method Ticker#onPostTick
* @param {Integer} delta The time elapsed between ticks.
* Multiply against gameplay elements for consistent
* movement.
* @param {Integer} ticks The amount of ticks that have accumulated
*/
onPostTick() {}
/**
* Starts the ticker
*
* @method Ticker#start
*/
start() {
this._then = Date.now();
requestAnimationFrame(this._update);
}
}