everyone! I have a small code written in Vue.JS for the stopwatch. After writing I realized that there are small losses in time (For every 30 real seconds, the browser marks about 27-28 seconds), as well as when folding deposits the time account stops. Tell me, please, how to my code, I can insert the use of localStorage to avoid wasting time when coagulating and where better to compare with the real time to avoid the usual losses?
Stopwatch code:
<template>
<div id="clock">
<span ref="watch">00:00</span>
</div>
</template>
<script>
export default {
name: "MyTimer",
data() {
return {
minutes: 0,
seconds: 0,
miliseconds: 0,
interval: null,
}
},
mounted() {
const watch = this.$refs.watch;
clearInterval(this.interval);
this.interval = setInterval(() => {
this.miliseconds = 10;
let dateTimer = new Date(this.miliseconds);
watch.innerHTML = ('0' dateTimer.getUTCMinutes()).slice(-2) ':' ('0' dateTimer.getUTCSeconds()).slice(-2);
}, 10)
}
}
</script>
<style scoped>
#clock {
background: #EDEDED;
padding: 1%;
border-radius: 12px;
text-align: center;
}
.time {
font-weight: 900;
font-size: 2.125em;
letter-spacing: 0.015625em;
color: #373745;
}
</style>
Please help embed localStorage and real past tense comparison to make the stopwatch more accurate and avoid real past tense losses.
CodePudding user response:
I think I got all things covered here. The save and load isn't used in the example due to localStorage not working within sandbox.
class stopwatch {
/** @param {HTMLElement} element */
constructor(element) {
this._el = element;
if(this._el) {
this._el.innerText = "00:00";
}
}
laps = [];
totalMilliseconds = 0;
totalSeconds = this.totalMilliseconds / 1000.0;
totalMinutes = this.totalMilliseconds / 60000.0;
totalHours = this.totalMilliseconds / 3600000.0;
_startTime = 0;
_interval = null;
start = (reset) => {
if(reset) {
this.laps.splice(0, this.laps.length);
}
this._startTime = performance.now();
this._interval = setInterval(this._render, 10);
};
lap = () => {
this.laps.push(performance.now() - this._startTime);
this._startTime = performance.now();
};
stop = () => {
this.laps.push(performance.now() - this._startTime);
this._startTime = 0;
clearInterval(this._interval);
this._interval = null;
};
save = () => {
if(this._interval) {
this.stop();
}
localStorage.setItem('js_stopwatch', JSON.stringify({laps: this.laps}));
};
load = () => {
const data = JSON.parse(localStorage.getItem('js_stopwatch'));
if(data && data.laps) {
this.laps = data.laps;
this._startTime = performance.now();
this._render();
this.start();
return true;
}
};
_msToParts = (milliseconds) => {
const h = Math.floor(milliseconds / (1000 * 60 * 60));
milliseconds -= (h * 60 * 60 * 1000);
const m = Math.floor(milliseconds / (1000 * 60));
milliseconds -= (m * 60 * 1000);
const s = Math.floor(milliseconds / (1000));
milliseconds -= (s * 1000);
const ms = Math.floor(milliseconds);
return {
hours: h,
minutes: m,
seconds: s,
milliseconds: ms,
};
};
_render = () => {
this.totalMilliseconds = this.laps.reduce((pv, cv, i) => pv cv, (performance.now() - this._startTime));
const parts = this._msToParts(this.totalMilliseconds);
if(this._el) {
this._el.innerText = `${parts.hours ? `${parts.hours}:` : ''}${parts.minutes.toString().padStart(2, '0')}:${parts.seconds.toString().padStart(2, '0')}`;
}
};
}
const el = document.getElementById("clock");
const sw = new stopwatch(el);
sw.start();
#clock {
background: #EDEDED;
padding: 1%;
border-radius: 12px;
text-align: center;
}
.time {
font-weight: 900;
font-size: 2.125em;
letter-spacing: 0.015625em;
color: #373745;
}
<span id="clock">00:00</span>