Vic VKh
Vic VKh

Reputation: 311

Partial circle with dashed line?

I'm trying to create a partial circle with dashed border but I can't find out how to achive that.

For instance, I want to create something like this using SVG

enter image description here

I know how to create both dashed border and a partial circle separately by using "stroke-dasharray". But I have no idea how to combine them.

For instance,

partial cicle

<svg viewBox="0 0 320 320">
  <path
    attr.stroke-dasharray="{{stroke_lenth}} {{circumference}}"
    d="M160 10
      a 150 150 0 0 1 0 300
      a 150 150 0 0 1 0 -300"
  />
</svg>

Upvotes: 1

Views: 3045

Answers (2)

Temani Afif
Temani Afif

Reputation: 272937

I would consider this previous answer that you can combine with a mask to hide a portion of the circle:

svg {
  width:200px;
  transform:rotate(90deg); /* control the rotation here */
}
<svg viewBox="-3 -3 106 106">
  <defs>
    <mask id="m" >
      <rect x="-3" y="-2" width="100%" height="100%" fill="white"/>
      <!-- update the 120 below to increase/decrease the visible part-->
      <circle cx="50" cy="50" r="50" 
        stroke-dasharray="120, 1000"  
        fill="transparent" 
        stroke="black" 
        stroke-width="8"/>
     </mask>
  </defs>
  <!-- 
    The circumference of the circle is 2*PI*R ~ 314.16
    if we want N dashed we use d=314.16/N
    For N = 20 we have d=15.71
    For a gap of 5 we will have "10.71,5" (d - gap,gap)
  -->
  <circle cx="50" cy="50" r="50" 
    stroke-dasharray="10.71, 5" 
    fill="transparent" 
    stroke="black" 
    stroke-width="5" mask="url(#m)" />
</svg>

A pure CSS solution but with low support actually due to the conic-gradient()

.box {
  --d:4deg; /* distance between dashes */
  --n:30;   /* number of dashes */
  --c:#000; /* color of dashes */
  --b:2px;   /* control the thickness of border*/
  --m:60deg; /* the masked part */
  --r:0deg; /* rotation */
  
  width: 180px;
  display:inline-block;
  aspect-ratio: 1;
  border-radius:50%;
  transform:rotate(var(--r));
  background: 
    repeating-conic-gradient(
        var(--c)    0 calc(360deg/var(--n) - var(--d)), 
        transparent 0 calc(360deg/var(--n)));
  mask:
   conic-gradient(#000 var(--m),#0000 0) intersect,
   radial-gradient(farthest-side,#0000 calc(100% - var(--b) - 1px),#000 calc(100% - var(--b)) calc(100% - 1px),#0000);
}



body {
  background:linear-gradient(to right,yellow,pink);
}
<div class="box"></div>

<div class="box" style="--n:20;--b:5px;width:150px;--c:blue;--m:20deg"></div>

<div class="box" style="--n:8;--d:20deg;--b:10px;width:130px;--c:red;--m:180deg"></div>

<div class="box" style="--n:18;--d:12deg;--b:8px;width:100px;--c:green;--r:90deg"></div>

<div class="box" style="--n:10;--d:20deg;--b:3px;width:100px;--c:purple;--r:120deg;--m:120deg"></div>

Upvotes: 4

enxaneta
enxaneta

Reputation: 33044

You'll need to calculate the starting point and the end point of the path. Next you draw the arc.

let center = {x:160,y:160}//the center of the circle
let r = 150;//the radius of the circle
let p1 = {//the starting point
  x:center.x + r*Math.cos(-2),
  y:center.x + r*Math.sin(-2),
}

let p2 = {//the ending point
  x:center.x + r*Math.cos(2.5),
  y:center.x + r*Math.sin(2.5),
}

let path = document.querySelector("path");

path.setAttribute("d",`M${p1.x},${p1.y} A150,150 0 1 1 ${p2.x},${p2.y}`)
<svg viewBox="0 0 320 320" width="300">
  <path stroke-width="5"
    stroke="black" stroke-dasharray="15" fill="none"
    d="M160 10
      a 150 150 0 0 1 0 300
      a 150 150 0 0 1 0 -300"
  />
</svg>

In the example above the starting angle is -1 radians. The angle where the arc ends is 2.5 radians

Upvotes: 4

Related Questions