STL
STL

Reputation: 63

SVG animating dotted border path like progressbar

I'm trying to animate a dotted SVG circle like a progressbar - to fill itself in 3 seconds, but have a hard time achieving this effect with the dotted border. Here's the code I currently have and it animates, but not like a progress:

svg circle {
  animation: dash 3s linear forwards;
}

@keyframes dash {
  from {
    stroke-dashoffset: 100;
  }
  to {
    stroke-dashoffset: 0;
  }
}
<svg class="progress-ring" viewBox="0 0 120 120" fill="none" width="120" height="120" xmlns="http://www.w3.org/2000/svg">
    <circle stroke="#000000" pathLength="215" stroke-width="7" fill="transparent" stroke-dasharray="6 6" r="57" cx="60" cy="60"/>
    </svg>

https://codepen.io/xtnciwuu-the-selector/pen/abLXOJO

Any help would be greatly appreciated

Upvotes: 1

Views: 569

Answers (1)

chrwahl
chrwahl

Reputation: 13070

Here are two different examples. The first one is a bit "hacky" in that I hard coded the dasharray with all the dots, spaces and then a subsequent long space.

The second example makes use of a mask. The animated circle/dasharray is masked off, so it looks like smaller dashes.

It kind of gives you two different expressions of the same animation.

svg circle#c1 {
  animation: dash1 3s linear forwards;
}

@keyframes dash1 {
  from {
    stroke-dashoffset: 36;
  }
  to {
    stroke-dashoffset: 0;
  }
}

svg circle#c2 {
  animation: dash2 3s linear forwards;
}

@keyframes dash2 {
  from {
    stroke-dasharray: 0 36;
  }
  to {
    stroke-dasharray: 36 36;
  }
}
<svg class="progress-ring" viewBox="0 0 120 120" fill="none" width="120" height="120" xmlns="http://www.w3.org/2000/svg">
  <circle id="c1" stroke="#000000" pathLength="36" stroke-width="7" fill="transparent"
  stroke-dasharray="1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 36"
  r="57" cx="60" cy="60" transform="rotate(-90 60 60)" />
</svg>

<svg class="progress-ring" viewBox="0 0 120 120" fill="none" width="120" height="120" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <mask id="m1">
      <circle stroke="white" pathLength="36" stroke-width="7" fill="transparent"
      stroke-dasharray="1 1" r="57" cx="60" cy="60" />
    </mask>
  </defs>
  <circle id="c2" mask="url(#m1)" stroke="#000000" pathLength="36" stroke-width="7"
  fill="transparent" stroke-dasharray="18 36" r="57" cx="60" cy="60"
  transform="rotate(-90 60 60)" />
</svg>

Upvotes: 2

Related Questions