import EventEmitter from 'eventemitter3';
import * as utils from '../utils';
import { arrayRemoveObject, getTime } from '../../../utils';
import Ticker from './Ticker';
const MANUAL_STOP = 'manual stop';
const MANUAL_PAUSE = 'manual pause';
/**
* 一个高精度、高性能的计时器
*
* @example
* var cd1 = new Tiny.ticker.CountDown({
* duration: 5e3,
* times: 3,
* });
* cd1.on('update', function (t) {
* console.log('每五秒打印一次,共打印三次');
* });
* cd1.on('complete', function (t) {
* console.log('Done');
* });
* cd1.start();
*
* @example
* var cd2 = new Tiny.ticker.CountDown({
* duration: 3e3,
* });
* cd2.on('update', function (t) {
* console.log('每三秒打印一次,第' + cd2.count + '次');
* });
* cd2.start();
*
* @version 1.1.7
* @class
* @memberof Tiny.ticker
*/
export default class CountDown extends EventEmitter {
/**
* @param {number} opts.duration - 每次的时间间隔(ms)
* @param {number} opts.times - 共计次数
*/
constructor(opts) {
super();
/**
*
* @member {number}
* @default 1000ms
*/
this.duration = opts.duration || 1e3;
/**
*
* @member {number}
* @default Infinity
*/
this.times = opts.times || Infinity;
/**
* 已计次数
*
* @member {number}
* @default 0
*/
this.count = 0;
utils.CountDownCache.push(this);
/**
* 每间隔 `duration` 触发一次
*
* @example
* var cd = new Tiny.ticker.CountDown();
* cd.on('update', function(){
* console.log('tick');
* });
*
* @event Tiny.ticker.CountDown#update
* @param {number} time
*/
/**
* 如果传入 `times`,则会在计时结束后触发
*
* @event Tiny.ticker.CountDown#complete
* @param {number} time
*/
/**
* 调用 `CountDown.pause()` 后触发
*
* @example
* var cd = new Tiny.ticker.CountDown();
* cd.on('pause', function(){
* console.log('paused');
* });
* cd.pause();
*
* @event Tiny.ticker.CountDown#pause
*/
/**
* 调用 `CountDown.stop()` 后触发
*
* @example
* var cd = new Tiny.ticker.CountDown();
* cd.on('stop', function(){
* console.log('stop');
* });
* cd.stop();
*
* @event Tiny.ticker.CountDown#stop
*/
}
/**
* 开始计时,如果是被暂停的计时器,会从上次暂停点继续
*/
start() {
this._indicate = null;
if (this.count >= this.times) {
return;
}
/**
* 计时器使用的 Ticker 对象
* @member {Tiny.ticker.Ticker}
*/
this.ticker = new Ticker();
this.startTime = getTime();
const tickerHandler = (time) => {
const current = getTime();
if (this.count >= this.times) {
this.ticker.destroy();
this.emit('complete', time);
return;
}
if (current - this.startTime >= this.duration) {
this.startTime = current;
this.count++;
this.emit('update', time);
}
};
this.ticker.add(tickerHandler);
this.ticker.start();
}
/**
* 暂停计时,再次执行 `start` 会从上次暂停点继续
*/
pause(auto) {
this.ticker.destroy();
if (!auto) {
this._indicate = MANUAL_PAUSE;
}
this.emit('pause');
}
/**
* 停止计时
*/
stop(auto) {
this.ticker.destroy();
this.count = 0;
if (!auto) {
this._indicate = MANUAL_STOP;
}
this.emit('stop');
}
// 是否手动暂停
isManualPause() {
return this._indicate === MANUAL_PAUSE;
}
// 是否手动停止
ifManualStop() {
return this._indicate === MANUAL_STOP;
}
/**
* 销毁计时器
*/
destroy() {
this.stop();
arrayRemoveObject(utils.CountDownCache, this);
}
/**
* 计时器是否正在运行
*
* @return {boolean}
* @default false
* @readonly
*/
get running() {
return this.ticker.started;
}
}