jingrow/components/common/ProgressBar.jsx
2025-06-17 15:23:37 +08:00

84 lines
1.9 KiB
JavaScript

"use client";
import React, { useState, useRef, useEffect } from "react";
const ProgressBarComponent = ({ max }) => {
const [counted, setCounted] = useState(0);
const targetElement = useRef(null);
const startCountup = () => {
const intervalId = setInterval(() => {
setCounted((prevCounted) => {
const newCounted = prevCounted + 1;
if (newCounted >= max) {
clearInterval(intervalId);
}
return newCounted;
});
}, 2000 / max);
};
useEffect(() => {
const handleIntersection = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
startCountup();
observer.unobserve(entry.target);
}
});
};
const options = {
root: null,
rootMargin: "0px",
threshold: 0.5,
};
const observer = new IntersectionObserver(handleIntersection, options);
if (targetElement.current) {
observer.observe(targetElement.current);
}
return () => {
if (targetElement.current) {
observer.unobserve(targetElement.current);
}
};
}, [max]);
return (
<>
<svg
ref={targetElement}
viewBox="0 0 100 6"
preserveAspectRatio="none"
style={{ display: "block", width: `${counted}%` }}
>
<path d="M 0,3 L 100,3" stroke="#eee" strokeWidth="6" fillOpacity="0" />
<path
d="M 0,3 L 100,3"
stroke="#555"
strokeWidth="6"
fillOpacity="0"
style={{ strokeDasharray: "100, 100", strokeDashoffset: 0 }}
/>
</svg>
<div
className="progressbarComponent-text"
style={{
color: "inherit",
position: "absolute",
right: "0px",
top: "-30px",
padding: "0px",
margin: "0px",
}}
>
{counted} %
</div>
</>
);
};
export default ProgressBarComponent;