@flxng/circle-timer
Version:
Circle Timer (countdown) component for Angular.
359 lines (351 loc) • 13.2 kB
JavaScript
import { Injectable, ɵɵdefineInjectable, EventEmitter, Component, NgZone, Input, Output, NgModule } from '@angular/core';
import { Subject, timer } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* Generated from: lib/circle-timer.service.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var CircleTimerService = /** @class */ (function () {
function CircleTimerService() {
}
CircleTimerService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root',
},] }
];
/** @nocollapse */
CircleTimerService.ctorParameters = function () { return []; };
/** @nocollapse */ CircleTimerService.ngInjectableDef = ɵɵdefineInjectable({ factory: function CircleTimerService_Factory() { return new CircleTimerService(); }, token: CircleTimerService, providedIn: "root" });
return CircleTimerService;
}());
/**
* @fileoverview added by tsickle
* Generated from: lib/circle-timer.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var CircleTimerComponent = /** @class */ (function () {
function CircleTimerComponent(ngZone) {
this.ngZone = ngZone;
// only to set initial state (ngOnInit)
this.duration = 0; // milliseconds
// milliseconds
this.color = '#1cbbf8';
this.onComplete = new EventEmitter();
this.destroy$ = new Subject();
this.startTime = 0;
this.timeLeft = 0;
this.ticking = false;
this.completed = false;
this.formattedTimeLeft = '';
this.fullDasharray = 283;
this.dasharray = this.fullDasharray + " " + this.fullDasharray;
}
/**
* @return {?}
*/
CircleTimerComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.init(this.startDate);
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.destroy$.next();
this.destroy$.complete();
};
/**
* @param {?=} startDate
* @return {?}
*/
CircleTimerComponent.prototype.init = /**
* @param {?=} startDate
* @return {?}
*/
function (startDate) {
this.setTimeLeft(startDate);
this.formatTimeLeft();
this.setDasharray();
if (this.timeLeft === 0) {
this.completed = true;
}
};
/**
* @param {?=} startDate
* @return {?}
*/
CircleTimerComponent.prototype.setTimeLeft = /**
* @param {?=} startDate
* @return {?}
*/
function (startDate) {
this.ticking = false;
this.completed = false;
this.destroy$.next();
if (!startDate) {
this.timeLeft = this.duration;
return 0;
}
/** @type {?} */
var startTime = new Date((/** @type {?} */ (startDate))).getTime();
/** @type {?} */
var endTime = startTime + this.duration;
/** @type {?} */
var timeLeftRaw = endTime - Date.now();
if (timeLeftRaw <= 0) {
this.timeLeft = 0;
return 0;
}
/** @type {?} */
var timeLeftSeconds = timeLeftRaw / 1000;
this.timeLeft = Math.floor(timeLeftSeconds) * 1000;
return timeLeftSeconds % 1;
};
/**
* @param {?=} startDate
* @param {?=} delayMs
* @param {?=} replaying
* @return {?}
*/
CircleTimerComponent.prototype.start = /**
* @param {?=} startDate
* @param {?=} delayMs
* @param {?=} replaying
* @return {?}
*/
function (startDate, delayMs, replaying) {
var _this = this;
if (delayMs === void 0) { delayMs = 0; }
if (replaying === void 0) { replaying = false; }
if (this.ticking) {
console.log('Cannot start: timer already running.');
return;
}
/** @type {?} */
var decimalPortion = this.setTimeLeft(startDate);
/** @type {?} */
var startDelayMs = delayMs + decimalPortion * 1000;
this.formatTimeLeft();
this.setDasharray();
if (this.timeLeft === 0) {
this.completed = true;
console.log('Cannot start: timer already completed.');
return;
}
timer(startDelayMs, 1000)
.pipe(takeUntil(this.destroy$))
.subscribe((/**
* @param {?} e
* @return {?}
*/
function (e) {
_this.ticking = true;
_this.timeLeft -= 1000;
if (_this.timeLeft <= 0) {
_this.timeLeft = 0;
_this.ticking = false;
_this.completed = true;
_this.onComplete.emit(replaying);
_this.destroy$.next();
}
_this.formatTimeLeft();
_this.setDasharray();
}));
};
/**
* @param {?=} startDate
* @return {?}
*/
CircleTimerComponent.prototype.replay = /**
* @param {?=} startDate
* @return {?}
*/
function (startDate) {
this.start(startDate, 1200, true);
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.pause = /**
* @return {?}
*/
function () { };
/**
* @return {?}
*/
CircleTimerComponent.prototype.continue = /**
* @return {?}
*/
function () { };
/**
* @return {?}
*/
CircleTimerComponent.prototype.complete = /**
* @return {?}
*/
function () {
this.timeLeft = 0;
this.ticking = false;
this.completed = true;
this.destroy$.next();
this.formatTimeLeft();
this.setDasharray();
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.isTicking = /**
* @return {?}
*/
function () {
return this.ticking;
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.isCompleted = /**
* @return {?}
*/
function () {
return this.completed;
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.formatTimeLeft = /**
* @return {?}
*/
function () {
if (this.timeLeft <= 0) {
this.timeLeft = 0;
}
/** @type {?} */
var daysLeft = Math.floor(this.timeLeft / (1000 * 60 * 60 * 24));
/** @type {?} */
var hoursLeft = Math.floor((this.timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
/** @type {?} */
var minutesLeft = Math.floor((this.timeLeft % (1000 * 60 * 60)) / (1000 * 60));
/** @type {?} */
var secondsLeft = Math.floor((this.timeLeft % (1000 * 60)) / 1000);
/** @type {?} */
var formattedDays = daysLeft < 10 ? "0" + daysLeft : "" + daysLeft;
/** @type {?} */
var formattedHours = hoursLeft < 10 ? "0" + hoursLeft : "" + hoursLeft;
/** @type {?} */
var formattedMinutes = minutesLeft < 10 ? "0" + minutesLeft : "" + minutesLeft;
/** @type {?} */
var formattedSeconds = secondsLeft < 10 ? "0" + secondsLeft : "" + secondsLeft;
this.formattedTimeLeft = formattedMinutes + ":" + formattedSeconds;
if (formattedHours !== '00' || formattedDays !== '00') {
this.formattedTimeLeft = formattedHours + ":" + this.formattedTimeLeft;
}
if (formattedDays !== '00') {
this.formattedTimeLeft = formattedDays + ":" + this.formattedTimeLeft;
}
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.setDasharray = /**
* @return {?}
*/
function () {
/** @type {?} */
var rawFraction = this.timeLeft / this.duration;
/** @type {?} */
var fraction = rawFraction - (1 / this.duration) * (1 - rawFraction);
/** @type {?} */
var remaining = Math.round(fraction * this.fullDasharray);
this.dasharray = remaining + " " + this.fullDasharray;
};
CircleTimerComponent.decorators = [
{ type: Component, args: [{
selector: 'flx-circle-timer',
template: "<div class=\"base-timer\">\r\n <svg class=\"base-timer-svg\"\r\n viewBox=\"0 0 100 100\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <g class=\"base-timer-circle\">\r\n <circle [ngClass]=\"completed ? 'base-timer-completed' : 'base-timer-stroke'\"\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\" />\r\n <path [attr.stroke-dasharray]=\"dasharray\"\r\n [style.stroke]=\"color\"\r\n id=\"remaining-time-stroke\"\r\n d=\" M 50, 50\r\n m -45, 0\r\n a 45,45 0 1,0 90,0\r\n a 45,45 0 1,0 -90,0\">\r\n </path>\r\n </g>\r\n </svg>\r\n <span class=\"time\">\r\n <!-- <img *ngIf=\"completed\"\r\n src=\"../../../assets/image/check.svg\"\r\n alt=\"\">\r\n <span *ngIf=\"!completed\">{{formattedTimeLeft}}</span> -->\r\n <span>{{formattedTimeLeft}}</span>\r\n </span>\r\n</div>",
styles: [":host .base-timer{position:relative;height:200px;width:200px}:host .base-timer-circle{fill:none;stroke:none}:host .base-timer-stroke{stroke-width:1px;stroke:grey}:host .base-timer-completed{stroke-width:1px;stroke:grey}:host .base-timer .time{position:absolute;width:200px;height:200px;top:0;display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;font-size:26px}:host .base-timer .time img{height:80px}:host .base-timer #remaining-time-stroke{stroke-width:2px;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-transform-origin:center;transform-origin:center;-webkit-transition:1s linear;transition:1s linear;stroke:#1cbbf8}:host .base-timer .base-timer-svg{-webkit-transform:scaleX(-1);transform:scaleX(-1)}"]
}] }
];
/** @nocollapse */
CircleTimerComponent.ctorParameters = function () { return [
{ type: NgZone }
]; };
CircleTimerComponent.propDecorators = {
startDate: [{ type: Input }],
duration: [{ type: Input }],
color: [{ type: Input }],
onComplete: [{ type: Output }]
};
return CircleTimerComponent;
}());
if (false) {
/** @type {?} */
CircleTimerComponent.prototype.startDate;
/** @type {?} */
CircleTimerComponent.prototype.duration;
/** @type {?} */
CircleTimerComponent.prototype.color;
/** @type {?} */
CircleTimerComponent.prototype.onComplete;
/** @type {?} */
CircleTimerComponent.prototype.destroy$;
/** @type {?} */
CircleTimerComponent.prototype.startTime;
/** @type {?} */
CircleTimerComponent.prototype.timeLeft;
/** @type {?} */
CircleTimerComponent.prototype.ticking;
/** @type {?} */
CircleTimerComponent.prototype.completed;
/** @type {?} */
CircleTimerComponent.prototype.formattedTimeLeft;
/** @type {?} */
CircleTimerComponent.prototype.fullDasharray;
/** @type {?} */
CircleTimerComponent.prototype.dasharray;
/**
* @type {?}
* @protected
*/
CircleTimerComponent.prototype.ngZone;
}
/**
* @fileoverview added by tsickle
* Generated from: lib/circle-timer.module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var CircleTimerModule = /** @class */ (function () {
function CircleTimerModule() {
}
CircleTimerModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
declarations: [CircleTimerComponent],
exports: [CircleTimerComponent],
},] }
];
return CircleTimerModule;
}());
/**
* @fileoverview added by tsickle
* Generated from: lib/index.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* Generated from: public-api.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* Generated from: flxng-circle-timer.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { CircleTimerComponent, CircleTimerModule, CircleTimerService };
//# sourceMappingURL=flxng-circle-timer.js.map