Issue
I would like to make a progress bar that loops over and over again after it finishes. I have tried different approaches and searched from the web but cant figure out how to do it. I am able to make a progress bar that resets it self after "progress is full" but it does not start automaticly again and I have to press a button every time I want it to run.
This is what I want to achieve = https://imgur.com/a/FhJctaE This is what I have right now = https://imgur.com/a/bTUzxyr
Can any of you help me with this :)
My code:
export default function Home() {
const [animationDuration, setAnimationDuration] = useState("0s");
const [isAnimating, setIsAnimating] = useState(false);
const [timerId, setTimerId] = useState<any>(null);
const handleTimer = (duration: number) => {
if (isAnimating) {
stopTimer();
} else {
startTimer(duration);
}
};
const startTimer = (duration: number) => {
const id = setTimeout(() => {
setIsAnimating(false);
setAnimationDuration("0s");
}, duration);
setTimerId(id);
setIsAnimating(true);
setAnimationDuration(`${duration / 1000}s`);
};
const stopTimer = () => {
clearTimeout(timerId as number);
setIsAnimating(false);
setAnimationDuration("0s");
};
return (
<div >
<div>
<div>Timer</div>
<div style={{ position: "relative" }}>
<div
className={`absolute w-[0px] bg-slate-300 h-4 rounded ${
isAnimating ? "animate-growWidth" : ""
}`}
style={{ animationDuration }}
></div>
<div></div>
</div>
<div>
<button
onClick={() => handleTimer(1500)} // 1.5s duration>
1.5s
</button>
<button
onClick={() => handleTimer(5000)} // 5s duration>
5s
</button>
</div>
</div>
</div>
);
}
CSS:
@keyframes growWidth {
0% {
width: 0;
}
100% {
width: 300px;
}
}
.animate-growWidth {
animation: growWidth 3s linear forwards;
}
Solution
Consider applying animation-iteration-count: infinite
. By default, animation-iteration-count
is 1
. Setting to infinite
will mean it will play indefinitely.
You'd also want to set the animation-duration
that is smaller that the overall duration you want the bar to animate for. This is so that you would be able to see the bar repeating the animation before it stops.
const { useState } = React;
function Home() {
const [animationDuration, setAnimationDuration] = useState("0s");
const [isAnimating, setIsAnimating] = useState(false);
const [timerId, setTimerId] = useState(null);
const handleTimer = (duration) => {
if (isAnimating) {
stopTimer();
} else {
startTimer(duration);
}
};
const startTimer = (duration) => {
const id = setTimeout(() => {
setIsAnimating(false);
setAnimationDuration("0s");
}, duration);
setTimerId(id);
setIsAnimating(true);
setAnimationDuration('700ms');
};
const stopTimer = () => {
clearTimeout(timerId);
setIsAnimating(false);
setAnimationDuration("0s");
};
return (
<div>
<div>
<div>Timer</div>
<div style={{ position: "relative" }}>
<div
className={`absolute w-[0px] bg-slate-300 h-4 rounded ${
isAnimating ? "animate-growWidth" : ""
}`}
style={{ animationDuration }}
></div>
<div></div>
</div>
<div>
<button onClick={() => handleTimer(1500)}>1.5s</button>
<button onClick={() => handleTimer(5000)}>5s</button>
</div>
</div>
</div>
);
}
ReactDOM.createRoot(document.getElementById("app")).render(<Home />);
@keyframes growWidth {
0% {
width: 0;
}
100% {
width: 300px;
}
}
.animate-growWidth {
animation: growWidth 3s linear forwards infinite;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com/3.4.0"></script>
<div id="app"></div>
Answered By - Wongjn
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.