Размещение linear gradient в circle исходя из процентов заполнения

Требуется реализовать данный комопнент:

введите сюда описание изображения

Пока сделал такой компонент в react но теперьб не знаю как правильно расчитать позиционированния градиента, может кто-то поможет?

Пример кода:

body {
  background: black;
}
<script src="https://cdn.tailwindcss.com"></script>
<div class='relative size-52'>
  <svg fill="none" class="size-full -rotate-90" stroke-width="2" view-box="0 0 212 212">
    <defs>
      <linearGradient id="circle-gradient" x1="100%" y1="0%" x2="0%" y2="100%">
        <stop offset="60%" stop-opacity="0" stop-color="white" />
        <stop offset="75%" stop-opacity="1" stop-color="white" />
      </linearGradient>
    </defs>
    <circle
      cx="106"
      cy="106"
      r="90"
      stroke-width="12"
      stroke="url(#circle-gradient)"
      stroke-dasharray="282.7433388230814 282.743338823"
      class="opacity-100"
      />
      <circle cx="106" cy="106" r="90" stroke-width="12" class="opacity-30 stroke-white" />
      <circle cx="16" cy="106.00000000000001" r="12" fill="white" class="drop-shadow" />
  </svg>
  <div class="absolute inset-0 m-auto size-fit p-4 text-center text-white text-[48px] font-bold">
    40
  </div>
</div>

Код компонента:

import React, { ReactNode } from 'react';

import { cn } from '@/lib/utils';

const CircleCountdown = ({
  max = 100,
  min = 0,
  value = 0,
  className = '',
  children,
}: {
  value: number
  max?: number
  min?: number
  className?: string
  children?: ReactNode
}) => {
  const percent = ((value - min) / (max - min)) * 100;
  const circumference = 2 * 90 * Math.PI;
  const draw = percent * circumference / 100;

  const angle = (percent / 100) * 2 * Math.PI;
  const endX = 106 + 90 * Math.cos(angle);
  const endY = 106 + 90 * Math.sin(angle);

  return (
    <div className={cn('relative size-52', className)}>
      <svg fill="none" className="size-full -rotate-90" strokeWidth="2" viewBox="0 0 212 212">
        <defs>
          <linearGradient id="circle-gradient" x1="100%" y1="0%" x2="0%" y2="100%">
            <stop offset="60%" stopOpacity="0" stopColor="white" />
            <stop offset="75%" stopOpacity="1" stopColor="white" />
          </linearGradient>
        </defs>
        <circle
          cx="106"
          cy="106"
          r="90"
          strokeWidth="12"
          stroke="url(#circle-gradient)"
          strokeDasharray={`${draw} ${circumference - draw}`}
          className="opacity-100"
        />
        <circle cx="106" cy="106" r="90" strokeWidth="12" className="opacity-30 stroke-white" />
        <circle cx={endX} cy={endY} r="12" fill="white" className="drop-shadow" />
      </svg>
      <div className="absolute inset-0 m-auto size-fit p-4 text-center">
        {children}
      </div>
    </div>
  );
};

export { CircleCountdown };

Ответы (0 шт):