JSFiddle - React, Tailwind, and code Playground

by zlobul

HTML

<div class=skill> 
  <div class=outer> 
    <div class=inner> 
      <div id="number">
        0
      </div>
    </div>  
  </div>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="160px" height="160px">
         <defs>
            <linearGradient id="GradientColor">
               <stop offset="0%" stop-color="white" />
               <stop offset="100%" stop-color="white" />
            </linearGradient>
            
    <filter id="neon-glow" filterUnits="userSpaceOnUse"
            x="-50%" y="-50%" width="200%" height="200%">
       <!-- blur the text at different levels-->
      <feGaussianBlur in="SourceGraphic" stdDeviation="1" result="blur1"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="3" result="blur3"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="4" result="blur4"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur5"/>
      <feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur8"/>
      <!-- merge all the blurs except for the first one -->
      <feMerge result="blur-merged">
        <feMergeNode in="blur3"/>
        <feMergeNode in="blur4"/>
        <feMergeNode in="blur5"/>
        <feMergeNode in="blur8"/>
      </feMerge>
      <!-- recolour the merged blurs red-->
      <feColorMatrix result="cyan-blur" in="blur-merged" type="matrix"
                     values="0.09 0   0   0   0
                        0   0.76  0   0   0
                        0   0   0.70  0   0
                        0   0   0   1   0 "/>
      <feMerge>
        <feMergeNode in="cyan-blur"/>       <!-- largest blurs coloured red -->
        <feMergeNode in="blur1"/>          <!-- smallest blur left white -->
        <feMergeNode in="SourceGraphic"/>  <!-- original white text -->
      </feMerge>
    </filter>
         </defs>
         <circle cx="80" cy="80" r="60" stroke-linecap="round" />

 </svg>


</div>

CSS

*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 100vh;
  display: flex;
  align-items:center;
  justify-content: center;
  background:black;
}

.skill{
 width: 160px;
 height:160px;
 /* background: gray; */
 position: relative;
}

.outer{
   width: 160px;
   height:160px;
   border-radius: 50%;
   padding: 20px;
}

.inner{
   width: 120px;
   height:120px;
   border-radius: 50%;
   display:flex;
   align-items: center;
   justify-content: center;
}

#number {
  font-weight:600;
  font-size:30px;
  color: white;
  text-shadow:
  0 0 1px white,
  0 0 6px #17c3b2,
  0 0 7px #17c3b2,
  0 0 8px #17c3b2,
  0 0 9px #17c3b2;
}

circle {
  fill: none;
  stroke: url(#GradientColor);
  filter: url(#neon-glow);
  stroke-width: 10px;  stroke-dasharray:440;
  stroke-dashoffset: 440;
  animation: anim 2s linear forwards;
}

svg{
  position: absolute;
  top: 0;
  left:0;
  transform: rotate(-90deg);
}


@keyframes anim{
  100% {
     stroke-dashoffset:0;
  }
}

JavaScript

let number = document.getElementById("number")
let counter = 0;
setInterval (() => {
	if ( counter == 11 ) {
  	clearInterval();
  } else {
    counter += 1;
    number.innerHTML = counter;
  }
}, 150)