Как реализовать плавное закрашивание SVG-элемента?

Мне нужно реализовать пошаговое закрашивание SVG картинки, при наведении на каждый блок определенного шага. введите сюда описание изображения

То есть, при наведении на блок "Тех Диагностика" полоса должна закрашиваться вот так: введите сюда описание изображения Вот код SVG.

      <div class="hidden lg:block xl:hidden absolute top-[195px] left-[90px]">
          <svg class="w-[750px] h-[333px]">
              <use xlink:href="#steps-line"/>
          </svg>
      </div>

А вот код одного из блоков

<div class="flex flex-row xl:ml-[100px] lg:mt-[215px] xl:mt-[120px]">
     <div class="transform translate-y-[-40px]">
          <img src="/static/images/redesign_redemption/step3.svg" alt="step3">
     </div>
     <div>
          <div class="text-xl font-medium mb-[6px]">Оформление документов</div>
          <div class="w-[70px] h-[25px] border-2 text-brand-gray font-bold border-brand-gray-light rounded-2xl text-center mb-[10px]">2 часа</div>
          <div class="text-[14px] mb-[10px]">
               Возьмем на себя оформление<br> полного пакета документов для<br> выкупа вашего авто.
          </div>
      </div>
</div>

Как можно это реализовать? (желательно реализовать это с плавным закрашиванием)


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

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

Используются свойства stroke-dashoffset и stroke-dasharray.

Через stroke-dasharray задаются размеры штрихов.

А stroke-dashoffset их сдвигает.

Анимацию можно делать через CSS @keyframes.

<svg viewBox="0 -5 100 30">
<defs>
<style>
#line{
  animation-name: lineanim;
  animation-duration: 5000ms;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
@keyframes lineanim {
  0%   { stroke-dashoffset: 0px; }
  100% { stroke-dashoffset: 265px; }
}
</style>
</defs>
<path d="M90,20 L15,20 A5,5 0 1 1 15,10 L85,10 A5,5 0 1 0 85,0 L 10,0" stroke="#ccc" stroke-width="2" fill="none"/>
<path id="line" d="M90,20 L15,20 A5,5 0 1 1 15,10 L85,10 A5,5 0 1 0 85,0 L 10,0" stroke="#000" stroke-width="2" fill="none" stroke-dasharray="0 260 0" />

</svg>

Второй пример без анимации @keyframes, но с анимацией перехода transition. Выбираете шаг - линия заполняется.

#step1:checked ~ svg #line {stroke-dashoffset: 0px;}
#step2:checked ~ svg #line {stroke-dashoffset: 65px;}
#step3:checked ~ svg #line {stroke-dashoffset: 130px;}
#step4:checked ~ svg #line {stroke-dashoffset: 195px;}
#step5:checked ~ svg #line {stroke-dashoffset: 260px;}
<input type="radio" name="step" value="1" id="step1"/><label for="step1">Step1</label>
<input type="radio" name="step" value="2" id="step2"/><label for="step2">Step2</label>
<input type="radio" name="step" value="3" id="step3"/><label for="step3">Step3</label>
<input type="radio" name="step" value="4" id="step4"/><label for="step4">Step4</label>
<input type="radio" name="step" value="4" id="step5"/><label for="step5">Step5</label>

<svg viewBox="0 -5 100 30">
<defs>
<style>
#line{
  transition-property: all;
  transition-duration: 500ms;
  transition-timing-function: linear;
}

</style>
</defs>
<path d="M90,20 L15,20 A5,5 0 1 1 15,10 L85,10 A5,5 0 1 0 85,0 L 10,0" stroke="#ccc" stroke-width="2" fill="none"/>
<path id="line" d="M90,20 L15,20 A5,5 0 1 1 15,10 L85,10 A5,5 0 1 0 85,0 L 10,0" stroke="#000" stroke-width="2" fill="none" stroke-dasharray="0 260 0" />

</svg>

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

как-то так

Кликайте по соответствующим пунктам.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" preserveAspectRatio="xMinYMin meet" id="svg4" viewBox="0 0 1000 500">
  <image xlink:href="https://i.stack.imgur.com/vGRBR.png" id="image2" height="100%" width="100%"/>
  <path id="trace" stroke-dasharray="1651" stroke-dashoffset="1651" d="M321 190h369c50 0 53 90 0 90H163c-82 0-83 133-1 133h419"  fill="none" stroke="#2D4461" stroke-width="6" stroke-linecap="round" > 
  <animate id="an1" attributeName="stroke-dashoffset" begin="rect1.click" dur="1.5s" values="1651;1450" fill="freeze" restart="whenNotactive" /> 
      <animate id="an2" attributeName="stroke-dashoffset" begin="rect2.click" dur="2s"    values="1450;1200"    fill="freeze" restart="whenNotactive" /> 
          <animate id="an3" attributeName="stroke-dashoffset" begin="rect3.click" dur="3s" values="1200;350" fill="freeze" restart="whenNotactive" /> 
              <animate id="an4" attributeName="stroke-dashoffset" begin="rect4.click" dur="2s" values="350;0" fill="freeze" restart="whenNotactive" />
  </path>
 
  <g fill="transparent">
 <path id="rect1" d="M64 65h245l3 152-247-2z"  />
  <path id="rect2" d="m664 97 290 1v148l-290-1z"  />
  <path id="rect3" d="M140 289h252l1 116-252-2z" />
  <path id="rect4" d="M597 337h232l-1 125-231 3z" />
  </g>
</svg>

UPDATE

Вариант анимации заполнения трассы при наведении на пункт выполнения работы

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" preserveAspectRatio="xMinYMin meet" id="svg4" viewBox="0 0 1000 500">
  <image xlink:href="https://i.stack.imgur.com/vGRBR.png" id="image2" height="100%" width="100%"/>
  <path id="trace" stroke-dasharray="1651" stroke-dashoffset="1651" d="M321 190h369c50 0 53 90 0 90H163c-82 0-83 133-1 133h419"  fill="none" stroke="#2D4461" stroke-width="6" stroke-linecap="round" > 
  <animate id="an1" attributeName="stroke-dashoffset" begin="rect1.mouseover" dur="1.5s" values="1651;1450" fill="freeze" restart="whenNotactive" /> 
      <animate id="an2" attributeName="stroke-dashoffset" begin="rect2.mouseover" dur="2s"    values="1450;1200"    fill="freeze" restart="whenNotactive" /> 
          <animate id="an3" attributeName="stroke-dashoffset" begin="rect3.mouseover" dur="3s" values="1200;350" fill="freeze" restart="whenNotactive" /> 
              <animate id="an4" attributeName="stroke-dashoffset" begin="rect4.mouseover" dur="2s" values="350;0" fill="freeze" restart="whenNotactive" />
  </path>
 
  <g fill="transparent">
 <path id="rect1" d="M64 65h245l3 152-247-2z"  />
  <path id="rect2" d="m664 97 290 1v148l-290-1z"  />
  <path id="rect3" d="M140 289h252l1 116-252-2z" />
  <path id="rect4" d="M597 337h232l-1 125-231 3z" />
  </g>
</svg>

Вариант с подсветкой выбора, добавлена адаптивность

.container {
width:100vw;
height:auto;
}
.rect:hover {
fill:lime;
fill-opacity:0.3;
cursor: pointer;
        -webkit-filter: drop-shadow(4px 8px 3px rgba(0, 0, 0, 1));
        filter: drop-shadow(4px 8px 3px rgba(0, 0, 0, 1));
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" preserveAspectRatio="xMinYMin meet" id="svg4" viewBox="0 0 1000 500">
  <image xlink:href="https://i.stack.imgur.com/vGRBR.png" id="image2" height="100%" width="100%"/>
  <path id="trace" stroke-dasharray="1651" stroke-dashoffset="1651" d="M321 190h369c50 0 53 90 0 90H163c-82 0-83 133-1 133h419"  fill="none" stroke="#2D4461" stroke-width="6" stroke-linecap="round" > 
  <animate id="an1" attributeName="stroke-dashoffset" begin="rect1.mouseover" dur="1.5s" values="1651;1450" fill="freeze" restart="whenNotactive" /> 
      <animate id="an2" attributeName="stroke-dashoffset" begin="rect2.mouseover" dur="2s"    values="1450;1200"    fill="freeze" restart="whenNotactive" /> 
          <animate id="an3" attributeName="stroke-dashoffset" begin="rect3.mouseover" dur="3s" values="1200;350" fill="freeze" restart="whenNotactive" /> 
              <animate id="an4" attributeName="stroke-dashoffset" begin="rect4.mouseover" dur="2s" values="350;0" fill="freeze" restart="whenNotactive" />
  </path>
 
  <g fill="transparent">
 <path class="rect" id="rect1" d="M64 65h245l3 152-247-2z"  />
  <path class="rect" id="rect2" d="m664 97 290 1v148l-290-1z"  />
  <path class="rect" id="rect3" d="M140 289h252l1 116-252-2z" />
  <path class="rect" id="rect4" d="M597 337h232l-1 125-231 3z" />
  </g>
</svg>
</div>

→ Ссылка