diff --git a/src/.umi/core/route.tsx b/src/.umi/core/route.tsx index d31be74..89e3f37 100644 --- a/src/.umi/core/route.tsx +++ b/src/.umi/core/route.tsx @@ -19,7 +19,7 @@ if (process.env.NODE_ENV === 'development') { import React from 'react'; export async function getRoutes() { - const routes = {"imageCompress/singleImageCompress":{"path":"imageCompress/singleImageCompress","id":"imageCompress/singleImageCompress","parentId":"@@/global-layout"},"imageCompress/batchImageCompress":{"path":"imageCompress/batchImageCompress","id":"imageCompress/batchImageCompress","parentId":"@@/global-layout"},"imageCompress/index":{"path":"imageCompress","id":"imageCompress/index","parentId":"@@/global-layout"},"imgFormatConversion":{"path":"imgFormatConversion","id":"imgFormatConversion","parentId":"@@/global-layout"},"jsonFormatting":{"path":"jsonFormatting","id":"jsonFormatting","parentId":"@@/global-layout"},"imageSlicing":{"path":"imageSlicing","id":"imageSlicing","parentId":"@@/global-layout"},"jsonDiff":{"path":"jsonDiff","id":"jsonDiff","parentId":"@@/global-layout"},"imgScan":{"path":"imgScan","id":"imgScan","parentId":"@@/global-layout"},"index":{"path":"/","id":"index","parentId":"@@/global-layout"},"home":{"path":"home","id":"home","parentId":"@@/global-layout"},"@@/global-layout":{"id":"@@/global-layout","path":"/","isLayout":true}} as const; + const routes = {"imageCompress/singleImageCompress":{"path":"imageCompress/singleImageCompress","id":"imageCompress/singleImageCompress","parentId":"@@/global-layout"},"imageCompress/batchImageCompress":{"path":"imageCompress/batchImageCompress","id":"imageCompress/batchImageCompress","parentId":"@@/global-layout"},"imageCompress/index":{"path":"imageCompress","id":"imageCompress/index","parentId":"@@/global-layout"},"imgFormatConversion":{"path":"imgFormatConversion","id":"imgFormatConversion","parentId":"@@/global-layout"},"jsonFormatting":{"path":"jsonFormatting","id":"jsonFormatting","parentId":"@@/global-layout"},"imageSlicing":{"path":"imageSlicing","id":"imageSlicing","parentId":"@@/global-layout"},"jsonDiff":{"path":"jsonDiff","id":"jsonDiff","parentId":"@@/global-layout"},"imgScan":{"path":"imgScan","id":"imgScan","parentId":"@@/global-layout"},"chrono":{"path":"chrono","id":"chrono","parentId":"@@/global-layout"},"index":{"path":"/","id":"index","parentId":"@@/global-layout"},"home":{"path":"home","id":"home","parentId":"@@/global-layout"},"@@/global-layout":{"id":"@@/global-layout","path":"/","isLayout":true}} as const; return { routes, routeComponents: { @@ -31,6 +31,7 @@ export async function getRoutes() { 'imageSlicing': React.lazy(() => import(/* webpackChunkName: "src__pages__imageSlicing" */'../../../src/pages/imageSlicing.tsx')), 'jsonDiff': React.lazy(() => import(/* webpackChunkName: "src__pages__jsonDiff" */'../../../src/pages/jsonDiff.tsx')), 'imgScan': React.lazy(() => import(/* webpackChunkName: "src__pages__imgScan" */'../../../src/pages/imgScan.tsx')), +'chrono': React.lazy(() => import(/* webpackChunkName: "src__pages__chrono" */'../../../src/pages/chrono.tsx')), 'index': React.lazy(() => import(/* webpackChunkName: "src__pages__index" */'../../../src/pages/index.tsx')), 'home': React.lazy(() => import(/* webpackChunkName: "src__pages__home" */'../../../src/pages/home.tsx')), '@@/global-layout': React.lazy(() => import(/* webpackChunkName: "layouts__index" */'/Users/xutaotao/Documents/s/XTools/src/layouts/index.tsx')), diff --git a/src/assets/img/time.svg b/src/assets/img/time.svg new file mode 100644 index 0000000..4c47f60 --- /dev/null +++ b/src/assets/img/time.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/layouts/menu.tsx b/src/layouts/menu.tsx index b84e96d..47cbe79 100644 --- a/src/layouts/menu.tsx +++ b/src/layouts/menu.tsx @@ -5,6 +5,7 @@ import JsonSvg from "@/assets/img/json.svg"; import JsonDiffSvg from "@/assets/img/jsonDiff.svg"; import imgScanSvg from "@/assets/img/imgScan.svg"; import imgFormatConversion from "@/assets/img/imgFormatConversion.svg"; +import timeSvg from "@/assets/img/time.svg"; export const NAV_MAP = [ { @@ -48,4 +49,10 @@ export const NAV_MAP = [ icon: , des:'图片格式互相转换' }, + { + itemKey: "/chrono", + text: "倒计时", + icon: , + des:'用于监控事物的持续时间' + }, ]; \ No newline at end of file diff --git a/src/pages/chrono.tsx b/src/pages/chrono.tsx new file mode 100644 index 0000000..b9b5a07 --- /dev/null +++ b/src/pages/chrono.tsx @@ -0,0 +1,61 @@ +import React, { useState, useEffect, useRef, useCallback } from 'react'; +import { Card, Space } from 'antd'; +import { Button, Typography } from '@douyinfe/semi-ui'; +import { formatMs } from '@/utils/index'; + +const {Title} = Typography; + +const ChronoComponent = () => { + const [isRunning, setIsRunning] = useState(false); + const [counter, setCounter] = useState(0); + const previousRafDateRef = useRef(Date.now()); + const requestIdRef:any = useRef(null); + + const rafCallback = useCallback(() => { + const deltaMs = Date.now() - previousRafDateRef.current; + previousRafDateRef.current = Date.now(); + setCounter((prevCounter) => prevCounter + deltaMs); + requestIdRef.current = requestAnimationFrame(rafCallback); + }, []); + + useEffect(() => { + if (isRunning) { + previousRafDateRef.current = Date.now(); + requestIdRef.current = requestAnimationFrame(rafCallback); + } else { + cancelAnimationFrame(requestIdRef.current); + } + }, [isRunning, rafCallback]); + + const resume = () => { + setIsRunning(true); + }; + + const pause = () => { + setIsRunning(false); + }; + + const reset = () => { + setCounter(0); + setIsRunning(false); + cancelAnimationFrame(requestIdRef.current); + }; + + return ( +
+ + {formatMs(counter)} + + + {!isRunning ? ( + + ) : ( + + )} + + +
+ ); +}; + +export default ChronoComponent; \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts index d5358ee..cdcf723 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -16,4 +16,16 @@ export function createRandomArray(length: number, min = 1, max = 1000) { return extension.toLowerCase(); } return ''; +} + +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 + .toString() + .padStart(3, '0')}`; } \ No newline at end of file