Spinner.tsx

import { Box, Slider, SvgIcon, useTheme } from '@mui/material';
import React, { useState } from 'react';
export const Spinner = () => {
  const theme = useTheme();
  const [value, setValue] = useState(50);
  const size = 500;
  const strokeWidth = 8;
  const radius = 50 - strokeWidth / 2;
  const circumference = 2 * Math.PI * radius;
  const lineCap = strokeWidth / 2;
  const reversedValue = 100 - value;
  const reversedRotation = 360 * (value / 100);
  const gap = lineCap;
  const minSegmentPercentForFullGap = ((gap + lineCap * 2) / circumference) * 100;
  const effectiveGap = gap * Math.max(0, Math.min(1, Math.min(value, reversedValue) / minSegmentPercentForFullGap));
  const dashLength = Math.max((value / 100) * circumference - effectiveGap - lineCap * 2, 0);
  const dashOffset = -(lineCap + effectiveGap);
  const reversedDashLength = Math.max((reversedValue / 100) * circumference - effectiveGap - lineCap * 2, 0);
  return (
    <>
      <SvgIcon
        sx={{
          width: `${size}px`,
          height: `${size}px`,
        }}
        viewBox="0 0 100 100"
      >
        {(reversedDashLength > 0 || value === 0) && (
          <circle
            cx="50"
            cy="50"
            r={radius}
            fill="none"
            stroke={theme.palette.onSurface.os100}
            strokeWidth={strokeWidth}
            strokeLinecap="round"
            strokeDasharray={`${reversedDashLength} ${circumference}`}
            strokeDashoffset={dashOffset}
            transform={`rotate(${reversedRotation} 50 50)`}
            {...(value === 0 && {
              strokeLinecap: 'butt',
              strokeDasharray: 'none',
              strokeDashoffset: 'none',
            })}
          />
        )}
        {(dashLength > 0 || value === 100) && (
          <circle
            cx="50"
            cy="50"
            r={radius}
            fill="none"
            stroke={theme.palette.brand.primary}
            strokeWidth={strokeWidth}
            strokeLinecap="round"
            strokeDasharray={`${dashLength} ${circumference}`}
            strokeDashoffset={dashOffset}
            {...(value === 100 && {
              strokeLinecap: 'butt',
              strokeDasharray: 'none',
              strokeDashoffset: 'none',
            })}
          />
        )}
      </SvgIcon>
      <Box sx={{ width: '500px' }}>
        <Slider value={value ?? 0} onChange={(_, nw) => setValue(nw as number)} />
      </Box>
    </>
  );
};