mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-21 07:16:15 -04:00
feat(new-tool): added chronometer
This commit is contained in:
parent
1c7257eeb0
commit
130031c225
5 changed files with 74 additions and 0 deletions
12
src/tools/chronometer/chronometer.service.test.ts
Normal file
12
src/tools/chronometer/chronometer.service.test.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { formatChronometerTime } 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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
13
src/tools/chronometer/chronometer.service.ts
Normal file
13
src/tools/chronometer/chronometer.service.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
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;
|
||||||
|
const hrsString = hrs > 0 ? `${hrs.toString().padStart(2, '0')}:` : '';
|
||||||
|
|
||||||
|
return `${hrsString}${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}.${ms
|
||||||
|
.toString()
|
||||||
|
.padStart(3, '0')}`;
|
||||||
|
}
|
32
src/tools/chronometer/chronometer.vue
Normal file
32
src/tools/chronometer/chronometer.vue
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<n-card>
|
||||||
|
<div class="duration">{{ formatChronometerTime({ elapsed: counter, msPerUnit }) }}</div>
|
||||||
|
</n-card>
|
||||||
|
<br />
|
||||||
|
<n-space justify="center">
|
||||||
|
<n-button v-if="!isActive" 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>
|
||||||
|
</n-space>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useInterval } from '@vueuse/core';
|
||||||
|
import { formatChronometerTime } from './chronometer.service';
|
||||||
|
|
||||||
|
const msPerUnit = 10;
|
||||||
|
|
||||||
|
const { counter, pause, resume, isActive } = useInterval(msPerUnit, { controls: true, immediate: false });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.duration {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 40px;
|
||||||
|
font-family: monospace;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
</style>
|
11
src/tools/chronometer/index.ts
Normal file
11
src/tools/chronometer/index.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { TimerOutlined } from '@vicons/material';
|
||||||
|
import { defineTool } from '../tool';
|
||||||
|
|
||||||
|
export const tool = defineTool({
|
||||||
|
name: 'Chronometer',
|
||||||
|
path: '/chronometer',
|
||||||
|
description: 'Monitor the duration of a thing. Basically a chronometer with simple chronometer features.',
|
||||||
|
keywords: ['chronometer', 'time', 'lap', 'duration', 'measure', 'pause', 'resume', 'stopwatch'],
|
||||||
|
component: () => import('./chronometer.vue'),
|
||||||
|
icon: TimerOutlined,
|
||||||
|
});
|
|
@ -5,6 +5,7 @@ import { tool as base64Converter } from './base64-converter';
|
||||||
import { tool as bcrypt } from './bcrypt';
|
import { tool as bcrypt } from './bcrypt';
|
||||||
import { tool as bip39 } from './bip39-generator';
|
import { tool as bip39 } from './bip39-generator';
|
||||||
import { tool as caseConverter } from './case-converter';
|
import { tool as caseConverter } from './case-converter';
|
||||||
|
import { tool as chronometer } from './chronometer';
|
||||||
import { tool as colorConverter } from './color-converter';
|
import { tool as colorConverter } from './color-converter';
|
||||||
import { tool as crontabGenerator } from './crontab-generator';
|
import { tool as crontabGenerator } from './crontab-generator';
|
||||||
import { tool as dateTimeConverter } from './date-time-converter';
|
import { tool as dateTimeConverter } from './date-time-converter';
|
||||||
|
@ -59,6 +60,11 @@ export const toolsByCategory: ToolCategory[] = [
|
||||||
icon: LockOpen,
|
icon: LockOpen,
|
||||||
components: [mathEvaluator],
|
components: [mathEvaluator],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Measurement',
|
||||||
|
icon: LockOpen,
|
||||||
|
components: [chronometer],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Text',
|
name: 'Text',
|
||||||
icon: LockOpen,
|
icon: LockOpen,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue