stylescape
Version:
Stylescape is a visual identity framework developed by Scape Agency.
111 lines • 3.81 kB
JavaScript
export class CountdownTimer {
constructor(selectorOrElement, options = {}) {
this.intervalId = null;
this.element =
typeof selectorOrElement === "string"
? document.querySelector(selectorOrElement)
: selectorOrElement;
this.options = {
endTime: options.endTime ?? new Date(Date.now() + 3600000),
format: options.format ?? "HH:MM:SS",
endText: options.endText ?? "Time's up!",
interval: options.interval ?? 1000,
onComplete: options.onComplete ?? (() => { }),
onTick: options.onTick ?? (() => { }),
leadingZeros: options.leadingZeros !== false,
};
if (typeof this.options.endTime === "string") {
this.endTime = new Date(this.options.endTime).getTime();
}
else if (typeof this.options.endTime === "number") {
this.endTime = this.options.endTime;
}
else {
this.endTime = this.options.endTime.getTime();
}
if (!this.element) {
console.warn("[Stylescape] CountdownTimer element not found");
return;
}
this.start();
}
start() {
if (this.intervalId)
return;
this.tick();
this.intervalId = window.setInterval(() => this.tick(), this.options.interval);
}
stop() {
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
}
reset(endTime) {
this.stop();
if (typeof endTime === "string") {
this.endTime = new Date(endTime).getTime();
}
else if (typeof endTime === "number") {
this.endTime = endTime;
}
else {
this.endTime = endTime.getTime();
}
this.start();
}
getRemaining() {
const total = Math.max(0, this.endTime - Date.now());
return {
total,
days: Math.floor(total / (1000 * 60 * 60 * 24)),
hours: Math.floor((total / (1000 * 60 * 60)) % 24),
minutes: Math.floor((total / (1000 * 60)) % 60),
seconds: Math.floor((total / 1000) % 60),
};
}
destroy() {
this.stop();
this.element = null;
}
tick() {
const remaining = this.getRemaining();
this.options.onTick(remaining);
if (remaining.total <= 0) {
this.stop();
this.updateDisplay(this.options.endText);
this.options.onComplete();
return;
}
this.updateDisplay(this.formatTime(remaining));
}
formatTime(time) {
const pad = (n) => this.options.leadingZeros
? n.toString().padStart(2, "0")
: n.toString();
switch (this.options.format) {
case "DD:HH:MM:SS":
return `${pad(time.days)}:${pad(time.hours)}:${pad(time.minutes)}:${pad(time.seconds)}`;
case "full":
return `${time.days}d ${time.hours}h ${time.minutes}m ${time.seconds}s`;
case "compact":
if (time.days > 0)
return `${time.days}d ${time.hours}h`;
if (time.hours > 0)
return `${time.hours}h ${time.minutes}m`;
return `${time.minutes}m ${time.seconds}s`;
case "HH:MM:SS":
default: {
const totalHours = time.days * 24 + time.hours;
return `${pad(totalHours)}:${pad(time.minutes)}:${pad(time.seconds)}`;
}
}
}
updateDisplay(text) {
if (this.element) {
this.element.textContent = text;
}
}
}
export default CountdownTimer;
//# sourceMappingURL=CountdownTimer.js.map