Untitled
unknown
plain_text
a year ago
5.9 kB
7
Indexable
<script>
class Timer {
constructor(selectors) {
this.sec = 0;
this.min = 0;
this.running = false;
this.startTime = 0; // Timestamp.
this.timerTime = [0, 0]; // Minutes and seconds.
this.timerCastInterval;
this.selectors = {
wrapper: '',
inputMin: '',
inputSec: '',
btnStart: '',
btnStop: '',
timerPreview: '',
timerPreviewCast: ''
};
this.uiElements = {
wrapper: null,
inputMin: null,
inputSec: null,
btnStart: null,
btnStop: null,
timerPreview: null,
timerPreviewCast: null,
}
this.setInterface(selectors);
this.addInterfaceListeners();
}
setInterface(selectors) {
const that = this;
this.selectors = {...this.selectors, ...selectors};
Object.keys(this.selectors).forEach(key => {
if (that.selectors[key].length > 0) {
const el = document.querySelector(that.selectors[key]);
if (el !== null) {
that.uiElements[key] = el;
}
}
});
}
addInterfaceListeners() {
const that = this;
// Start.
if (this.uiElements.btnStart !== null) {
this.uiElements.btnStart.addEventListener('click', function () {
if (!that.isRunning()) {
that.start();
}
});
}
// Stop.
if (this.uiElements.btnStop !== null) {
this.uiElements.btnStop.addEventListener('click', function () {
if (that.isRunning()) {
that.stop();
}
});
}
};
setSec(sec) {
if (this.isRunning() || isNaN(sec)) {
return;
}
this.sec = this.sanitizeSec(sec);
}
setMin(min) {
if (this.isRunning() || isNaN(min)) {
return;
}
this.min = this.sanitizeMin(min);
}
sanitizeSec(sec) {
if (isNaN(sec)) {
sec = 0;
}
sec = parseInt(sec);
if (sec < 0) {
sec = 0;
}
if (sec > 59) {
sec = 59;
}
return sec;
}
sanitizeMin(min) {
if (isNaN(min)) {
min = 0;
}
min = parseInt(min);
if (min < 0) {
min = 0;
}
return min;
}
isRunning() {
return this.running;
}
getCurrentTime() {
// Timestamp.
return Math.floor(new Date().getTime() / 1000);
}
setStartTime() {
this.startTime = this.getCurrentTime() - this.sec - this.min * 60;
}
resetStartTime() {
this.startTime = 0;
}
manageDynamicClasses(action) {
// Wrapper class.
if (this.uiElements.wrapper !== null) {
const toAdd = action === 'stop' ? 'timer-stopped' : 'timer-running';
const toRemove = action === 'stop' ? 'timer-running' : 'timer-stopped';
this.uiElements.wrapper.classList.add(toAdd);
this.uiElements.wrapper.classList.remove(toRemove);
}
if (action === 'start') {
this.uiElements.btnStart.disabled = true;
this.uiElements.inputMin.disabled = true;
this.uiElements.inputSec.disabled = true;
this.uiElements.btnStop.disabled = false;
}
if (action === 'stop') {
this.uiElements.btnStart.disabled = false;
this.uiElements.inputMin.disabled = false;
this.uiElements.inputSec.disabled = false;
this.uiElements.btnStop.disabled = true;
}
}
start() {
if (this.isRunning()) {
return;
}
this.updateTimeFromInputs();
this.setStartTime();
this.updateTime();
this.cast();
this.manageDynamicClasses('start');
this.running = true;
}
stop() {
this.updateTime();
this.running = false;
this.resetStartTime();
this.stopCast();
this.manageDynamicClasses('stop');
this.updateTimeInputs();
}
updateTime() {
if (!this.isRunning()) {
return;
}
const diffSeconds = this.getCurrentTime() - this.startTime;
this.min = Math.floor(diffSeconds / 60);
this.sec = diffSeconds % 60;
}
getTimerTime() {
this.updateTime();
return [this.min, this.sec];
}
formatTimeNumber(number) {
return number < 10 ? '0' + number : number;
}
getFormattedTimerTime() {
const time = this.getTimerTime();
const minutesFormatted = this.formatTimeNumber(time[0]);
const secondsFormatted = this.formatTimeNumber(time[1]);
return minutesFormatted + ':' + secondsFormatted;
}
updateTimeFromInputs() {
const sec = this.uiElements.inputSec.value;
const min = this.uiElements.inputMin.value;
if (sec.length > 0 && !isNaN(sec)) {
this.setSec(sec);
this.uiElements.inputSec.value = this.formatTimeNumber(this.sanitizeSec(sec));
}
if (min.length > 0 && !isNaN(min)) {
this.setMin(min);
this.uiElements.inputMin.value = this.formatTimeNumber(this.sanitizeMin(min));
}
}
updateTimeInputs() {
this.uiElements.inputMin.value = this.formatTimeNumber(this.min);
this.uiElements.inputSec.value = this.formatTimeNumber(this.sec);
}
cast() {
const that = this;
this.timerCastInterval = setInterval(function () {
const time = that.getFormattedTimerTime();
if (that.uiElements.timerPreview !== null) {
that.uiElements.timerPreview.innerHTML = time;
}
}, 100);
}
stopCast() {
clearInterval(this.timerCastInterval);
}
}
document.addEventListener("DOMContentLoaded", function () {
window.timer = new Timer({
wrapper: '.js-timer-wrapper',
inputMin: '.js-timer-min',
inputSec: '.js-timer-sec',
btnStart: '.js-timer-start',
btnStop: '.js-timer-stop',
timerPreview: '.timer-preview',
timerPreviewCast: ''
});
});
</script>
<div class="js-timer-wrapper">
<div class="timer-preview">00:00</div>
<input type="text" value="" name="timer-min" class="js-timer-min" placeholder="min">
<input type="text" value="" name="timer-sec" class="js-timer-sec" placeholder="sec">
<button class="js-timer-start">Start</button>
<button class="js-timer-stop">Stop</button>
</div>Editor is loading...
Leave a Comment