feat(components): 新增设备管理相关组件和仪表盘组件 feat(hooks): 添加自定义hooks用于API调用和数据管理 style: 优化滚动条样式和模态框布局 chore: 清理无用脚本和调试文件 docs: 更新组件导出文件
39 lines
1.0 KiB
React
39 lines
1.0 KiB
React
import React, { useState, useEffect, useRef } from 'react';
|
|
|
|
const AnimatedCounter = ({ value, duration = 1500 }) => {
|
|
const [displayValue, setDisplayValue] = useState(0);
|
|
const animationRef = useRef(null);
|
|
const startTimeRef = useRef(null);
|
|
|
|
useEffect(() => {
|
|
const animate = (currentTime) => {
|
|
if (!startTimeRef.current) {
|
|
startTimeRef.current = currentTime;
|
|
}
|
|
|
|
const elapsed = currentTime - startTimeRef.current;
|
|
const progress = Math.min(elapsed / duration, 1);
|
|
const easeOutQuart = 1 - Math.pow(1 - progress, 4);
|
|
const currentValue = Math.floor(easeOutQuart * value);
|
|
|
|
setDisplayValue(currentValue);
|
|
|
|
if (progress < 1) {
|
|
animationRef.current = requestAnimationFrame(animate);
|
|
}
|
|
};
|
|
|
|
animationRef.current = requestAnimationFrame(animate);
|
|
|
|
return () => {
|
|
if (animationRef.current) {
|
|
cancelAnimationFrame(animationRef.current);
|
|
}
|
|
};
|
|
}, [value, duration]);
|
|
|
|
return <span>{displayValue}</span>;
|
|
};
|
|
|
|
export default React.memo(AnimatedCounter);
|