import Component from './Component';
import { isObject, isNumber, callback } from '../Helpers/Functions';
export default class Timer extends Component {
/**
* Create a new `Timer` instance.
*
* @class Timer
* @extends Component
* @param {(Object|Number)} interval - The interval passed as a `Number`,
* or can set the attribute of the class with an object.
*/
constructor(interval) {
super(Object.assign({
count: 0,
handle: null,
started: null,
running: false,
interval: isNumber(interval) ? interval : null,
}, isObject(interval) ? interval : null));
}
/**
* The `elapsed` attribute.
*
* @type {Number}
*/
get elapsed() {
return !this.lastLoop ? 0 : this.lastLoop - (
this.started ? this.started.getTime() : new Date().getTime()
);
}
/**
* The `isRunning` attribute.
*
* @type {boolean}
*/
get isRunning() {
return this.running === true;
}
/**
* The `isStopped` attribute.
*
* @type {boolean}
*/
get isStopped() {
return this.running === false;
}
/**
* Resets the timer.
*
* @param {(Function|undefined)} fn - The interval callback.
* @return {Timer} - The `Timer` instance.
*/
reset(fn) {
this.stop(() => {
this.count = 0;
this.start(() => callback.call(this, fn));
this.emit('reset');
});
return this;
}
/**
* Starts the timer.
*
* @param {Function} fn - The interval callback.
* @return {Timer} - The `Timer` instance.
*/
start(fn) {
this.started = new Date;
this.lastLoop = Date.now();
this.running = true;
this.emit('start');
const loop = () => {
if(Date.now() - this.lastLoop >= this.interval) {
callback.call(this, fn);
this.lastLoop = Date.now();
this.emit('interval');
this.count++;
}
this.handle = window.requestAnimationFrame(loop);
return this;
};
return loop();
}
/**
* Stops the timer.
*
* @param {Function} fn - The stop callback.
* @return {Timer} - The `Timer` instance.
*/
stop(fn) {
if(this.isRunning) {
setTimeout(() => {
window.cancelAnimationFrame(this.handle);
this.running = false;
callback.call(this, fn);
this.emit('stop');
});
}
return this;
}
/**
* Define the name of the class.
*
* @return {string}
*/
static defineName() {
return 'Timer';
}
}