Помогите данный прелодер на css переписать на svg?

Главное, чтобы данный прелодер одинаковый вид при любом расширении, плюс надо чтобы символы тоже имели градиент. Можно конечно этого добиться на css, но все же это будет уже извращением...

Заранее благодарю за помощь...

document.querySelector(".circle").innerHTML = "Loading..."
  .split("")
  .map((e, i) => `<span style="--rot:${i * 11}deg">${e}</span>`)
  .join("");
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
}

html,
body {
  height: auto;
  min-height: 100vh;
  background-color: #272727;
  color: burlywood;
  font-size: 2vw;
  border: 1px solid transparent;
}

body * {
  /* border: 1px solid red; */
}

.circle {
  margin: 100px auto;
  width: 20vw;
  height: 20vw;
  position: relative;
  border-radius: 50%;
  overflow: hidden;
}

.circle::after,
.circle::before {
  position: absolute;
  content: "";
  display: block;
  width: inherit;
  height: inherit;
  border-radius: 50%;
  /*
        */
}

.circle::after {
  animation: rott 1s ease infinite;
  background: linear-gradient(130deg, red 20%, purple 70%);
  background-position: -42px -29px;
  background-repeat: no-repeat;
  border: 30px solid #272727;
  box-sizing: border-box;
  border-top: 30px solid transparent;
  border-left: 30px solid transparent;
  background-size: 132% 120%;
}

.circle::before {
  background-color: #272727;
  transform: translate(-50%, -50%);
  z-index: 4;
  left: 50%;
  top: 50%;
  width: calc(20vw - 30px);
  height: calc(20vw - 30px);
}

span {
  z-index: 9;
  display: inline-flex;
  justify-content: center;
  align-items: flex-start;
  width: 30px;
  height: 100%;
  position: absolute;
  padding: 60px 0 0 0;
  top: 50%;
  left: 50%;
  transform-origin: 6px 56% 0;
  transform: translate(-50%, -50%) rotate(var(--rot));
}

span:nth-child(8) {
  animation: opa 1s ease 0s infinite;
}

span:nth-child(9) {
  animation: opa 1s ease 0.2s infinite;
}

span:nth-child(10) {
  animation: opa 1s ease 0.5s infinite;
}

@keyframes rott {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes opa {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
<div class="circle"></div>


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

Автор решения: Alexandr_TT
  • Из окружности вырезается дуга с помощью stroke-dasharray

  • Дуга окрашивается линейным градиентом

  • Дуга вращается с помощью изменения атрибутов stroke-dashoffset

  • Неравномерность вращения реализуется keyTimes="0;0.75;0.9;1"

  • Расположение текста Loading ... по дуге за счет применения
    <textPath href="#textPath" startOffset="12">

body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
         viewBox="0 0 400 400"  > 
 <defs>    
                <!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
   <linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
      <stop offset="0" stop-color="white" stop-opacity="0.05"  />
      <stop offset="0.8" stop-color="red"  />
   </linearGradient>
 </defs>    
                  <!-- Дуга, на которой расположены буквы  -->
<path id="textPath" d="M200,110 A90,90 0 0 1 200,290" stroke-width="2" fill="none" stroke="none" /> 
<text class="txt1" font-size="32px" letter-spacing="0.2em" fill="#DEB887">
  <textPath href="#textPath" startOffset="12">
    <tspan dy="-0.1em">Loading . . .</tspan>
  </textPath>
</text>
                         <!-- Вращающаяся дуга -->
<circle id="circle" cx="200" cy="200" r="150" stroke="url(#Lg)" stroke-width="20" stroke-dashoffset="942"  stroke-dasharray="471" fill="none" stroke="crimson" stroke-linecap="round" >
    <animate
     attributeName="stroke-dashoffset"
     begin="0s" dur="1s"
     values="942;471;235;0"
     keyTimes="0;0.75;0.9;1"
      calcMode="linear"
     repeatCount="indefinite" /> 
  
</circle> 
</svg>
</div>

Update

Добавлена анимация текста Loading ...

Реализовано с помощью маски-полукруга, который вращается и тем самым открывает, маскирует текст

<mask id="mask">    
      <rect width="100%" height="100%" fill="white" />
       <path transform="rotate(0,200,200)" d="M200,90 A110,110 0 0 1 200,310" stroke-width="20" fill="black" stroke="black" >  
      <animateTransform
     attributeName="transform"
     type="rotate"
     begin="0s" dur="4s"
     values="0,200,200;360,200,200"
     repeatCount="indefinite" /> 
     </path>    
</mask>

body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
          viewBox="0 0 400 400"  > 
 <defs>
   <linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
      <stop offset="0" stop-color="white" stop-opacity="0.05"  />
      <stop offset="0.8" stop-color="red"  />
        
   </linearGradient> 
   <mask id="mask">    
      <rect width="100%" height="100%" fill="white" />
       <path transform="rotate(0,200,200)" d="M200,90 A110,110 0 0 1 200,310" stroke-width="20" fill="black" stroke="black" >  
      <animateTransform
     attributeName="transform"
     type="rotate"
     begin="0s" dur="4s"
     values="0,200,200;360,200,200"
     repeatCount="indefinite" /> 
     </path>    
   </mask>
 </defs>         
<path   id="textPath" d="M200,110 A90,90 0 0 1 200,290" stroke-width="2" fill="none" stroke="none" /> 
<text  mask="url(#mask)" class="txt1" font-size="32px" letter-spacing="0.2em" fill="#DEB887">
  <textPath href="#textPath" startOffset="12">
    <tspan dy="-0.1em">Loading . . .</tspan>
  </textPath>
</text>
  
<circle id="circle" cx="200" cy="200" r="150" stroke="url(#Lg)" stroke-width="20" stroke-dashoffset="942"  stroke-dasharray="471" fill="none" stroke="crimson" stroke-linecap="round" >
    <animate
     attributeName="stroke-dashoffset"
     begin="0s" dur="1s"
     values="942;471;235;0"
     keyTimes="0;0.75;0.9;1"
      calcMode="linear"
     repeatCount="indefinite" /> 
  
</circle> 
</svg>
</div>

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

Варианты с анимацией градиента

В градиенте анимируется атрибут offset у обоих составляющих градиент цветов:

                  <!-- Линейный градиент для окраски текста -->
<linearGradient id="LgText" x1="0" y1="0" x2="0.25" y2="1">
  <stop offset="5%" stop-color="orangered"  >
      <animate attributeName="offset" dur="3s" values="0;1;1" fill="freeze" repeatCount="indefinite" /> 
  </stop>
   <stop offset="95%" stop-color="#DEB887" >
      <animate attributeName="offset" dur="3s" values="0;1;1" fill="freeze" repeatCount="indefinite" /> 
   </stop>
</linearGradient> 

при значении values="0;1;1" повторение 1 обеспечивает паузу в конце закраски

body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
          viewBox="0 0 400 400"  > 
 <defs>    
                <!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
   <linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
      <stop offset="0" stop-color="white" stop-opacity="0.05"  />
      <stop offset="0.8" stop-color="red"  />
   </linearGradient> 
                   <!-- Линейный градиент для окраски текста -->
<linearGradient id="LgText" x1="0" y1="0" x2="0.25" y2="1">
  <stop offset="5%" stop-color="orangered"  >
      <animate attributeName="offset" dur="3s" values="0;1;1" fill="freeze" repeatCount="indefinite" /> 
  </stop>
   <stop offset="95%" stop-color="#DEB887" >
      <animate attributeName="offset" dur="3s" values="0;1;1" fill="freeze" repeatCount="indefinite" /> 
   </stop>
</linearGradient> 
 </defs>    
                  <!-- Дуга, на которой расположены буквы  -->
<path id="textPath" d="M200,110 A90,90 0 0 1 200,290" stroke-width="2" fill="none" stroke="none" /> 
<text class="txt1" font-size="36px" font-weight="bold" letter-spacing="0.2em" fill="url(#LgText)">
  <textPath href="#textPath" startOffset="2">
    <tspan dy="-0.1em">Loading . . .</tspan>
  </textPath>
</text>
                         <!-- Вращающаяся дуга -->
<circle id="circle" cx="200" cy="200" r="150" stroke="url(#Lg)" stroke-width="20" stroke-dashoffset="942"  stroke-dasharray="471" fill="none" stroke="crimson" stroke-linecap="round" >
    <animate
     attributeName="stroke-dashoffset"
     begin="0s" dur="1s"
     values="942;471;235;0"
     keyTimes="0;0.75;0.9;1"
      calcMode="linear"
     repeatCount="indefinite" /> 
  
</circle> 
</svg>
</div>       

При values="0;1;1;0;0" будет закраска в обе стороны с паузой в конечных позициях

body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
          viewBox="0 0 400 400"  > 
 <defs>    
                <!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
   <linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
      <stop offset="0" stop-color="white" stop-opacity="0.05"  />
      <stop offset="0.8" stop-color="red"  />
   </linearGradient> 
                   <!-- Линейный градиент для окраски текста -->
   <linearGradient id="LgText" x1="0" y1="0" x2="0.25" y2="1">
  <stop offset="5%" stop-color="orangered"  >
      <animate attributeName="offset" dur="6s" values="0;1;1;0;0" fill="freeze" repeatCount="indefinite" /> 
    </stop>
   <stop offset="95%" stop-color="#DEB887" >
      <animate attributeName="offset" dur="6s" values="0;1;1;0;0" fill="freeze" repeatCount="indefinite" /> 
   </stop>
   
 </linearGradient> 
 </defs>    
                  <!-- Дуга, на которой расположены буквы  -->
<path id="textPath" d="M200,110 A90,90 0 0 1 200,290" stroke-width="2" fill="none" stroke="none" /> 
<text class="txt1" font-size="36px" font-weight="bold" letter-spacing="0.2em" fill="url(#LgText)">
  <textPath href="#textPath" startOffset="2">
    <tspan dy="-0.1em">Loading . . .</tspan>
  </textPath>
</text>
                         <!-- Вращающаяся дуга -->
<circle id="circle" cx="200" cy="200" r="150" stroke="url(#Lg)" stroke-width="20" stroke-dashoffset="942"  stroke-dasharray="471" fill="none" stroke="crimson" stroke-linecap="round" >
    <animate
     attributeName="stroke-dashoffset"
     begin="0s" dur="1s"
     values="942;471;235;0"
     keyTimes="0;0.75;0.9;1"
      calcMode="linear"
     repeatCount="indefinite" /> 
  
</circle> 
</svg>
</div>       

Update

Цитата из комментария @Air:

Например, что бы полоса была на одном уровне с надписью, и проходила через нее... По сути, полоса с градиентом доходя до границы надписи и исчезала, как бы входила в нее и выходила из нее в конце... было бы прикольно

Идея сделать буквы прозрачными, только строка с очертанием буквы, включить их в маску и применить эту маску к вращающейся дуге

  • Вариант с закраской градиентом в одну сторону

body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
          viewBox="0 0 400 400"  > 
 <defs>    
                <!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
   <linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
      <stop offset="0" stop-color="white" stop-opacity="0.05"  />
      <stop offset="0.8" stop-color="red"  />
   </linearGradient> 
                   <!-- Линейный градиент для окраски текста -->
   <linearGradient id="LgText" x1="0" y1="0" x2="0.25" y2="1">
  <stop offset="5%" stop-color="orangered"  >
      <animate attributeName="offset" dur="2s" values="0;1" fill="freeze" repeatCount="indefinite" /> 
    </stop>
   <stop offset="95%" stop-color="#DEB887" >
      <animate attributeName="offset" dur="2s" values="0;1" fill="freeze" repeatCount="indefinite" /> 
   </stop>
   
 </linearGradient> 
 </defs>    

                         <!-- Вращающаяся дуга -->
<circle id="circle" cx="200" cy="200" r="150" stroke="url(#Lg)" stroke-width="42" stroke-dashoffset="942"  stroke-dasharray="471" fill="none" stroke="crimson" stroke-linecap="round" >
    <animate
     attributeName="stroke-dashoffset"
     begin="0s" dur="1s"
     values="942;471;235;0"
     keyTimes="0;0.75;0.9;1"
      calcMode="linear"
     repeatCount="indefinite" /> 
  
</circle> 
                    <!-- Дуга, на которой расположены буквы  -->
<path id="textPath" d="M200,110 A90,90 0 0 1 200,290" stroke-width="2" fill="none" stroke="none" /> 
<text class="txt1" font-size="36px" font-weight="bold" letter-spacing="0.2em" fill="url(#LgText)" stroke="#DEB887" >
  <textPath href="#textPath" startOffset="2">
    <tspan dy="-1.3em">Loading . . .</tspan>
  </textPath>
</text>
</svg>
</div>       

  • Вариант с закраской градиентом в обе стороны

body {
background:#272727;
}
.container {
width:40vw;
height:40vh;
}
<div class="container">
<svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
          viewBox="0 0 400 400"  > 
 <defs>    
                <!-- Линейный градиент для окраски дуги с прозрачным хвостом -->
   <linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
      <stop offset="0" stop-color="white" stop-opacity="0.05"  />
      <stop offset="0.8" stop-color="red"  />
   </linearGradient> 
                   <!-- Линейный градиент для окраски текста -->
   <linearGradient id="LgText" x1="0" y1="0" x2="0.25" y2="1">
  <stop offset="5%" stop-color="orangered"  >
      <animate attributeName="offset" dur="6s" values="0;1;1;0;0" fill="freeze" repeatCount="indefinite" /> 
    </stop>
   <stop offset="95%" stop-color="#DEB887" >
      <animate attributeName="offset" dur="6s" values="0;1;1;0;0" fill="freeze" repeatCount="indefinite" /> 
   </stop>
   
 </linearGradient> 
 <mask id="mask">
   <rect width="100%" height="100%" fill="white"/>
   <g fill="black"> 
       <path id="textPath" d="M200,110 A90,90 0 0 1 200,290"  fill="black" stroke="none" /> 
<text class="txt1" font-size="36px" font-weight="bold" letter-spacing="0.2em"  stroke="black" >
  <textPath href="#textPath" startOffset="2">
    <tspan dy="-1.3em">Loading . . .</tspan>
  </textPath>
</text>
   </g>
 </mask>
 </defs>      
 
                     <!-- Дуга, на которой расположены буквы  -->
<path id="textPath" d="M200,110 A90,90 0 0 1 200,290" stroke-width="2" fill="none" stroke="none" /> 
<text class="txt1" font-size="36px" font-weight="bold" letter-spacing="0.2em" fill="url(#LgText)" stroke="#DEB887" >
  <textPath href="#textPath" startOffset="2">
    <tspan dy="-1.3em">Loading . . .</tspan>
  </textPath>
</text>

                         <!-- Вращающаяся дуга -->
<circle id="circle" cx="200" cy="200" r="150" mask="url(#mask)" stroke="url(#Lg)" stroke-width="42" stroke-dashoffset="942"  stroke-dasharray="471" fill="none"  stroke-linecap="round" >
    <animate
     attributeName="stroke-dashoffset"
     begin="0s" dur="1s"
     values="942;471;235;0"
     keyTimes="0;0.75;0.9;1"
      calcMode="linear"
     repeatCount="indefinite" /> 
  
</circle> 

</svg>
</div>       

→ Ссылка