Can you help me rewrite this css preloader to svg?

Question:

The main thing is that this preloader should look the same for any extension, plus the symbols should also have a gradient. Of course, this can be achieved on css , but still it will be a perversion…

Thank you in advance for your help…

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>

Answer:

  • An arc is cut from a circle using stroke-dasharray

  • The arc is colored with a linear gradient

  • The arc is rotated by changing the stroke-dashoffset

  • Rotation irregularity is implemented keyTimes="0;0.75;0.9;1"

  • Arrangement of the text Loading ... along the arc due to the application
    <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

Added text animation Loading …

Implemented using a mask-semicircle that rotates and thus opens, masks the text

<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>
Scroll to Top