如何创建等距虚线圆? [英] How to create dashed circles with uniform spacing?

查看:62
本文介绍了如何创建等距虚线圆?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用CSS制作一个虚线圆,并通过以下过程创建它.

I wanted to make a dotted circle with CSS and created it with the following process.

尽管此过程可以显示虚线圆圈, 虚线的起点和终点之间的间隙变窄,并且间隙不均匀.

Although the dashed circle could be displayed by this process, The gap between the end and the beginning of the dashed line became narrow, and the gap was not uniform.

.c {
  width: 500px;
  height: 500px;
  border-width: 15px;
  border-style: dashed;
  border-radius: 600px;
}

<div class="c"></div>

有没有办法使差距均匀?我们还能控制破折号之间的距离吗?

Is there a way to make the gap uniform? can we also control the gap between dashes?

如果仅靠CSS无法做到这一点,我们正在考虑使用JavaScript或类似的工具.

If that's not possible with CSS alone, we're considering using JavaScript or something similar.

推荐答案

此处是conic-gradient()解决方案的优化版本,您可以在其中轻松控制破折号的数量和它们之间的间隔

Here is an optimized version of the conic-gradient() solution where you can easily control the number of dashes and the space between

.box {
  --d:4deg; /* distance between dashes */
  --n:30;   /* number of dashes */
  --c:#000; /* color of dashes */
  width: 180px;
  display:inline-block;
  border-radius:50%;
  border:2px solid transparent; /* control the thickness of border*/
  background: 
    linear-gradient(#fff,#fff) padding-box padding-box,
    repeating-conic-gradient(
        var(--c)    0 calc(360deg/var(--n) - var(--d)), 
        transparent 0 calc(360deg/var(--n)) 
    ) border-box;
}

/* keep the element square */
.box:before {
  content:"";
  display:block;
  padding-top:100%;
}

<div class="box"></div>

<div class="box" style="--n:20;border-width:5px;width:150px"></div>

<div class="box" style="--n:8;--d:20deg;border-width:5px;width:150px"></div>

<div class="box" style="--n:10;--d:15deg;border-width:3px;width:100px"></div>

<div class="box" style="--n:10;--d:20deg;border-width:3px;width:100px"></div>

要完全透明,我们考虑mask

To have full transparency we consider mask

.box {
  --d:4deg; /* distance between dashes */
  --n:30;   /* number of dashes */
  --c:#000; /* color of dashes */
  --b:2px;   /* control the thickness of border*/
  
  width: 180px;
  display:inline-block;
  border-radius:50%;
  background: 
    repeating-conic-gradient(
        var(--c)    0 calc(360deg/var(--n) - var(--d)), 
        transparent 0 calc(360deg/var(--n)));
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px));
          mask:radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px));
}

/* keep the element square */
.box:before {
  content:"";
  display:block;
  padding-top:100%;
}


body {
  background:linear-gradient(to right,yellow,pink);
}

<div class="box"></div>

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

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

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

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

要使事情变得有趣,我们甚至可以考虑将破折号涂成更复杂的颜色:

To make things funny we can even consider a more complex coloration to the dashes:

.box {
  --d:4deg; /* distance between dashes */
  --n:30;   /* number of dashes */
  --b:2px;   /* control the thickness of border*/
  
  width: 180px;
  display:inline-block;
  border-radius:50%;
  background:linear-gradient(red,blue);
  -webkit-mask:
      radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px)),
      repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--d)),transparent 0 calc(360deg/var(--n)));
  -webkit-mask-composite: source-in;
          mask:
      radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px)),
      repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--d)),transparent 0 calc(360deg/var(--n)));
          mask-composite: intersect;
}

/* keep the element square */
.box:before {
  content:"";
  display:block;
  padding-top:100%;
}


body {
  background:linear-gradient(to right,yellow,pink);
}

<div class="box"></div>

<div class="box" style="--n:20;--b:5px;width:150px;background:conic-gradient(green,orange,black)"></div>

<div class="box" style="--n:8;--d:20deg;--b:10px;width:130px;background:conic-gradient(black,white,black)"></div>

<div class="box" style="--n:18;--d:12deg;--b:8px;width:100px;background:linear-gradient(60deg,red 50%,green 0)"></div>

<div class="box" style="--n:10;--d:20deg;--b:3px;width:100px;background:#fff"></div>

您肯定可以在其中包含一些内容,以便更好地在伪元素上应用遮罩/背景,以避免遮盖内容:

You may for sure want some content inside so better apply the mask/background on a pseudo element to avoid masking the content:

.box {
  --d:4deg; /* distance between dashes */
  --n:30;   /* number of dashes */
  --b:2px;   /* control the thickness of border*/
  
  width: 180px;
  display:inline-flex;
  justify-content:center;
  align-items:center;
  font-size:35px;
  border-radius:50%;
  position:relative;
}
.box::after {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  z-index:-1;
  border-radius:inherit;
  background:var(--c,linear-gradient(red,blue));
  -webkit-mask:
      radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px)),
      repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--d)),transparent 0 calc(360deg/var(--n)));
  -webkit-mask-composite: source-in;
          mask:
      radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px)),
      repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--d)),transparent 0 calc(360deg/var(--n)));
          mask-composite: intersect;
  
}

/* keep the element square */
.box:before {
  content:"";
  padding-top:100%;
}


body {
  background:linear-gradient(to right,yellow,pink);
}

<div class="box">19</div>

<div class="box" style="--n:20;--b:5px;width:150px;--c:conic-gradient(green,orange,black)">17</div>

<div class="box" style="--n:8;--d:20deg;--b:10px;width:130px;--c:conic-gradient(black,white,black)">5</div>

<div class="box" style="--n:18;--d:12deg;--b:8px;width:100px;--c:linear-gradient(60deg,red 50%,green 0)">9</div>

<div class="box" style="--n:10;--d:20deg;--b:3px;width:100px;--c:#fff">13</div>

获得更多CSS想法以取得相似结果的相关问题:仅CSS饼图-如何在切片之间添加间距/填充? .您会找到比conic-gradient()更多的受支持方式(实际上,它在Firefox上不起作用),但是与上面的解决方案(只需要一个元素)不同,您需要使用很多代码.

Related question to get more CSS ideas to achieve a similar result: CSS Only Pie Chart - How to add spacing/padding between slices?. You will find more supported ways than conic-gradient() (actually it doesn't work on Firefox) but you are required to use a lot of code unlike the above solution where only one element is needed.

使用SVG,您还需要进行一些计算以确保间距均匀:

Using SVG you will also need some calculation to make sure you have a uniform spacing:

svg {
  width:200px;
}

<svg viewBox="-3 -3 106 106">
  <!-- 
    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" />
</svg>

使用CSS变量,我们可以简化它,但并非所有浏览器都支持它(实际上,它在Firefox中不起作用)

With CSS variables we can make it easier but it's not supported in all the browser (actually it doesn't work in Firefox)

svg {
  --n:20; /* number of dashes*/
  --d:5;  /* distance */
  width:200px;
}

svg circle {
   stroke-dasharray:calc((2*3.14*50)/var(--n) - var(--d)), var(--d); 
}

<svg viewBox="-3 -3 106 106">
  <circle cx="50" cy="50" r="50" fill="transparent" stroke="black" stroke-width="5" />
</svg>

<svg viewBox="-3 -3 106 106" style="width:150px;--n:20;--d:10">
  <circle cx="50" cy="50" r="50" fill="transparent" stroke="red"   stroke-width="5" />
</svg>

<svg viewBox="-3 -3 106 106" style="width:100px;--n:8;--d:15">
  <circle cx="50" cy="50" r="50" fill="transparent" stroke="green" stroke-width="5" />
</svg>

我们还可以轻松地将SVG用作背景,使事情变得更加灵活:

We can also easily use the SVG as background to make things more flexible:

.box {
  display:inline-block;
  width:200px;
  background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="-3 -3 106 106"><circle cx="50" cy="50" r="50" fill="transparent" stroke="black" stroke-width="5" style="stroke-dasharray:29.25, 10" /></svg>') center/contain;
}

.box:before {
  content:"";
  display:block;
  padding-top:100%;
}

<div class="box">

</div>

<div class="box" style="width:150px;">

</div>

<div class="box" style="width:100px;">

</div>

用作背景时,您需要手动设置该值,因此每次都需要不同的背景.我们只能通过使用SVG作为遮罩来使颜色易于更改;

When used as background, you need to manually set the value so you will need a different background each time. We can only make the color easy to change by using the SVG as mask;

.box {
  display:inline-block;
  width:200px;
  position:relative;
}

.box:before {
  content:"";
  display:block;
  padding-top:100%;
}

.box::after {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  z-index:-1;
  background:var(--c,red);
  -webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="-3 -3 106 106"><circle cx="50" cy="50" r="50" fill="transparent" stroke="black" stroke-width="5" style="stroke-dasharray:29.25, 10" /></svg>') center/contain;
          mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="-3 -3 106 106"><circle cx="50" cy="50" r="50" fill="transparent" stroke="black" stroke-width="5" style="stroke-dasharray:29.25, 10" /></svg>') center/contain;
}

<div class="box">

</div>

<div class="box" style="width:150px;--c:linear-gradient(60deg,green 50%,yellow 0);">

</div>

<div class="box" style="width:100px;--c:linear-gradient(red,blue)">

</div>

这篇关于如何创建等距虚线圆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆