@ciri/ngx-countdown
Version:
An angular countdown component.
289 lines • 18.6 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/countdown.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, TemplateRef } from '@angular/core';
import { interval } from 'rxjs';
import { animationFrame } from 'rxjs/internal/scheduler/animationFrame';
import { isSameSecond, parseFormat, parseTimeData } from './utils';
/**
* @record
*/
function CountdownData() { }
if (false) {
/** @type {?} */
CountdownData.prototype.remain;
/** @type {?} */
CountdownData.prototype.formattedTime;
/** @type {?} */
CountdownData.prototype.fragments;
}
/** @enum {number} */
const CountdownState = {
/** 暂停状态 */
paused: 0,
/** 运行状态 */
playing: 1,
/** 完成状态 */
finished: 2,
};
export { CountdownState };
CountdownState[CountdownState.paused] = 'paused';
CountdownState[CountdownState.playing] = 'playing';
CountdownState[CountdownState.finished] = 'finished';
/**
* 所有组件实例使用同一个 interval 流,以免实例多了后造成卡顿
* @type {?}
*/
const instances = [];
/** @type {?} */
const counter$ = interval(0, animationFrame);
/** @type {?} */
let counterSub;
/**
* @return {?}
*/
function setupCounter() {
destroyCounter();
counterSub = counter$.subscribe((/**
* @return {?}
*/
() => {
for (let i = 0; i < instances.length; i++) {
/** @type {?} */
const inst = instances[i];
if (inst.state !== CountdownState.playing) {
continue;
}
if (inst.remain <= 0) {
inst.state = CountdownState.finished;
inst.cdr.detectChanges();
inst.finish.emit();
continue;
}
/** @type {?} */
const remain = Math.max(inst.endTime - Date.now(), 0);
if (!inst.millisecond) {
if (!isSameSecond(remain, inst.remain) || remain === 0) {
inst.remain = remain;
inst.tick.emit(inst.remain);
}
}
else {
inst.remain = remain;
inst.tick.emit(inst.remain);
}
inst.cdr.detectChanges();
}
}));
}
/**
* @return {?}
*/
function destroyCounter() {
counterSub && counterSub.unsubscribe();
}
/**
* 倒计时组件
*/
export class CountdownComponent {
/**
* @param {?} cdr
*/
constructor(cdr) {
this.cdr = cdr;
/**
* 格式
*/
this.format = 'HH:mm:ss';
/**
* 是否自动开始
*/
this.autoStart = true;
/**
* 是否开启毫秒级渲染
*/
this.millisecond = false;
/**
* 倒计时完毕时触发
*/
this.finish = new EventEmitter();
/**
* 每倒计时一次都触发
*/
this.tick = new EventEmitter();
this.state = CountdownState.paused;
this._time = 60000;
}
/**
* 总毫秒数
* @param {?} value
* @return {?}
*/
set time(value) {
this._time = Math.max(value, 0);
this.reset();
}
/**
* @return {?}
*/
get time() {
return this._time;
}
/**
* @return {?}
*/
get data() {
/** @type {?} */
const noMillisecond = this.format.indexOf('S') === -1;
/** @type {?} */
const isPlaying = this.state === CountdownState.playing
// 即使 format 中没有设置毫秒,程序计算时候也会将毫秒计算进去,导致运行时秒数看上去总是小 1
// 此处在渲染时候手动 +1 秒,以追求视觉统一
;
// 即使 format 中没有设置毫秒,程序计算时候也会将毫秒计算进去,导致运行时秒数看上去总是小 1
// 此处在渲染时候手动 +1 秒,以追求视觉统一
/** @type {?} */
const timeData = parseTimeData(this.remain + (noMillisecond && isPlaying ? 1000 : 0));
/** @type {?} */
const formattedTime = parseFormat(this.format, timeData);
return {
formattedTime,
remain: this.remain,
fragments: formattedTime.split(':')
};
}
/**
* @return {?}
*/
ngOnInit() {
instances.push(this);
if (instances.length === 1) {
setupCounter();
}
}
/**
* @return {?}
*/
ngOnDestroy() {
this.pause();
/** @type {?} */
const index = instances.indexOf(this);
if (index !== -1) {
instances.splice(index, 1);
}
if (instances.length === 0) {
destroyCounter();
}
}
/**
* 继续倒计时
* @return {?}
*/
start() {
if (this.state === CountdownState.playing) {
return;
}
if (this.state === CountdownState.finished) {
this.remain = this.time;
}
this.endTime = Date.now() + this.remain;
this.state = CountdownState.playing;
}
/**
* 暂停倒计时
* @return {?}
*/
pause() {
this.state = CountdownState.paused;
}
/**
* 重置倒计时
* @return {?}
*/
reset() {
this.pause();
this.remain = this.time;
this.cdr.detectChanges();
if (this.autoStart) {
this.start();
}
}
}
CountdownComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-countdown',
template: "<ng-container *ngIf=\"!render\">{{ data.formattedTime }}</ng-container>\n<ng-container *ngTemplateOutlet=\"render; context: { $implicit: data }\"></ng-container>\n",
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
/** @nocollapse */
CountdownComponent.ctorParameters = () => [
{ type: ChangeDetectorRef }
];
CountdownComponent.propDecorators = {
format: [{ type: Input }],
autoStart: [{ type: Input }],
millisecond: [{ type: Input }],
render: [{ type: Input }],
time: [{ type: Input }],
finish: [{ type: Output }],
tick: [{ type: Output }]
};
if (false) {
/**
* 格式
* @type {?}
*/
CountdownComponent.prototype.format;
/**
* 是否自动开始
* @type {?}
*/
CountdownComponent.prototype.autoStart;
/**
* 是否开启毫秒级渲染
* @type {?}
*/
CountdownComponent.prototype.millisecond;
/**
* 自定义模版
* @type {?}
*/
CountdownComponent.prototype.render;
/**
* 倒计时完毕时触发
* @type {?}
*/
CountdownComponent.prototype.finish;
/**
* 每倒计时一次都触发
* @type {?}
*/
CountdownComponent.prototype.tick;
/** @type {?} */
CountdownComponent.prototype.state;
/**
* @type {?}
* @private
*/
CountdownComponent.prototype._time;
/**
* 剩余毫秒数
* @type {?}
* @private
*/
CountdownComponent.prototype.remain;
/**
* @type {?}
* @private
*/
CountdownComponent.prototype.endTime;
/**
* @type {?}
* @private
*/
CountdownComponent.prototype.cdr;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY291bnRkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BjaXJpL25neC1jb3VudGRvd24vIiwic291cmNlcyI6WyJsaWIvY291bnRkb3duLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFDTixXQUFXLEVBQ1osTUFBTSxlQUFlLENBQUE7QUFDdEIsT0FBTyxFQUFFLFFBQVEsRUFBZ0IsTUFBTSxNQUFNLENBQUE7QUFDN0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdDQUF3QyxDQUFBO0FBQ3ZFLE9BQU8sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLFNBQVMsQ0FBQTs7OztBQUVsRSw0QkFJQzs7O0lBSEMsK0JBQWM7O0lBQ2Qsc0NBQXFCOztJQUNyQixrQ0FBZ0I7OztBQUVsQixNQUFZLGNBQWM7SUFDeEIsV0FBVztJQUNYLE1BQU0sR0FBQTtJQUNOLFdBQVc7SUFDWCxPQUFPLEdBQUE7SUFDUCxXQUFXO0lBQ1gsUUFBUSxHQUFBO0VBQ1Q7Ozs7Ozs7OztNQUtLLFNBQVMsR0FBRyxFQUFFOztNQUNkLFFBQVEsR0FBRyxRQUFRLENBQUMsQ0FBQyxFQUFFLGNBQWMsQ0FBQzs7SUFDeEMsVUFBd0I7Ozs7QUFFNUIsU0FBUyxZQUFZO0lBQ25CLGNBQWMsRUFBRSxDQUFBO0lBQ2hCLFVBQVUsR0FBRyxRQUFRLENBQUMsU0FBUzs7O0lBQUMsR0FBRyxFQUFFO1FBQ25DLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFOztrQkFDbkMsSUFBSSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFFekIsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLGNBQWMsQ0FBQyxPQUFP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Q2xCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQTtTQUNiO0lBQ0gsQ0FBQzs7O1lBeEdGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsZUFBZTtnQkFDekIsK0tBQXlDO2dCQUN6QyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTthQUNoRDs7OztZQTlFQyxpQkFBaUI7OztxQkFpRmhCLEtBQUs7d0JBRUwsS0FBSzswQkFFTCxLQUFLO3FCQUVMLEtBQUs7bUJBRUwsS0FBSztxQkFVTCxNQUFNO21CQUVOLE1BQU07Ozs7Ozs7SUFwQlAsb0NBQW9DOzs7OztJQUVwQyx1Q0FBa0M7Ozs7O0lBRWxDLHlDQUFxQzs7Ozs7SUFFckMsb0NBQWlDOzs7OztJQVlqQyxvQ0FBMEM7Ozs7O0lBRTFDLGtDQUEyQzs7SUFFM0MsbUNBQTZDOzs7OztJQWdCN0MsbUNBQTZCOzs7Ozs7SUFFN0Isb0NBQXNCOzs7OztJQUN0QixxQ0FBdUI7Ozs7O0lBRVgsaUNBQThCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFRlbXBsYXRlUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQgeyBpbnRlcnZhbCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcydcbmltcG9ydCB7IGFuaW1hdGlvbkZyYW1lIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9zY2hlZHVsZXIvYW5pbWF0aW9uRnJhbWUnXG5pbXBvcnQgeyBpc1NhbWVTZWNvbmQsIHBhcnNlRm9ybWF0LCBwYXJzZVRpbWVEYXRhIH0gZnJvbSAnLi91dGlscydcblxuaW50ZXJmYWNlIENvdW50ZG93bkRhdGEge1xuICByZW1haW46IG51bWJlclxuICBmb3JtYXR0ZWRUaW1lOiBzdHJpbmdcbiAgZnJhZ21lbnRzOiBhbnlbXVxufVxuZXhwb3J0IGVudW0gQ291bnRkb3duU3RhdGUge1xuICAvKiog5pqC5YGc54q25oCBICovXG4gIHBhdXNlZCxcbiAgLyoqIOi/kOihjOeKtuaAgSAqL1xuICBwbGF5aW5nLFxuICAvKiog5a6M5oiQ54q25oCBICovXG4gIGZpbmlzaGVkXG59XG5cbi8qKlxuICog5omA5pyJ57uE5Lu25a6e5L6L5L2/55So5ZCM5LiA5LiqIGludGVydmFsIOa1ge+8jOS7peWFjeWunuS+i+WkmuS6huWQjumAoOaIkOWNoemhv1xuICovXG5jb25zdCBpbnN0YW5jZXMgPSBbXVxuY29uc3QgY291bnRlciQgPSBpbnRlcnZhbCgwLCBhbmltYXRpb25GcmFtZSlcbmxldCBjb3VudGVyU3ViOiBTdWJzY3JpcHRpb25cblxuZnVuY3Rpb24gc2V0dXBDb3VudGVyKCkge1xuICBkZXN0cm95Q291bnRlcigpXG4gIGNvdW50ZXJTdWIgPSBjb3VudGVyJC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5zdGFuY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbnN0ID0gaW5zdGFuY2VzW2ldXG5cbiAgICAgIGlmIChpbnN0LnN0YXRlICE9PSBDb3VudGRvd25TdGF0ZS5wbGF5aW5nKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChpbnN0LnJlbWFpbiA8PSAwKSB7XG4gICAgICAgIGluc3Quc3RhdGUgPSBDb3VudGRvd25TdGF0ZS5maW5pc2hlZFxuICAgICAgICBpbnN0LmNkci5kZXRlY3RDaGFuZ2VzKClcbiAgICAgICAgaW5zdC5maW5pc2guZW1pdCgpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlbWFpbiA9IE1hdGgubWF4KGluc3QuZW5kVGltZSAtIERhdGUubm93KCksIDApXG5cbiAgICAgIGlmICghaW5zdC5taWxsaXNlY29uZCkge1xuICAgICAgICBpZiAoIWlzU2FtZVNlY29uZChyZW1haW4sIGluc3QucmVtYWluKSB8fCByZW1haW4gPT09IDApIHtcbiAgICAgICAgICBpbnN0LnJlbWFpbiA9IHJlbWFpblxuICAgICAgICAgIGluc3QudGljay5lbWl0KGluc3QucmVtYWluKVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbnN0LnJlbWFpbiA9IHJlbWFpblxuICAgICAgICBpbnN0LnRpY2suZW1pdChpbnN0LnJlbWFpbilcbiAgICAgIH1cblxuICAgICAgaW5zdC5jZHIuZGV0ZWN0Q2hhbmdlcygpXG4gICAgfVxuICB9KVxufVxuZnVuY3Rpb24gZGVzdHJveUNvdW50ZXIoKSB7XG4gIGNvdW50ZXJTdWIgJiYgY291bnRlclN1Yi51bnN1YnNjcmliZSgpXG59XG5cbi8qKlxuICog5YCS6K6h5pe257uE5Lu2XG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1jb3VudGRvd24nLFxuICB0ZW1wbGF0ZVVybDogJy4vY291bnRkb3duLmNvbXBvbmVudC5odG1sJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgQ291bnRkb3duQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvKiog5qC85byPICovXG4gIEBJbnB1dCgpIGZvcm1hdDogc3RyaW5nID0gJ0hIOm1tOnNzJ1xuICAvKiog5piv5ZCm6Ieq5Yqo5byA5aeLICovXG4gIEBJbnB1dCgpIGF1dG9TdGFydDogYm9vbGVhbiA9IHRydWVcbiAgLyoqIOaYr+WQpuW8gOWQr+avq+enkue6p+a4suafkyAqL1xuICBASW5wdXQoKSBtaWxsaXNlY29uZDogYm9vbGVhbiA9IGZhbHNlXG4gIC8qKiDoh6rlrprkuYnmqKHniYggKi9cbiAgQElucHV0KCkgcmVuZGVyOiBUZW1wbGF0ZVJlZjxhbnk+XG4gIC8qKiDmgLvmr6vnp5LmlbAgKi9cbiAgQElucHV0KClcbiAgc2V0IHRpbWUodmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuX3RpbWUgPSBNYXRoLm1heCh2YWx1ZSwgMClcbiAgICB0aGlzLnJlc2V0KClcbiAgfVxuICBnZXQgdGltZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdGltZVxuICB9XG5cbiAgLyoqIOWAkuiuoeaXtuWujOavleaXtuinpuWPkSAqL1xuICBAT3V0cHV0KCkgZmluaXNoID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KClcbiAgLyoqIOavj+WAkuiuoeaXtuS4gOasoemDveinpuWPkSAqL1xuICBAT3V0cHV0KCkgdGljayA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpXG5cbiAgc3RhdGU6IENvdW50ZG93blN0YXRlID0gQ291bnRkb3duU3RhdGUucGF1c2VkXG4gIGdldCBkYXRhKCk6IENvdW50ZG93bkRhdGEge1xuICAgIGNvbnN0IG5vTWlsbGlzZWNvbmQgPSB0aGlzLmZvcm1hdC5pbmRleE9mKCdTJykgPT09IC0xLFxuICAgICAgaXNQbGF5aW5nID0gdGhpcy5zdGF0ZSA9PT0gQ291bnRkb3duU3RhdGUucGxheWluZ1xuXG4gICAgLy8g5Y2z5L2/IGZvcm1hdCDkuK3msqHmnInorr7nva7mr6vnp5LvvIznqIvluo/orqHnrpfml7blgJnkuZ/kvJrlsIbmr6vnp5LorqHnrpfov5vljrvvvIzlr7zoh7Tov5DooYzml7bnp5LmlbDnnIvkuIrljrvmgLvmmK/lsI8gMVxuICAgIC8vIOatpOWkhOWcqOa4suafk+aXtuWAmeaJi+WKqCArMSDnp5LvvIzku6Xov73msYLop4bop4nnu5/kuIBcbiAgICBjb25zdCB0aW1lRGF0YSA9IHBhcnNlVGltZURhdGEodGhpcy5yZW1haW4gKyAobm9NaWxsaXNlY29uZCAmJiBpc1BsYXlpbmcgPyAxMDAwIDogMCkpXG4gICAgY29uc3QgZm9ybWF0dGVkVGltZSA9IHBhcnNlRm9ybWF0KHRoaXMuZm9ybWF0LCB0aW1lRGF0YSlcbiAgICByZXR1cm4ge1xuICAgICAgZm9ybWF0dGVkVGltZSxcbiAgICAgIHJlbWFpbjogdGhpcy5yZW1haW4sXG4gICAgICBmcmFnbWVudHM6IGZvcm1hdHRlZFRpbWUuc3BsaXQoJzonKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3RpbWU6IG51bWJlciA9IDYwMDAwXG4gIC8qKiDliankvZnmr6vnp5LmlbAgKi9cbiAgcHJpdmF0ZSByZW1haW46IG51bWJlclxuICBwcml2YXRlIGVuZFRpbWU6IG51bWJlclxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZikge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICBpbnN0YW5jZXMucHVzaCh0aGlzKVxuICAgIGlmIChpbnN0YW5jZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICBzZXR1cENvdW50ZXIoKVxuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMucGF1c2UoKVxuICAgIGNvbnN0IGluZGV4ID0gaW5zdGFuY2VzLmluZGV4T2YodGhpcylcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBpbnN0YW5jZXMuc3BsaWNlKGluZGV4LCAxKVxuICAgIH1cbiAgICBpZiAoaW5zdGFuY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZGVzdHJveUNvdW50ZXIoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDnu6fnu63lgJLorqHml7ZcbiAgICovXG4gIHN0YXJ0KCkge1xuICAgIGlmICh0aGlzLnN0YXRlID09PSBDb3VudGRvd25TdGF0ZS5wbGF5aW5nKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0ZSA9PT0gQ291bnRkb3duU3RhdGUuZmluaXNoZWQpIHtcbiAgICAgIHRoaXMucmVtYWluID0gdGhpcy50aW1lXG4gICAgfVxuXG4gICAgdGhpcy5lbmRUaW1lID0gRGF0ZS5ub3coKSArIHRoaXMucmVtYWluXG4gICAgdGhpcy5zdGF0ZSA9IENvdW50ZG93blN0YXRlLnBsYXlpbmdcbiAgfVxuXG4gIC8qKlxuICAgKiDmmoLlgZzlgJLorqHml7ZcbiAgICovXG4gIHBhdXNlKCkge1xuICAgIHRoaXMuc3RhdGUgPSBDb3VudGRvd25TdGF0ZS5wYXVzZWRcbiAgfVxuXG4gIC8qKlxuICAgKiDph43nva7lgJLorqHml7ZcbiAgICovXG4gIHJlc2V0KCkge1xuICAgIHRoaXMucGF1c2UoKVxuICAgIHRoaXMucmVtYWluID0gdGhpcy50aW1lXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpXG5cbiAgICBpZiAodGhpcy5hdXRvU3RhcnQpIHtcbiAgICAgIHRoaXMuc3RhcnQoKVxuICAgIH1cbiAgfVxufVxuIl19