How to remove a circle at the end of a line with stroke-linecap = "round"

Viewed 224

I wrote a simple progress bar code to demonstrate the problem:

enter image description here

Line animation starts after click

<style>
body{text-align:center;font-family:sans-serif;background:silver;}
svg{width:30%;}
</style>

<svg id="svg1"  viewbox="0 0 100 100">
   <circle cx="50" cy="50" r="40" fill="transparent" stroke="#fff" stroke-width="8"/>
  <path id="progress" stroke-dasharray="251.2" stroke-dashoffset="251.2" stroke-width="8" stroke="#4596AB" stroke-linecap="round" fill="none"
        d="M50 10
           a 40 40 0 0 1 0 80
           a 40 40 0 0 1 0 -80"> 
    <animate attributeName="stroke-dashoffset" begin="svg1.click" dur="4s" values="251.2;0;251.2" fill="freeze" />     
  </path>
</svg>

When I assign the stroke-linecap ="round" attribute, a circle appears at the beginning of the line. In this case, the line has zero length.

With other values for example stroke-linecap ="butt" this effect does not occur.

How to remove a circle at the start of a line with stroke-linecap = "round"?

Note: This effect is not observed here in the snippet, but is clearly visible in the browser, in a separately saved file

2 Answers

The reason for this browser bug was found using @Paul LeBeau

I counted the circumference 2 * PI * 40 ~= 2 * 3.14 * 40 ~= 251.2

At this value of 251.2 there is a small circle as shown in the picture in the question.

if you calculate using getTotalLength(), you get 251.36264038085938

At this value of the circumference ~= 251.36, there is no small circle

<style>
body{text-align:center;font-family:sans-serif;background:silver;}
svg{width:30%;}
</style>

<svg id="svg1"  viewBox="0 0 100 100">
   <circle cx="50" cy="50" r="40" fill="transparent" stroke="#fff" stroke-width="8"/>
  <path id="progress" stroke-dasharray="251.36" stroke-dashoffset="251.36" stroke-width="8" stroke="#4596AB" stroke-linecap="round" fill="none"
        d="M50 10
           a 40 40 0 0 1 0 80
           a 40 40 0 0 1 0 -80"> 
    <animate attributeName="stroke-dashoffset" begin="svg1.click" dur="4s" values="251.36;0;251.36" fill="freeze" />       
  </path>
</svg>
<script>
 console.log(progress.getTotalLength());
 </script>  

Conclusion: to avoid a small circle, you need to count the circumference to the second decimal place

[not an answer; but better code]

See the link to an answer in the comments.

To prevent (weird) path calculations, I suggest you set pathLength to 100

<style>
  svg {
    background: silver;
  }
</style>

<svg id="svg1" viewbox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="transparent" stroke="#fff" stroke-width="8" />
  <path id="progress" stroke-dasharray="100" stroke-dashoffset="100" 
        stroke-width="8" stroke="#4596AB" stroke-linecap="round" fill="none" 
        pathLength="100" d="M50 10a40 40 0 0 1 0 80a 40 40 0 0 1 0 -80">
    <animate attributeName="stroke-dashoffset" begin="svg1.click" 
             dur="40s" values="100;0;100" fill="freeze" />
  </path>
</svg>

Related