UNPKG

minsky-kit

Version:
234 lines (181 loc) 6.03 kB
// imports import EventDispatcher from './EventDispatcher'; // private static properties // class definition export default class Ticker extends EventDispatcher { // constructor constructor (args = {}, objectName = 'Ticker') { // call super super(args, objectName); // set properties this.timeout = (args.timeout) ? processTimeoutArgument(args.timeout) : 0; this.isInterval = args.isInterval || false; this.autoDestroy = (typeof args.autoDestroy === 'boolean') ? args.autoDestroy : false; this.autoStart = (typeof args.autoStart === 'boolean') ? args.autoStart : false; this.data = args.data || {}; this.useTimeout = args.useTimeout || false; this.autoReset = args.autoReset || false; // set system properties this.timerId = 0; this.time = args.time || 0; this.lastTick = 0; // autostart if (args.autoStart) this.start(); // call super initializer super.initialize(args); // autostart if (this.autoStart) this.start(); } // methods start (reset = false) { // reset if required if (reset) this.reset(); // only start when already running if (!this.running) { // request frame and keep id this.id = (this.useTimeout) ? setTimeout(this.tick.bind(this)) : requestAnimationFrame(this.tick.bind(this)); // keep currnet time this.lastTick = performance.now(); // dispatch start event this.dispatch('start'); } } stop (reset = false) { if (this.running) { // cancel animation request (this.useTimeout) ? clearTimeout(this.id) : cancelAnimationFrame(this.id); // reset id this.id = 0; // dispatch stop event this.dispatch('stop'); } // reset time if requested if (reset) this.reset(); } reset (stop = false) { // reset time this.time = 0; // dispatch reset event this.dispatch('reset'); // stop if requested if (this.id && stop) this.stop(); } tick (force) { // cancel if not running // if (!this.dispatch) return; // check if tick is ran after instance is destroyed if (!force && !this.running) return; // get current time const currentTime = performance.now(); let requestTick = true; // update time this.time += currentTime - this.lastTick; // dispatch tick this.dispatch('tick'); // if time passed timout => do stuff if (this.time >= this.timeout) { if (this.isInterval) { this.reset(); this.dispatch('interval', this.data); } else { this.stop(this.autoReset); this.dispatch('timeout', this.data); requestTick = false; if (this.autoDestroy) this.destroy(); } } // request new frame if (requestTick) this.id = requestAnimationFrame(this.tick.bind(this)); // keep current time for next tick this.lastTick = currentTime; } destroy () { // dispatch event this.dispatch('destroy'); // ensure stop this.stop(); // remove all references this.id = this.timeout = this.callback = this.isInterval = this.autoDestroy = this.time = this.lastTick = null; // destroy super super.destroy(); } // getters & setters get running () { return !!this.id; } get progress () { return this.time / this.timeout; } // statics } // argument processor exact copy of v2.2.0's function processTimeoutArgument (str) { if (!Number.isNaN(str)) { return str; } if (str.indexOf(':')) { // hh:mm:ss.msms const parts = str.split(':'); const total = parts.length - 1; return (parseFloat(parts[total]) + (parseInt(parts[total - 1]) * 60) + ((total > 1) ? parseInt(parts[total - 2]) * 3600 : 0)) * 1000; } // css way: 2ms, 2s, 2min, 2h, 2milliseconds, 2seconds, ... return parseFloat(str) * getMsFactorFromString(str); } // time formatting from v2 function getMsFactorFromString (str) { let result; switch (true) { case (str.indexOf('ms') > -1 || str.indexOf('milliseconds') > -1): result = 1; // 1 break; case (str.indexOf('s') > -1 || str.indexOf('seconds') > -1): result = 1000; // 1 * 1000 break; case (str.indexOf('min') > -1 || str.indexOf('minutes') > -1): result = 60000; // 1 * 1000 * 60 break; case (str.indexOf('h') > -1 || str.indexOf('hr') > -1 || str.indexOf('hour') > -1): result = 3600000; // 1 * 1000 * 60 * 60 break; default: } return result; } export function quickTick (...args) { // different formats let timeout; let callback; let isInterval = false; let data; if (typeof args[0] === 'number') { timeout = args.shift(); // shift it } if (typeof args[0] === 'object') { timeout = timeout || 0; data = args[0]; if (typeof args[1] === 'function') callback = args[1]; } else if (typeof args[0] === 'function') { callback = args[0]; data = {}; timeout = timeout || 0; } if (typeof args[1] === 'boolean' || typeof args[2] === 'boolean' || typeof args[3] === 'boolean') { isInterval = true; } // construct const t = new Ticker({ timeout, isInterval, data, }); // change additional properties t.autoDestroy = true; // add listeners t.on(isInterval ? 'interval' : 'timeout', data, callback); // start t.start(true); return t; } Ticker.quick = quickTick;