anitimejs
Version:
Thư viện xử lý chuỗi số và thời gian trong JavaScript/Typescript
134 lines (133 loc) • 4.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
const useTimer = ({ initialStartTime = Date.now(), autoStart = false, interval = 1000, onTick, } = {}) => {
const [startTime, setStartTime] = (0, react_1.useState)(initialStartTime);
const [elapsedTime, setElapsedTime] = (0, react_1.useState)(0);
const [offsetTime, setOffsetTime] = (0, react_1.useState)(Math.floor(initialStartTime / 1000));
const [timeDifference, setTimeDifference] = (0, react_1.useState)(0);
const [isRunning, setIsRunning] = (0, react_1.useState)(autoStart);
const [startedAt, setStartedAt] = (0, react_1.useState)(autoStart ? Date.now() : null);
const [pausedAt, setPausedAt] = (0, react_1.useState)(null);
const timerRef = (0, react_1.useRef)(null);
const isRunningRef = (0, react_1.useRef)(autoStart);
const updateTimes = (0, react_1.useCallback)(() => {
const now = Date.now();
if (isRunningRef.current) {
setElapsedTime((prev) => prev + 1);
setOffsetTime((prev) => prev + 1);
setTimeDifference(Math.floor((now - startTime) / 1000));
// Gọi callback onTick nếu được cung cấp
if (onTick) {
onTick({
elapsedTime: elapsedTime + 1,
offsetTime: offsetTime + 1,
timeDifference: Math.floor((now - startTime) / 1000),
isRunning: true,
startedAt,
pausedAt
});
}
}
}, [startTime, elapsedTime, offsetTime, onTick, startedAt, pausedAt]);
const start = (0, react_1.useCallback)(() => {
if (!isRunningRef.current) {
const now = Date.now();
isRunningRef.current = true;
setIsRunning(true);
setStartedAt(now);
setPausedAt(null);
// Xóa interval cũ nếu có
if (timerRef.current) {
clearInterval(timerRef.current);
}
timerRef.current = setInterval(updateTimes, interval);
}
}, [updateTimes, interval]);
const stop = (0, react_1.useCallback)(() => {
if (isRunningRef.current && timerRef.current) {
clearInterval(timerRef.current);
timerRef.current = null;
isRunningRef.current = false;
setIsRunning(false);
setPausedAt(Date.now());
}
}, []);
const reset = (0, react_1.useCallback)((startImmediately = false) => {
stop();
const now = Date.now();
setStartTime(now);
setElapsedTime(0);
setOffsetTime(Math.floor(now / 1000));
setTimeDifference(0);
setPausedAt(null);
setStartedAt(null);
if (startImmediately) {
setStartedAt(now);
setIsRunning(true);
isRunningRef.current = true;
timerRef.current = setInterval(updateTimes, interval);
}
}, [stop, updateTimes, interval]);
const setTime = (0, react_1.useCallback)((newTime) => {
if (typeof newTime !== "number" || newTime < 0) {
console.error("Invalid time provided to setTime");
return;
}
const wasRunning = isRunningRef.current;
stop();
setStartTime(newTime);
setElapsedTime(0);
setOffsetTime(Math.floor(newTime / 1000));
setTimeDifference(0);
// Khởi động lại nếu đang chạy trước đó
if (wasRunning) {
start();
}
}, [stop, start]);
const toggle = (0, react_1.useCallback)(() => {
if (isRunningRef.current) {
stop();
}
else {
start();
}
}, [start, stop]);
// Định dạng thời gian thành chuỗi
const formatTime = (0, react_1.useCallback)((format = "HH:MM:SS") => {
const seconds = elapsedTime % 60;
const minutes = Math.floor(elapsedTime / 60) % 60;
const hours = Math.floor(elapsedTime / 3600);
const padZero = (num) => num.toString().padStart(2, '0');
return format
.replace('HH', padZero(hours))
.replace('MM', padZero(minutes))
.replace('SS', padZero(seconds));
}, [elapsedTime]);
// Khởi động timer nếu autoStart = true
(0, react_1.useEffect)(() => {
if (autoStart) {
start();
}
return () => {
if (timerRef.current) {
clearInterval(timerRef.current);
}
};
}, [autoStart, start]);
return {
elapsedTime,
offsetTime,
timeDifference,
isRunning,
startedAt,
pausedAt,
start,
stop,
reset,
setTime,
toggle,
formatTime
};
};
exports.default = useTimer;