diff options
author | 2022-08-04 09:06:42 +0200 | |
---|---|---|
committer | 2022-08-04 09:06:42 +0200 | |
commit | e48d60b1ed19279f48441743f7ed69e8fd915011 (patch) | |
tree | 1be5c8d968c74313ee93fbcb347f26bff65d4c80 | |
parent | fda0b0ca25c1733542a4e797ac1a2150c546a660 (diff) | |
download | it-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.ts | 9 | ||||
-rw-r--r-- | src/tools/chronometer/chronometer.service.ts | 12 | ||||
-rw-r--r-- | src/tools/chronometer/chronometer.vue | 33 |
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> |