I am encountering a problem with handling an animation of a progress bar in my code. The issue arises when I pause the animation, as it seems to slightly backtrack instead of pausing at the correct position upon clicking a button. Can someone help identify what's wrong in my code?
It's important to note that this is just a simplified version and I prefer not to mess with class removal since in the actual code, I need to restart the animation under certain conditions.
const { useState, useEffect } = React;
const App = () => {
const totalTime = 10;
const [timeLeft, setTimeLeft] = useState(totalTime);
const [isTimerAnimated, setIsTimerAnimated] = useState(true);
useEffect(() => {
const interval = setInterval(() => {
if (timeLeft > 0 && isTimerAnimated) {
setTimeLeft((prevTimeLeft) => prevTimeLeft - 1);
}
}, 1000);
return () => clearInterval(interval);
}, [timeLeft, isTimerAnimated]);
const handleAnimationState = () => {
if (isTimerAnimated) {
setIsTimerAnimated(false);
} else {
setIsTimerAnimated(true);
setTimeLeft(totalTime);
}
};
return (
<div>
<div className="progress-bar">
<div
className={`${isTimerAnimated ? "animated" : ""}`}
style={{
transform: `scaleX(${timeLeft ? timeLeft / totalTime : 0})`,
animationDuration: `${totalTime}s`,
}}
/>
</div>
<button onClick={handleAnimationState}>{isTimerAnimated ? "Pause the animation" : "Restart the animation"}</button>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
@keyframes timerAnimation {
from {
transform: scaleX(1);
}
to {
transform: scaleX(0);
}
}
.progress-bar {
height: 10px;
width: 300px;
background-color: #fdb913;
border-radius: 10px;
overflow: hidden;
margin-top: 2rem;
margin-bottom: 3rem;
}
.progress-bar div {
background-color: grey;
height: 100%;
animation-play-state: paused;
animation-fill-mode: forwards;
transform-origin: left center;
}
.progress-bar div.animated {
animation: timerAnimation linear;
animation-play-state: running;
}
<div id="root">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"></script>
</div>