'how to make svg curve at one end

im using svg for circular progress bar , i want to make one end curve not the both end . how is this possible ? how can i implement one end curve in svg? enter image description here

svg {
  height: 80vh;
  margin: 10vh auto;
  border: 1px solid red;
  display: block;
  transform: rotate(-90deg);
}

svg circle {
  stroke-width: 10;
  fill: transparent;
}

#outer {
  stroke: lightgrey;
}

#inner {
  stroke: blue;
  animation: value 2.5s linear forwards;
  stroke-linecap: round;
}

@keyframes value {
  0% {
    stroke-dasharray: 0 100;
  }
  100% {
    stroke-dasharray: 90 100;
  }
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <circle id="outer" cx="50" cy="50" r="40" />

  <circle id="inner" pathLength="100" cx="50" cy="50" r="40" />
</svg>


Solution 1:[1]

The easiest way would be to mask the starting point of the blue circle. For this you will need a <mask> like so:

  <mask id="m">
    <rect width="100" height="100" fill="white"/>
    <rect x="85" y="40" width="10" height="10" />
  </mask>

Please observe that the first rectangle is white and it covers the whole chart. (Everything under a white pixel will be visible). The smaller rectangle is black and covers the starting point of the blue circle. Everything under a black pixel will be invisible.

svg {
  height: 80vh;
  margin: 10vh auto;
  border: 1px solid red;
  display: block;
  transform: rotate(-90deg);
}

svg circle {
  stroke-width: 10;
  fill: transparent;
}

#outer {
  stroke: lightgrey;
}

#inner {
  stroke: blue;
  animation: value 2.5s linear forwards;
  stroke-linecap: round;
}

@keyframes value {
  0% {
    stroke-dasharray: 0 100;
  }
  100% {
    stroke-dasharray: 90 100;
  }
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <mask id="m">
    <rect width="100" height="100" fill="white"/>
    <rect x="85" y="40" width="10" height="10" />
  </mask>
  
  <circle id="outer" cx="50" cy="50" r="40" />
  <circle id="inner" pathLength="100" cx="50" cy="50" r="40" mask="url(#m)" />
</svg>

Solution 2:[2]

Try this code:

svg {
  height: 80vh;
  margin: 10vh auto;
  border: 1px solid red;
  display: block;
  transform: rotate(-90deg);
  border-top-right-radius: 20px;
}

svg circle {
  stroke-width: 10;
  fill: transparent;
}

#outer {
  stroke: lightgrey;
}

#inner {
  stroke: blue;
  animation: value 2.5s linear forwards;
  stroke-linecap: round;
}

@keyframes value {
  0% {
    stroke-dasharray: 0 100;
  }
  100% {
    stroke-dasharray: 90 100;
  }
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <circle id="outer" cx="50" cy="50" r="40" />

  <circle id="inner" pathLength="100" cx="50" cy="50" r="40" />
</svg>

Solution 3:[3]

I came up with an alternative solution than enxaneta suggested. The problem with using a mask is that when your value goes over 96% or so, the circle isn't completely filled and the mask is revealed.

Instead, you can set a rounded progress line on top of another progress line that has flat endcaps. By rotating the rounded progress line by roughly 5 degrees, the flat end is revealed.

instructions visualized

Here's how to do that in React Native with react-native-svg:

   const radius = 60;
   let myPercentage = 40;

   const circleCircumference = 2 * Math.PI * radius;
   const valueOffset = circleCircumference - 
                      (circleCircumference * myPercentage * 0.98) / 100;
    
   <Svg height={radius * 2 + 30} width={radius * 2 + 30}>
      <G rotation={-90} originX={radius + 15} originY={radius + 15}>
         // Background gray circle
         <Circle
            cx="50%"
            cy="50%"
            r={radius}
            stroke="rgb(60, 60, 60)"
            fill="transparent"
            strokeWidth="10"
            strokeDasharray={circleCircumference}
            strokeLinecap="butt"
         />

         // Background progress circle with flat ends
         <Circle
            cx="50%"
            cy="50%"
            r={radius}
            stroke={"rgb(0, 51, 204)"}
            fill="transparent"
            strokeWidth="10"
            strokeDasharray={circleCircumference}
            strokeDashoffset={valueOffset}
            strokeLinecap="butt"
         />

         // Progress circle with round ends rotated by 5 degrees
         <Circle
            cx="50%"
            cy="50%"
            r={radius}
            stroke={rgb(0, 51, 204)}
            fill="transparent"
            rotation={5}
            originX={radius + 15}
            originY={radius + 15}
            strokeWidth="10"
            strokeDasharray={circleCircumference}
            strokeDashoffset={valueOffset}
            strokeLinecap="round"
         />
      </G>
   </Svg>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 enxaneta
Solution 2 Swapnil Prakash
Solution 3