Search code examples
svggeometrysvg-filterssvg-animate

is it possible to make SVG circle fill color from bottom to top based on percentage?


<svg viewbox="-20 -20 100 100">

  <circle r="15.29563" cx="0" stroke="#7dc4c2" fill="#5ea4a2">

</svg>

How to fill the circle as below based on percentage!!

https://i.sstatic.net/gVAN5.png

Thanks in advance.


Solution

  • you could use a gradient with stop-opacity to do this. you would add two "middle" stops with opacity 0 and 1 respectively an set the offset of both to the percentage you need.

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="200" height="200">
      <linearGradient id="lg" x1="0.5" y1="1" x2="0.5" y2="0">
          <stop offset="0%" stop-opacity="1" stop-color="royalblue"/>
          <stop offset="40%" stop-opacity="1" stop-color="royalblue"/>
          <stop offset="40%" stop-opacity="0" stop-color="royalblue"/>
          <stop offset="100%" stop-opacity="0" stop-color="royalblue"/>
      </linearGradient>
      <circle cx="50" cy="50" r="45" fill="url(#lg)" stroke="crimson" stroke-width="5"/>
    </svg>

    you could even animate it

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="200" height="200">
          <linearGradient id="lg" x1="0.5" y1="1" x2="0.5" y2="0">
              <stop offset="0%" stop-opacity="1" stop-color="royalblue"/>
              <stop offset="40%" stop-opacity="1" stop-color="royalblue">
                <animate attributeName="offset" values="0;1;0" repeatCount="indefinite" dur="10s" begin="0s"/>
              </stop>
              <stop offset="40%" stop-opacity="0" stop-color="royalblue">
                <animate attributeName="offset" values="0;1;0" repeatCount="indefinite" dur="10s"  begin="0s"/>
              </stop>
              <stop offset="100%" stop-opacity="0" stop-color="royalblue"/>
          </linearGradient>
          <circle cx="50" cy="50" r="45" fill="url(#lg)" stroke="crimson" stroke-width="5"/>
    </svg>

    the advantage is that this works on any shape and size without changing the gradient

       <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 300" width="400" height="200">
          <linearGradient id="lg" x1="0.5" y1="1" x2="0.5" y2="0">
              <stop offset="0%" stop-opacity="1" stop-color="royalblue"/>
              <stop offset="40%" stop-opacity="1" stop-color="royalblue"/>
              <stop offset="40%" stop-opacity="0" stop-color="royalblue"/>
              <stop offset="100%" stop-opacity="0" stop-color="royalblue"/>
          </linearGradient>
          <circle cx="50" cy="50" r="45" fill="url(#lg)" stroke="crimson" stroke-width="5"/>
         <circle cx="250" cy="150" r="145" fill="url(#lg)" stroke="crimson" stroke-width="5"/>
         <rect x="400" y="20" width="100" height="100" fill="url(#lg)" stroke="crimson" stroke-width="5"/>
         <path d="M50 150L95 290 h-90z" fill="url(#lg)" stroke="crimson" stroke-width="5"/>
    
         <path d="M450 205 A45 45 0 0 1 450 295A100 100 0 0 0 450 205z" fill="url(#lg)" stroke="crimson" stroke-width="5"/>
       </svg>