Last active
September 8, 2024 04:45
-
-
Save Evavic44/4ca8d9793ed5206d6f6b5ee074fbb71b to your computer and use it in GitHub Desktop.
Animated progress bar circle with SVG
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect } from "react"; | |
export default function ProgressBar() { | |
const scheme = "#BD2546"; // hardcode progress bar theme or make it dynamic | |
const progress = 78; // progress value | |
function handleProgress(value: number, circle: "track" | "progress") { | |
const track = 2 * 3.14 * 90; | |
const progress = track * ((100 - value) / 100); | |
return circle === "track" ? track : progress; | |
} | |
// handle progress animation dynamically | |
useEffect(() => { | |
const style = document.createElement("style"); | |
style.type = "text/css"; | |
style.innerHTML = ` | |
@keyframes dash { | |
from { | |
stroke-dashoffset: ${handleProgress(progress, "track")}; | |
} | |
to { | |
stroke-dashoffset: ${handleProgress(progress, "progress")}; | |
} | |
} | |
`; | |
document.head.appendChild(style); | |
return () => { | |
document.head.removeChild(style); | |
}; | |
}, [progress]); | |
return ( | |
<div className="relative"> | |
<svg | |
width="180" | |
height="180" | |
viewBox="-25 -25 250 250" | |
version="1.1" | |
xmlns="http://www.w3.org/2000/svg" | |
className="-rotate-90" | |
> | |
<circle | |
r="90" | |
cx="100" | |
cy="100" | |
fill="transparent" | |
strokeWidth="16px" | |
strokeDasharray="565.48px" | |
strokeDashoffset="0" | |
className="dark:stroke-zinc-900 stroke-light-mediumgrey" | |
></circle> | |
<circle | |
r="90" | |
cx="100" | |
cy="100" | |
strokeWidth="16px" | |
strokeLinecap="round" | |
fill="transparent" | |
strokeDasharray={handleProgress(progress, "track")} | |
stroke={scheme} | |
className="animate-dash" | |
style={{ animation: "dash 1.5s ease-in-out forwards" }} | |
></circle> | |
</svg> | |
<em className="font-bold text-2xl not-italic absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"> | |
{progress}% | |
</em> | |
</div> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Result