refactor: initial pass at rewriting the CircularProgress component

This commit is contained in:
Derrick Hammer 2023-10-13 01:49:52 -04:00
parent 3d2b9ddbec
commit 11ceeb7916
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
1 changed files with 56 additions and 22 deletions

View File

@ -117,6 +117,15 @@ const NetworkIndicator = ({ network }: { network: Network }) => {
</div> </div>
); );
}; };
function getTextDimensions(
fontSize: number,
ratios: { width: number; height: number },
) {
const width = fontSize * ratios.width;
const height = fontSize * ratios.height;
return { width, height };
}
const CircularProgress = ({ const CircularProgress = ({
chain, chain,
@ -125,8 +134,35 @@ const CircularProgress = ({
chain: Network; chain: Network;
className?: string; className?: string;
}) => { }) => {
const progressOffset = ((100 - chain.sync) / 100) * 282.74; // These math are not mathing const [fontRatio, setFontRatio] = useState({
const textOffset = (chain.sync / 100) * (30 - 44) + 44; width: 0,
height: 0,
});
const radius = 45;
const SVG_SIZE = radius * 2 + 10; // +10 to add some padding around
const STROKE_WIDTH = radius * 0.08; // 8% of the radius for the stroke width
const textSize = radius * 0.5; // half of the radius for text size
useEffect(() => {
const testText = document.createElement("span");
testText.style.fontSize = `${textSize}px`;
testText.style.position = "absolute";
testText.style.left = "-9999px";
testText.textContent = "The quick brown fox jumps over the lazy dog";
document.body.appendChild(testText);
const rect = testText.getBoundingClientRect();
setFontRatio({
width: rect.width / textSize,
height: rect.height / textSize,
});
document.body.removeChild(testText);
}, [textSize]);
const { width: textWidth } = getTextDimensions(textSize, fontRatio);
const circumference = 2 * Math.PI * radius;
const offset = circumference * ((100 - chain.sync) / 100);
return ( return (
<svg <svg
@ -134,38 +170,36 @@ const CircularProgress = ({
className, className,
chainIndicatorVariant({ syncState: chain.syncState }), chainIndicatorVariant({ syncState: chain.syncState }),
])} ])}
width="36" width={SVG_SIZE}
height="36" height={SVG_SIZE}
viewBox="0 0 100 100" viewBox={`0 0 ${SVG_SIZE} ${SVG_SIZE}`}
version="1.1" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
style={{ transform: "rotate(-90deg)" }}> style={{ transform: "rotate(-90deg)" }}>
<circle <circle
r="45" r={radius}
cx="50" cx={SVG_SIZE / 2}
cy="50" cy={SVG_SIZE / 2}
fill="transparent" fill="transparent"
stroke="#e0e0e0" stroke="#e0e0e0"
strokeWidth="4px" strokeWidth={STROKE_WIDTH}
strokeDasharray="282.74px" strokeDasharray={`${circumference}px`}></circle>
strokeDashoffset="0"></circle>
<circle <circle
r="45" r={radius}
cx="50" cx={SVG_SIZE / 2}
cy="50" cy={SVG_SIZE / 2}
stroke="currentColor" stroke="currentColor"
strokeWidth="4px" strokeWidth={STROKE_WIDTH}
strokeLinecap="round" strokeLinecap="round"
strokeDashoffset={`${progressOffset}px`} strokeDashoffset={`${offset}px`}
fill="transparent" fill="transparent"
strokeDasharray="282.74px"></circle> strokeDasharray={`${circumference}px`}></circle>
<text <text
x={textOffset} x={(SVG_SIZE - textWidth) / 2}
y="57.5px" y={(SVG_SIZE + textSize) / 2} // Adding half of the text size for vertical centering
fill="currentColor" fill="currentColor"
fontSize="26px" fontSize={`${textSize}px`}
fontWeight="normal" fontWeight="normal">
style={{ transform: "rotate(90deg) translate(0px, -98px)" }}>
{chain.sync} {chain.sync}
</text> </text>
</svg> </svg>