首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在CSS中画一个圆形扇区?

如何在CSS中画一个圆形扇区?
EN

Stack Overflow用户
提问于 2014-01-18 22:50:00
回答 14查看 90.3K关注 0票数 79

那么,用纯CSS绘制一个圆是很容易的。

代码语言:javascript
复制
.circle {
    width: 100px;
    height: 100px;
    border-radius: 100px;
    border: 3px solid black;
    background-color: green;
}

如何绘制地段?给定一个度X 0-360,我想画一个X度扇区。我能用纯CSS做到这点吗?

例如:

感谢+示例

谢谢你,Jonathan,我用了第一种方法。如果它对某人有帮助,这里有一个JQuery函数的例子,它获得百分比并绘制一个扇区。扇区位于百分比圆的后面,此示例显示了如何从起点度数实现圆周的圆弧。

代码语言:javascript
复制
$(function drawSector() {
  var activeBorder = $("#activeBorder");
  var prec = activeBorder.children().children().text();
  if (prec > 100)
    prec = 100;
  var deg = prec * 3.6;
  if (deg <= 180) {
    activeBorder.css('background-image', 'linear-gradient(' + (90 + deg) + 'deg, transparent 50%, #A2ECFB 50%),linear-gradient(90deg, #A2ECFB 50%, transparent 50%)');
  } else {
    activeBorder.css('background-image', 'linear-gradient(' + (deg - 90) + 'deg, transparent 50%, #39B4CC 50%),linear-gradient(90deg, #A2ECFB 50%, transparent 50%)');
  }

  var startDeg = $("#startDeg").attr("class");
  activeBorder.css('transform', 'rotate(' + startDeg + 'deg)');
  $("#circle").css('transform', 'rotate(' + (-startDeg) + 'deg)');
});
代码语言:javascript
复制
.container {
  width: 110px;
  height: 110px;
  margin: 100px auto;
}

.prec {
  top: 30px;
  position: relative;
  font-size: 30px;
}

.prec:after {
  content: '%';
}

.circle {
  position: relative;
  top: 5px;
  left: 5px;
  text-align: center;
  width: 100px;
  height: 100px;
  border-radius: 100%;
  background-color: #E6F4F7;
}

.active-border {
  position: relative;
  text-align: center;
  width: 110px;
  height: 110px;
  border-radius: 100%;
  background-color: #39B4CC;
  background-image: linear-gradient(91deg, transparent 50%, #A2ECFB 50%), linear-gradient(90deg, #A2ECFB 50%, transparent 50%);
}
代码语言:javascript
复制
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>

<div class="container">
  <div id="activeBorder" class="active-border">
    <div id="circle" class="circle">
      <span class="prec">66</span>
      <span id="startDeg" class="90"></span>
    </div>
  </div>
</div>

代码语言:javascript
复制
$(function drawSector() {
    // Get degrees
    ...
    // Draw a sector
    if (deg <= 180) {
        activeBorder.css('background-image', 'linear-gradient(' + (90+deg) + 'deg, transparent 50%, #A2ECFB 50%), linear-gradient(90deg, #A2ECFB 50%, transparent 50%)');
    }
    else {
        activeBorder.css('background-image', 'linear-gradient(' + (deg-90) + 'deg, transparent 50%, #39B4CC 50%), linear-gradient(90deg, #A2ECFB 50%, transparent 50%)');
    }

    // Rotate to meet the start degree
    activeBorder.css('transform','rotate(' + startDeg + 'deg)');
});
EN

回答 14

Stack Overflow用户

回答已采纳

发布于 2014-01-18 23:46:38

CSS和多背景渐变

您可以绘制白色部分,而不是尝试绘制绿色部分:

代码语言:javascript
复制
pie {
    border-radius: 50%;
    background-color: green;
}

.ten {
    background-image:
        /* 10% = 126deg = 90 + ( 360 * .1 ) */
        linear-gradient(126deg, transparent 50%, white 50%),
        linear-gradient(90deg, white 50%, transparent 50%);
}

代码语言:javascript
复制
pie {
  width: 5em;
  height: 5em;
  display: block;
  border-radius: 50%;
  background-color: green;
  border: 2px solid green;
  float: left;
  margin: 1em;
}

.ten {
  background-image: linear-gradient(126deg, transparent 50%, white 50%), linear-gradient(90deg, white 50%, transparent 50%);
}

.twentyfive {
  background-image: linear-gradient(180deg, transparent 50%, white 50%), linear-gradient(90deg, white 50%, transparent 50%);
}

.fifty {
  background-image: linear-gradient(90deg, white 50%, transparent 50%);
}


/* Slices greater than 50% require first gradient
   to be transparent -> green */

.seventyfive {
  background-image: linear-gradient(180deg, transparent 50%, green 50%), linear-gradient(90deg, white 50%, transparent 50%);
}

.onehundred {
  background-image: none;
}
代码语言:javascript
复制
<pie class="ten"></pie>
<pie class="twentyfive"></pie>
<pie class="fifty"></pie>
<pie class="seventyfive"></pie>
<pie class="onehundred"></pie>

演示:http://jsfiddle.net/jonathansampson/7PtEm/

可伸缩矢量图形

如果可以,您可以使用SVG <circle><path>元素来实现类似的效果。请考虑以下几点:

代码语言:javascript
复制
<svg>
  <circle cx="115" cy="115" r="110"></circle>
  <path d="M115,115 L115,5 A110,110 1 0,1 190,35 z"></path>
</svg>

上面的内容相当简单。我们有一个包含圆和路径的元素。圆的中心是115x115 (使SVG元素为230x230)。圆的半径为110,总宽度为220 (边界为10)。

然后我们添加一个<path>元素,这是本例中最复杂的部分。该元素有一个属性,用于确定路径的绘制位置和绘制方式。它以下列值开头:

代码语言:javascript
复制
M115,115

这将指示路径从上述圆的中心开始。接下来,我们从这个位置到下一个位置画一条线:

代码语言:javascript
复制
L115,5

这将绘制一条从圆的中心到元素顶部的垂直线(距离元素顶部5个像素)。在这一点上,事情变得有点复杂,但仍然非常容易理解。

现在,我们从当前位置(115,5)绘制一条弧线:

代码语言:javascript
复制
A110,110 1 0,1 190,35 z

这将创建我们的圆弧,并使其半径与圆(110)的半径相匹配。这两个值分别表示x半径和y半径,因为我们处理的是一个圆,所以这两个值是相等的。下一组重要的数字是最后一个,190,35。这将告诉圆弧在何处结束。

至于其余的信息(1 0,1z),它们控制弧本身的曲率、方向和末端。您可以通过查阅任何在线SVG路径参考来了解有关它们的更多信息。

要实现不同大小的“切片”,只需更改190,35以反映更大或更小的一组坐标。你可能会发现,如果你想跨越超过180度,你将需要创建第二个圆弧。

如果要从角度确定x和y坐标,可以使用以下公式:

代码语言:javascript
复制
x = cx + r * cos(a)
y = cy + r * sin(a)

在上面的例子中,76的度数是:

代码语言:javascript
复制
x = 115 + 110 * cos(76)
y = 115 + 110 * sin(76)

这给了我们205.676,177.272

在某种程度上,您可以创建以下内容:

代码语言:javascript
复制
circle {
  fill: #f1f1f1;
  stroke: green;
  stroke-width: 5;
}

path {
  fill: green;
}

svg.pie {
  width: 230px;
  height: 230px;
}
代码语言:javascript
复制
<svg class="pie">
  <circle cx="115" cy="115" r="110"></circle>
  <path d="M115,115 L115,5 A110,110 1 0,1 190,35 z"></path>
</svg>

<svg class="pie">
  <circle cx="115" cy="115" r="110"></circle>
  <path d="M115,115 L115,5 A110,110 1 0,1 225,115 z"></path>
</svg>

<svg class="pie">
  <circle cx="115" cy="115" r="110"></circle>
  <path d="M115,115 L115,5 A110,110 1 0,1 115,225 A110,110 1 0,1 35,190 z"></path>
</svg>

演示:http://jsfiddle.net/jonathansampson/tYaVW/

票数 177
EN

Stack Overflow用户

发布于 2015-03-01 00:04:39

使用overflowtransform属性可以很好地做到这一点,而不需要进行任何复杂的计算。

>旋转变换

角度小于180度的

  1. 添加一个长宽比为2:1的元素,并添加一个伪元素,该伪元素的上边界半径与元素的高度相同,下半径为0。
  2. Put transform-origin: 50% 100%;这将伪元素从其中间旋转();伪元素通过补充所需的角度,

transform: rotate(180 - rqrd. angle);i.e..

看看它是如何工作的:

EG :

使用此方法的40度扇区:

代码语言:javascript
复制
div {
  ...
  overflow: hidden;
  ...
}
div:before {
  ...
  border-radius: 100px 100px 0 0;
  transform-origin: 50% 100%;
  transform: rotate(140deg);
  ...
}

代码语言:javascript
复制
div {
  height: 100px;
  width: 200px;
  overflow: hidden;
  position: relative;
}
div:before {
  height: inherit;
  width: inherit;
  position: absolute;
  content: "";
  border-radius: 100px 100px 0 0;
  background-color: crimson;
  -webkit-transform-origin: 50% 100%;
  -moz-transform-origin: 50% 100%;
  -ms-transform-origin: 50% 100%;
  transform-origin: 50% 100%;
  -webkit-transform: rotate(140deg);
  -moz-transform: rotate(140deg);
  -ms-transform: rotate(140deg);
  transform: rotate(140deg);
}
代码语言:javascript
复制
<div></div>

>倾斜变换

你也可以把图片放在扇区里面!

这可以使用父元素上的skew转换和伪元素上的-ve skew来完成:

代码语言:javascript
复制
div {
    ...
    overflow: hidden;
    transform-origin: 0% 100%;
    transform: skew(-50deg);  /*Complement of rqrd angle*/
    ...
}
div:before {
    ...
    transform-origin: 0% 100%;
    transform: skew(50deg);
    ...
}

看看它是如何工作的:

代码语言:javascript
复制
div {
  height: 200px;
  width: 200px;
  overflow: hidden;
  -webkit-transform-origin: 0% 100%;
  -moz-transform-origin: 0% 100%;
  -ms-transform-origin: 0% 100%;
  transform-origin: 0% 100%;
  -webkit-transform: skew(-50deg);
  -moz-transform: skew(-50deg);
  -ms-transform: skew(-50deg);
  transform: skew(-50deg); /*Complement of rqrd angle or (90 - angle)*/
  position: relative;
}
div:before {
  height: inherit;
  width: inherit;
  position: absolute;
  content: "";
  border-radius: 0 200px 0 0;
  background: url('http://www.placekitten.com/g/300/200/');
  -webkit-transform-origin: 0% 100%;
  -moz-transform-origin: 0% 100%;
  -ms-transform-origin: 0% 100%;
  transform-origin: 0% 100%;
  -webkit-transform: skew(50deg);
  -moz-transform: skew(50deg);
  -ms-transform: skew(50deg);
  transform: skew(50deg);
}
代码语言:javascript
复制
<div></div>

Acknowledgements:我不想成为一个自我窃取的人,我使用了我之前使用过的herehere的想法。

票数 37
EN

Stack Overflow用户

发布于 2014-01-18 22:55:43

这有帮助吗?

代码语言:javascript
复制
.circle {
  width: 16em;
  height: 16em;
  border-radius: 50%;
  background: linear-gradient(36deg, #272b66 42.34%, transparent 42.34%) 0 0;
  background-repeat: no-repeat;
  background-size: 50% 50%;
}
代码语言:javascript
复制
<div class="circle"></div>

实际上,这里需要一些几何计算。但让我简单地解释一下:

考虑到圆内的4个季度,可以计算出每个季度的线性梯度角。而background-position决定了季度:

代码语言:javascript
复制
Q I   =>  100% 0
Q II  =>  100% 100%
Q III =>  0    100%
Q IV  =>  0    0

剩下的唯一一件事就是使用的颜色停靠点来自哪里:

考虑 circle 中的一段30角度的圆。

正如才华横溢的Ana Tudor在她的中解释的那样,如果我们取正方形宽度的长度为a,那么半对角线的长度将为a*sqrt(2)/2

如果我们将梯度度设为g,两个梯度和对角线之间的差值设为d,那么color-stop的长度可以通过以下公式计算:

代码语言:javascript
复制
a*sin(g) / (a*sqrt(2)/2 * cos(d))
= sin(g) / (sqrt(2)  /2 * cos(d)) 

因此,在本例中,我们有sin(30deg) / (sqrt(2)*cos((45-30)deg)) = 0.3660,色标的%值为36.60%

因为我们的形状是在第一季度,所以background-position100% 0

线性梯度为

代码语言:javascript
复制
linear-gradient(-30deg, orange 36.60%, transparent 36.60%) 100% 0;

代码语言:javascript
复制
.circle {
  width: 16em;
  height: 16em;
  border-radius: 50%;
  background: linear-gradient(-30deg, orange 36.60%, transparent 36.60%) 100% 0;
  background-repeat: no-repeat;
  background-size: 50% 50%;
}
代码语言:javascript
复制
<div class="circle"></div>

我建议阅读Ana的文章以了解更多细节。

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21205652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档