const { useEffect, useState, useRef } = React;
const useAnimationFrame = (callback, running) => {
const savedCallback = useRef(callback);
const animationFrameId = useRef(0);
useEffect(() => {
savedCallback.current = callback;
});
useEffect(() => {
function tick() {
if (typeof savedCallback.current === 'function') {
savedCallback.current();
}
if (running) {
animationFrameId.current = window.requestAnimationFrame(tick);
}
}
if (running) {
const animationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame;
const cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame;
animationFrameId.current = animationFrame(tick);
return () => cancelAnimationFrame(animationFrameId.current);
}
}, [running]);
};
const Progress = ({
startNum = 0,
endNum = 100,
step = 1,
running = true,
onStart = () => {}, // 开始的回调
onStep = () => {}, // 每一步的回调
onEnd = () => {}, // 结束时的回调
}) => {
const [progress, setProgress] = useState(startNum);
onStart();
useAnimationFrame(() => {
const nextProgress = Math.min(progress + step, endNum);
if (nextProgress <= endNum) {
setProgress(nextProgress);
onStep(nextProgress);
} else {
onEnd();
}
}, running && progress < endNum);
return <p>{progress}</p>;
};
const Home = () => {
const [startNum, setStartNum] = useState(0);
const endNum = 10000;
const [count, setCount] = useState(0);
const [running, setRunning] = useState(false);
const [step, setStep] = useState(20);
const [progress, setProgress] = useState(0);
return (
<div className="home">
<Progress running={running} step={step} startNum={startNum} endNum={endNum} onStep={setProgress} />
<p><progress className="progress" value={progress} max={endNum}></progress></p>
<div class="manager">
<p>
step: {step} <input type="button" value="-" onClick={() => setStep(Math.max(1, step - 1))} />
<input type="button" value="+" onClick={() => setStep(Math.min(100, step + 1))} />
</p>
<p>开始:<input type="button" value="start" onClick={() => setRunning(true)} /></p>
<p>暂停:<input type="button" value="pause" onClick={() => setRunning(false)} /></p>
<p>切换:<input type="button" value="toggle" onClick={() => setRunning(!running)} /></p>
</div>
</div>
);
};
ReactDOM.render(<Home />, document.getElementById('app'));