Прогресс бар заполняется в обратном порядке

Т.е. когда stroke-dashoffset="565.48", то круг пустой, а когда stroke-dashoffset="0", то круг заполнен

Как инвертировать stroke-dashoffset? В рамках svg файла.

<svg width="200" height="200" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(-90deg)">
    <!-- Фоновый круг -->
    <circle
      r="90"
      cx="100"
      cy="100" 
      fill="transparent" 
      stroke="#e0e0e0" 
      stroke-width="16px" 
      stroke-dasharray="565.48px" 
      stroke-dashoffset="0">
    </circle>
    <!-- Круговой прогресс -->
    <circle 
      id="procent_circle"
      r="90" 
      cx="100" 
      cy="100" 
      stroke="#76e5b1" 
      stroke-width="16px" 
      stroke-dashoffset="565.48" 
      fill="transparent" 
      stroke-dasharray="565.48px">
    </circle>
    <!-- Текстовое поле для отображения процентов -->
    <text
      id="procent"
      x="73px" 
      y="117px" 
      fill="#6bdba7"
      font-size="52px" 
      font-weight="bold" 
      style="transform:rotate(90deg) translate(0px, -196px)">
      58
    </text>
</svg>


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

Автор решения: Alexandr_TT

Т.е. когда stroke-dashoffset="565.48", то круг пустой, а когда stroke-dashoffset="0", то круг заполнен

Всё правильно,- так и должно быть.
stroke-dashoffset Даже из названия атрибута понятно, что это отступ линии от начальной точки.
Если отступ максимален - 565.48, то строка пустая.
Если отступа нет - stroke-dashoffset="0" строка заполнена полностью.
Так как circle это окружность, кольцо, у которого нет начала и конца, то анимация с использованием stroke-dashoffset невозможна.
Просто отступы считать неоткуда.

Поэтому окружность нужно создавать с помощью path, либо для circle использовать анимацию stroke-dasharray

<svg width="200" height="200" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(-90deg)">
    <!-- Фоновый круг -->
    <circle
      r="90"
      cx="100"
      cy="100" 
      fill="transparent" 
      stroke="#e0e0e0" 
      stroke-width="16px" >
      </circle>
    <!-- Круговой прогресс -->
    <circle 
      id="procent_circle"
      r="90" 
      cx="100" 
      cy="100" 
      stroke="#76e5b1" 
      stroke-width="16px" 
      fill="transparent" 
      stroke-dasharray="0,565.48"
      stroke-dashoffset="565.48">
       <animate attributeName="stroke-dasharray" begin="0.2s" dur="2s" values="0, 565.48;565.48,0 "  repeatCount="indefinite" />   
    </circle>
    <!-- Текстовое поле для отображения процентов -->
    <text
      id="procent"
      x="73px" 
      y="117px" 
      fill="#6bdba7"
      font-size="52px" 
      font-weight="bold" 
      style="transform:rotate(90deg) translate(0px, -196px)">
      58
    </text>
</svg>

<animate attributeName="stroke-dasharray" begin="0.2s" dur="2s" values="0, 565.48;565.48,0 " repeatCount="indefinite" />

Секрет этой анимации в значении: values="0, 565.48;565.48,0 ",где
0, 565.48 - черта установлена в нулевое значение, а пробел максимален

565.48,0 - черта максимальна, пробел равен нулю.

В результате анимации зеленая черта растет от нуля до максимума

→ Ссылка
Автор решения: Leonid

Не знаю какой именно эффект должен быть, но если изменить "массив штрихов" на схему:

stroke-dasharray="0px 565.48px 565.48px"

И запустить анимацию, предложенную @Alexandr_TT, то вполне можно запустить прогресс-бар, меняя как раз stroke-dashoffset от 0 до 565,48:

<animate attributeName="stroke-dashoffset" begin="0.2s" dur="2s" values="0;565.48" repeatCount="indefinite" />

<svg width="200" height="200" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(-90deg)">
    <!-- Фоновый круг -->
    <circle
      r="90"
      cx="100"
      cy="100" 
      fill="transparent" 
      stroke="#e0e0e0" 
      stroke-width="16px" 
      stroke-dasharray="0px 565.48px 565.48px"
      stroke-dashoffset="0">
      <animate attributeName="stroke-dashoffset" begin="0.2s" dur="2s" values="0;565.48"  repeatCount="indefinite" /> 
    </circle>
    <!-- Круговой прогресс -->
    <circle 
      id="procent_circle"
      r="90" 
      cx="100" 
      cy="100" 
      stroke="#76e5b1" 
      stroke-width="16px" 
      stroke-dashoffset="565.48" 
      fill="transparent" 
      stroke-dasharray="565.48px">
    </circle>
    <!-- Текстовое поле для отображения процентов -->
    <text
      id="procent"
      x="73px" 
      y="117px" 
      fill="#6bdba7"
      font-size="52px" 
      font-weight="bold" 
      style="transform:rotate(90deg) translate(0px, -196px)">
      58
    </text>
</svg>

→ Ссылка
Автор решения: De.Minov

Когда stroke-dashoffset="565.48", то круг пустой, а когда stroke-dashoffset="0", то круг заполнен

В вашем вопросе уже есть ответ, можно просто уменьшать значение stroke-dashoffset - т.е. 100% = 0, 0% = 565.48.
Формула: dash-array * (1 - percent / 100).

Ещё я упростил код SVG:

const input = document.querySelector('input[type="range"]');

const getPercent = () => {
  const value = +input.value;

  document.querySelectorAll('svg').forEach((svg) => {
    const percent = svg.querySelector('.percent');
    const text = svg.querySelector('.text');

    const dashArray = +percent.getAttribute('stroke-dasharray');
    percent.setAttribute('stroke-dashoffset', dashArray * (1 - value / 100));

    text.textContent = value;
  });
}

getPercent();
input.addEventListener('change', getPercent);
input.addEventListener('mousemove', getPercent);
body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 2em;
  width: 100%;
  height: 100vh;
  margin: 0;
}

.demo {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1em;
}

svg {
  width: 120px;
  height: auto;
}
<div class="demo">
  <svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
    <g stroke-width="16" fill="transparent" transform="rotate(-90 100 100)">
      <circle cx="100" cy="100" r="90" stroke="#e0e0e0"/>
      <circle class="percent" cx="100" cy="100" r="90" stroke="#76e5b1" stroke-dashoffset="565.48" stroke-dasharray="565.48"/>
    </g>
    <text class="text" x="100" y="113" fill="#6bdba7" font-size="52" font-weight="bold" dominant-baseline="top" text-anchor="middle">0</text>
  </svg>
  <svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
    <g stroke-width="16" fill="transparent" transform="rotate(-90 100 100) scale(1 -1) translate(0 -200)">
      <circle cx="100" cy="100" r="90" stroke="#e0e0e0"/>
      <circle class="percent" cx="100" cy="100" r="90" stroke="#76e5b1" stroke-dashoffset="565.48" stroke-dasharray="565.48"/>
    </g>
    <text class="text" x="100" y="113" fill="#6bdba7" font-size="52" font-weight="bold" dominant-baseline="top" text-anchor="middle">0</text>
  </svg>
</div>
<input type="range" min="0" value="50" max="100" step="1" />

А ещё, я не правильно воспринял вопрос, и "развернул" ещё и сам прогресс, как это сделал Leonid.
Только для этого я использовал transform.

→ Ссылка
Автор решения: Alexandr_TT

Анимация stroke-dashoffset

Вариант ответа

Так как circle это окружность, кольцо, у которого нет начала и конца, то анимация с использованием stroke-dashoffset невозможна. Просто отступы считать неоткуда.

Поэтому окружность нужно создавать с помощью path, либо для circle использовать анимацию stroke-dasharray

Анимация с помощью stroke-dasharray рассмотрена в ответе раз и в ответе два

Для анимации stroke-dashoffset рисуем окружность в векторном редакторе.
Начинаем с верхней точки 1, откуда будет начинаться анимация заполнения круга:

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

  1. С помощью инструмента - Рисовать кривые Безье наносим 4 узловые точки по часовой стрелке.
  2. Меняем тип узловых точек на автоматически сглаженные
  3. Траектория круга будет автоматически нарисована. Далее сохраняем файл в формате *.svg и оптимизируем его с помощью SVGOMG

Круг, нарисованный с помощью path готов и его можно будет использовать в анимации stroke-dashoffset

<path  transform="translate(0 -97)" stroke-dashofset="569.57" stroke-dasharray="569.57"
  d="M100 106.9c42.4 0 90 35.2 90 90 0 58-33.1 90.3-90 90.3-43.1 0-90-31.4-90-90.4 0-55.2 47.6-90 90-90z" 
 style="stroke:#76e5b1; stroke-width:16; fill:none;stroke-linecap:butt">      

Код с анимацией:

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200" style="border:0px red  solid">
  
     <!-- Фоновый круг -->
   <path  transform="translate(0 -97)" 
        d="M100 106.9c42.4 0 90 35.2 90 90 0 58-33.1 90.3-90 90.3-43.1 0-90-31.4-90-90.4 0-55.2 47.6-90 90-90z" style="stroke:#e0e0e0; stroke-width:16; fill:none;stroke-linecap:butt">
    </path>     
    
        <!-- Круговой прогресс -->
   
   <path  transform="translate(0 -97)" stroke-dashofset="569.57" stroke-dasharray="569.57"
        d="M100 106.9c42.4 0 90 35.2 90 90 0 58-33.1 90.3-90 90.3-43.1 0-90-31.4-90-90.4 0-55.2 47.6-90 90-90z" style="stroke:#76e5b1; stroke-width:16; fill:none;stroke-linecap:butt">
       <!-- Команда анимации -->
    <animate attributeName="stroke-dashoffset"  dur="4s" values="569.57;0"  repeatCount="indefinite" />
    </path> 
     
     <!-- Текстовое поле для отображения процентов -->
    <text
      id="procent"
      x="73px" 
      y="117px" 
      fill="#6bdba7"
      font-size="52px" 
      font-weight="bold" 
      >
      58
     </text> 
   </svg>

Секрет анимации в значении - values="569.57;0", где

stroke-dashoffset - отступ от начала линии изменяется от максимума до нуля, а это значит, что линия будет увеличиваться от нуля до полного заполнения.

→ Ссылка