aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Corentin Thomasset <corentin.thomasset74@gmail.com> 2022-08-04 09:06:42 +0200
committerGravatar Corentin Thomasset <corentin.thomasset74@gmail.com> 2022-08-04 09:06:42 +0200
commite48d60b1ed19279f48441743f7ed69e8fd915011 (patch)
tree1be5c8d968c74313ee93fbcb347f26bff65d4c80
parentfda0b0ca25c1733542a4e797ac1a2150c546a660 (diff)
downloadit-tools-e48d60b1ed19279f48441743f7ed69e8fd915011.tar.gz
it-tools-e48d60b1ed19279f48441743f7ed69e8fd915011.tar.zst
it-tools-e48d60b1ed19279f48441743f7ed69e8fd915011.zip
refactor(chronometer): improved chronometer precision
-rw-r--r--src/tools/chronometer/chronometer.service.test.ts9
-rw-r--r--src/tools/chronometer/chronometer.service.ts12
-rw-r--r--src/tools/chronometer/chronometer.vue33
3 files changed, 37 insertions, 17 deletions
diff --git a/src/tools/chronometer/chronometer.service.test.ts b/src/tools/chronometer/chronometer.service.test.ts
index 5fdb3c7..6230ca2 100644
--- a/src/tools/chronometer/chronometer.service.test.ts
+++ b/src/tools/chronometer/chronometer.service.test.ts
@@ -1,12 +1,13 @@
import { describe, expect, it } from 'vitest';
-import { formatChronometerTime } from './chronometer.service';
+import { formatMs } from './chronometer.service';
describe('chronometer', () => {
describe('formatChronometerTime', () => {
it('format the elapsed time', () => {
- expect(formatChronometerTime({ elapsed: 123456 })).toEqual('02:03.456');
- expect(formatChronometerTime({ elapsed: 123456, msPerUnit: 100 })).toEqual('03:25:45.600');
- expect(formatChronometerTime({ elapsed: 12345600 })).toEqual('03:25:45.600');
+ expect(formatMs(0)).toEqual('00:00.000');
+ expect(formatMs(1)).toEqual('00:00.001');
+ expect(formatMs(123456)).toEqual('02:03.456');
+ expect(formatMs(12345600)).toEqual('03:25:45.600');
});
});
});
diff --git a/src/tools/chronometer/chronometer.service.ts b/src/tools/chronometer/chronometer.service.ts
index a2e03b8..62fb819 100644
--- a/src/tools/chronometer/chronometer.service.ts
+++ b/src/tools/chronometer/chronometer.service.ts
@@ -1,10 +1,8 @@
-export function formatChronometerTime({ elapsed, msPerUnit = 1 }: { elapsed: number; msPerUnit?: number }) {
- const elapsedMs = elapsed * msPerUnit;
-
- const ms = elapsedMs % 1000;
- const secs = ((elapsedMs - ms) / 1000) % 60;
- const mins = (((elapsedMs - ms) / 1000 - secs) / 60) % 60;
- const hrs = (((elapsedMs - ms) / 1000 - secs) / 60 - mins) / 60;
+export function formatMs(msTotal: number) {
+ const ms = msTotal % 1000;
+ const secs = ((msTotal - ms) / 1000) % 60;
+ const mins = (((msTotal - ms) / 1000 - secs) / 60) % 60;
+ const hrs = (((msTotal - ms) / 1000 - secs) / 60 - mins) / 60;
const hrsString = hrs > 0 ? `${hrs.toString().padStart(2, '0')}:` : '';
return `${hrsString}${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}.${ms
diff --git a/src/tools/chronometer/chronometer.vue b/src/tools/chronometer/chronometer.vue
index 2efcdc1..16009ff 100644
--- a/src/tools/chronometer/chronometer.vue
+++ b/src/tools/chronometer/chronometer.vue
@@ -1,11 +1,11 @@
<template>
<div>
<n-card>
- <div class="duration">{{ formatChronometerTime({ elapsed: counter, msPerUnit }) }}</div>
+ <div class="duration">{{ formatMs(counter) }}</div>
</n-card>
<br />
<n-space justify="center">
- <n-button v-if="!isActive" secondary type="primary" @click="resume">Start</n-button>
+ <n-button v-if="!isRunning" secondary type="primary" @click="resume">Start</n-button>
<n-button v-else secondary type="warning" @click="pause">Stop</n-button>
<n-button secondary @click="counter = 0">Reset</n-button>
@@ -14,12 +14,33 @@
</template>
<script setup lang="ts">
-import { useInterval } from '@vueuse/core';
-import { formatChronometerTime } from './chronometer.service';
+import { useRafFn } from '@vueuse/core';
+import { ref } from 'vue';
+import { formatMs } from './chronometer.service';
-const msPerUnit = 10;
+const isRunning = ref(false);
+const counter = ref(0);
-const { counter, pause, resume, isActive } = useInterval(msPerUnit, { controls: true, immediate: false });
+let previousRafDate = Date.now();
+const { pause: pauseRaf, resume: resumeRaf } = useRafFn(
+ () => {
+ const deltaMs = Date.now() - previousRafDate;
+ previousRafDate = Date.now();
+ counter.value += deltaMs;
+ },
+ { immediate: false },
+);
+
+function resume() {
+ previousRafDate = Date.now();
+ resumeRaf();
+ isRunning.value = true;
+}
+
+function pause() {
+ pauseRaf();
+ isRunning.value = false;
+}
</script>
<style lang="less" scoped>