如何在 CSS 中绘制圆形扇区?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21205652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to draw a circle sector in CSS?
提问by Itay Gal
Well, drawing a circle with pure CSS is easy.
好吧,用纯 CSS 画一个圆很容易。
.circle {
width: 100px;
height: 100px;
border-radius: 100px;
border: 3px solid black;
background-color: green;
}
How do I draw a sector? Given a degree X [0-360] I want to draw a X degrees sector. Can I do that with pure CSS?
如何绘制扇区?给定一个度数 X [0-360] 我想画一个 X 度数的扇区。我可以用纯 CSS 做到这一点吗?
For example:
例如:
Thanks + Example
谢谢+例子
Thank you Jonathan, I used the first method. If it helps someone here's an example of a JQuery function that gets percentage and draw a sector. The sector is behind the percentage circle and this example shows how to achieve an arc around a circle from a start degree.
谢谢乔纳森,我用的是第一种方法。如果它对某人有帮助,这里有一个获取百分比并绘制扇区的 JQuery 函数示例。该扇区位于百分比圆的后面,此示例显示了如何从起始角度围绕圆形成弧。
$(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)');
});
.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%);
}
<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>
$(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)');
});
回答by Sampson
CSS and Multiple Background Gradients
CSS 和多个背景渐变
Rather than trying to draw the green portion, you could draw the white portions instead:
与其尝试绘制绿色部分,不如绘制白色部分:
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%);
}
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;
}
<pie class="ten"></pie>
<pie class="twentyfive"></pie>
<pie class="fifty"></pie>
<pie class="seventyfive"></pie>
<pie class="onehundred"></pie>
Demo: http://jsfiddle.net/jonathansampson/7PtEm/
演示:http: //jsfiddle.net/jonathansampson/7PtEm/
Scalable Vector Graphics
可缩放矢量图形
If it's an option, you can accomplish a similar effect using SVG <circle>
and <path>
elements. Consider the following:
如果这是一个选项,您可以使用 SVG<circle>
和<path>
元素实现类似的效果。考虑以下:
<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>
The above is fairly straight forward. We have an element containing a circle and a path. The circle's center is at 115x115 (making the SVG element 230x230). The circle has a radius of 110, making it a total of 220 wide (leaving a border of 10).
以上是相当简单的。我们有一个包含圆和路径的元素。圆的中心为 115x115(使 SVG 元素为 230x230)。该圆的半径为 110,因此它的总宽度为 220(边界为 10)。
We then add a <path>
element, which is the most complicated portion of this example. This element has one attribute which determines where, and how the path is drawn. It starts with the following value:
然后我们添加一个<path>
元素,这是这个例子中最复杂的部分。该元素有一个属性,用于确定路径的绘制位置和方式。它以以下值开头:
M115,115
This instructs the path to start in the center of the aforementioned circle. Next, we draw a line from this location to the next location:
这指示路径从上述圆的中心开始。接下来,我们从这个位置到下一个位置画一条线:
L115,5
This draws a vertical line from the center of the circle up to the top of the element (well, five pixels from the top). It is at this point things get a little more complicated but still very much intelligible.
这将绘制一条从圆心到元素顶部的垂直线(好吧,距顶部五个像素)。在这一点上,事情变得有点复杂,但仍然非常容易理解。
We now draw an arc from our present location (115,5):
我们现在从当前位置 (115,5) 绘制一条弧线:
A110,110 1 0,1 190,35 z
This creates our arc and gives it a radius matching that of our circle (110). The two values represent the x-radius and y-radius, and both are equal since we're dealing with a circle. The next set of important numbers are the last, 190,35
. This tells the arc where to complete.
这将创建我们的弧并赋予它一个与我们的圆 (110) 相匹配的半径。这两个值代表 x 半径和 y 半径,由于我们处理的是圆,因此两者相等。下一组重要数字是最后一个,190,35
。这告诉弧在哪里完成。
As for the rest of the information (1 0,1
and z
) these control the curvature, direction, and terminal of the arc itself. You can learn more about them by consulting any online SVG path reference.
至于其余的信息(1 0,1
和z
),它们控制着弧本身的曲率、方向和终点。您可以通过查阅任何在线 SVG 路径参考来了解有关它们的更多信息。
To accomplish a "slice" of a different size, merely change the 190,35
to reflect a larger or smaller set of coordinates. You may find that you'll need to create a second, arc if you want to span more than 180 degrees.
要完成不同大小的“切片”,只需更改190,35
以反映更大或更小的坐标集。如果您想要跨越 180 度以上,您可能会发现您需要创建第二个圆弧。
If you want to determine the x and y coordinates from an angle, you can use the following equations:
如果要从某个角度确定 x 和 y 坐标,可以使用以下等式:
x = cx + r * cos(a)
y = cy + r * sin(a)
With the above example, a degree of 76 would be:
在上面的例子中,度数 76 将是:
x = 115 + 110 * cos(76)
y = 115 + 110 * sin(76)
Which gives us 205.676,177.272
.
这给了我们205.676,177.272
.
With some ease, you can create the following:
您可以轻松创建以下内容:
circle {
fill: #f1f1f1;
stroke: green;
stroke-width: 5;
}
path {
fill: green;
}
svg.pie {
width: 230px;
height: 230px;
}
<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>
回答by The Pragmatick
That is very well possible using overflow
and transform
properties without any need to do complex calculations.
使用overflow
和transform
属性非常有可能,而无需进行复杂的计算。
> Rotate transform
> 旋转变换
For angles less than 180deg
对于小于 180 度的角度
Add an element with aspect ratio 2:1and
overflow: hidden;
Add a pseudo-element with with top border radii same as the height of the element and bottom radii as 0.
Put
transform-origin: 50% 100%;
This transforms the pseudo-element from its middle bottom.Transform: rotate(); the pseudo element by supplement of the required angle,
i.e.,transform: rotate(180 - rqrd. angle);
添加纵横比为 2:1的元素和
overflow: hidden;
添加一个伪元素,其顶部边框半径与元素高度相同,底部半径为 0。
Put
transform-origin: 50% 100%;
这会从中间底部转换伪元素。变换:旋转();通过所需角度的补充伪元件,
即,transform: rotate(180 - rqrd. angle);
See how it works :
看看它怎么运作 :
EG :
A 40deg sector using this method : Fiddle
EG:
使用此方法的 40deg 扇区:Fiddle
div {
...
overflow: hidden;
...
}
div:before {
...
border-radius: 100px 100px 0 0;
transform-origin: 50% 100%;
transform: rotate(140deg);
...
}
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);
}
<div></div>
> Skew transform
> 倾斜变换
You can also put image inside sector!
您也可以将图像放在扇区内!
This can be done using skew
transforms on parent and -ve skew on pseudoelement :
Fiddle
这可以使用skew
父级上的变换和伪元素上的 -ve skew来完成:
Fiddle
div {
...
overflow: hidden;
transform-origin: 0% 100%;
transform: skew(-50deg); /*Complement of rqrd angle*/
...
}
div:before {
...
transform-origin: 0% 100%;
transform: skew(50deg);
...
}
See how this works :
看看这是如何工作的:
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);
}
<div></div>
Acknowledgements: I don't want to be a self stealer, I used the ideas which I had previously used hereand here.
回答by Hashem Qolami
Does this help?
这有帮助吗?
.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%;
}
<div class="circle"></div>
Actually, some geometry calculation is needed here. But Let me explain that in short:
实际上,这里需要进行一些几何计算。但让我简单地解释一下:
Considering the 4 quarters in the circle, the angle of linear gradient can be calculated in each quarter. And the background-position
determines the quarter:
考虑圆内的4个四分之一,可以计算出每个四分之一的线性梯度角度。并background-position
确定季度:
Q I => 100% 0
Q II => 100% 100%
Q III => 0 100%
Q IV => 0 0
The only thing that remains is where the used color-stophas came from:
唯一剩下的是使用过的色标来自哪里:
Consider a 30-angledpiece of circle in the 1st quarter.
考虑第 1 季度的30 角圆。
As talented Ana Tudorhas explained in her great article, If we take the length of the width of the square to be a
, then the length of the half diagonal is going to be a*sqrt(2)/2
.
正如才华横溢的Ana Tudor在她伟大的文章中所解释的那样,如果我们取正方形的宽度a
的长度,那么半对角线的长度将是a*sqrt(2)/2
。
If we take the gradient degree to be g
the difference between two gradient and diagonal angles to be d
then the length of color-stop
can be calculated by:
如果我们把梯度度作为g
两个梯度和对角线之间的角之差,d
那么 的长度color-stop
可以计算为:
a*sin(g) / (a*sqrt(2)/2 * cos(d))
= sin(g) / (sqrt(2) /2 * cos(d))
So, in this case we have sin(30deg) / (sqrt(2)*cos((45-30)deg)) = 0.3660
, and the % value for the color stop is 36.60%
因此,在这种情况下,我们有sin(30deg) / (sqrt(2)*cos((45-30)deg)) = 0.3660
,并且色标的 % 值为36.60%
Since our shape is in the 1st quarter, the background-position
is 100% 0
.
由于我们的形状在第一季度,因此background-position
是100% 0
。
and the linear-gradient would be like this:
线性梯度将是这样的:
linear-gradient(-30deg, orange 36.60%, transparent 36.60%) 100% 0;
.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%;
}
<div class="circle"></div>
I recommend to read the Ana's article for more details.
我建议阅读 Ana 的文章以了解更多详细信息。
回答by c. schaefer
since i did not find any satisfying answer at all, i had to go down on my knees, using clip-path function and a whole sunday of css to finally get what i wanted.
由于我根本没有找到任何令人满意的答案,我不得不跪下,使用剪辑路径功能和整个星期天的 css 终于得到了我想要的。
you can choose a start and end angle and then the element will nicely draw just that, nothing else. you will need just the border-radius solution for drawing the base circle.
您可以选择开始和结束角度,然后元素将很好地绘制该角度,仅此而已。您只需要边界半径解决方案来绘制基圆。
my solutions works with a grid of four polygons, each providing a possible start or end point for the values 0-90° resp. 0-100%, 90-180° resp. 0-100% and so on, sharing the center point and hence, there are two times 4 segements. you could think about the mechanics as a telescope rod with multiple segments, each doing its segmented job from 0 to N. due to the mechanics, while still maintaining some clarity in the code (0-90,90-180 ..), i had to manually rotate(-45deg) the div, so that 0° == 12''.
我的解决方案适用于四个多边形的网格,每个多边形为 0-90° 和 0-90° 值提供一个可能的起点或终点。0-100%, 90-180° 分别 0-100% 等,共享中心点,因此,有两次 4 段。您可以将力学视为具有多个段的望远镜杆,由于力学的原因,每个段都从 0 到 N 进行分段工作,同时仍然保持代码的一些清晰度(0-90,90-180 ..),我必须手动旋转 (-45deg) div,以便 0° == 12''。
here is a little sketch that may illustrate how i did it:
这是一个小草图,可以说明我是如何做到的:
please note that you cannot use this for any commercial purposes since i did not find any solution like that online, hence, there needs to be some value to it. please respect this.
请注意,您不能将其用于任何商业目的,因为我没有在网上找到任何类似的解决方案,因此,它需要有一些价值。请尊重这一点。
drawing circle segments using css von c. schaefer ist lizenziert unter einer Creative Commons Namensnennung - Nicht kommerziell - Keine Bearbeitungen 4.0 International Lizenz.
使用 css von c 绘制圆段。schaefer ist lizenziert unter einer Creative Commons Namensnennung - Nicht kommerziell - Keine Bearbeitungen 4.0 International Lizenz。
<script src="http://code.jquery.com/jquery-latest.js"></script>
<style type="text/css">
.circle{
position: absolute;
top: 100px;
width: 600px;
height: 600px;
border-radius: 50%;
background-color: #FFFF00;
opacity: .9;
-webkit-transform: rotate(45deg);
}
}
<script type="text/javaScript">
var obj;
var start, end;
function rangeStart(val) {
obj = $("body").find(".circle");
start = val;
setAngle(obj, start, end);
}
function rangeEnd(val) {
obj = $("body").find(".circle");
end = val;
setAngle(obj, start, end);
}
function applyMasking(obj) {
obj.css("-webkit-clip-path", ptsToString());
}
// not working for degree start to be lower than end, hence, we set the interface to automatically adapt to that exception:
/*
function checkForRangeExceptions() {
if(end < start) {
$("body").find("input[name='rangeLower']").val($("body").find("input[name='rangeUpper']").val());
$("body").find("input[name='rangeLower']").slider('refresh');
}
}
*/
// setInterval(doit, 200);
var angie = 0;
function doit() {
obj = $("body").find(".circle");
if(angie < 360)
angie+=15;
else angie = 0;
setAngle(obj, 0, angie);
}
function ptsToString() {
var str = "";
str+="polygon(";
for(var i=0; i < pts.length; i++) {
str+=pts[i].x+"% ";
if(i != pts.length-1)
str+=pts[i].y+"% ,";
else str+=pts[i].y+"%";
}
str+=")";
return str;
}
/*
gets passed an html element and sets its clip-path according to the passed angle,
starting at 0°; note that from a clock perspective, we start at +45° and hence have
to add that value to passed angles later on:
*/
var pts =
[
{x: 50, y: 50}, {x: 0, y: 0}, {x: 0, y: 0},
{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0},
{x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}
];
var lb, ub;
var sa, ea;
function setAngle(obj, start, end) {
// if no start, set 0° as default:
start = (start == undefined ? start = 0 : start);
// find out upper and lower sector bounds:
lb = (angleToSector(start) * 2) - 1;
ub = angleToSector(end) * 2;
// find start end end angles:
sa = mapAngleToPoint(start);
ea = mapAngleToPoint(end);
// now set points except start point which is 0:
for(var i=1; i < pts.length; i++) {
// set all below lb to lb:
if(i <= lb) { pts[i].x = sa.x; pts[i].y = sa.y; }
// set all in between to max values:
else if(i > lb && i < ub) {
pts[i] = setMax(i);
}
// set all above ub to ub:
else if(i >= ub) { pts[i].x = ea.x; pts[i].y = ea.y; }
}
// apply masking:
applyMasking(obj);
}
// assuming that 100 need to map 90°:
function angleToPerc(angle) {
return angle * (100/90);
}
function lowerBound(angle) {
return (mapAngleToSector(angle));
}
function uppperBound(angle){
return (mapAngleToSector(angle));
}
// sectors 1-4
function angleToSector(angle) {
if (angle >= 0 && angle < 90) return 1;
else if (angle >= 90 && angle < 180) return 2;
else if (angle >= 180 && angle < 270) return 3;
else if (angle >= 270 && angle <= 360) return 4;
}
// this maps the passed angle to a coordinate value:
var as;
function mapAngleToPoint(angle) {
var pt = {x: 0, y: 0};
as = angleToSector(angle);
if(as == 1) {pt.x = angleToPerc(angle); pt.y = 0; }
else if(as == 2) {pt.x = 100; pt.y = angleToPerc(angle-90)}
else if(as == 3) {pt.x = 100-angleToPerc(angle-180); pt.y = 100; }
else if(as == 4) {pt.x = 0; pt.y = 100-angleToPerc(angle-270); }
return pt;
}
// set a point to its max by index:
function setMax(index) {
var pt = {x: 0, y: 0};
if (index == 1 || index == 2) { pt.x = 100; pt.y = 0; }
else if (index == 3 || index == 4) { pt.x = 100; pt.y = 100; }
else if (index == 5 || index == 6) { pt.x = 0; pt.y = 100; }
else if (index == 7 || index == 8) { pt.x = 0; pt.y = 0; }
return pt;
}
</script>
</head>
<body>
<div class="circle">
</div>
<input type="range" name="rangeLower" value="0" min="0" max="360" onchange="rangeStart(this.value);">
<input type="range" name="rangeUpper" value="66"min="0" max="360" onchange="rangeEnd(this.value);">
</body>
回答by Gavin
- Your need to draw a circle
- use
clip-path
to cut a sector(you need to do some math)
- 你需要画一个圆圈
- 使用
clip-path
切一个部门(你需要做一些数学)
you can play around with clip-path
here
你可以在这里玩clip-path
here is a demo:
这是一个演示:
#skills {
position: relative;
width: 300px;
height: 300px;
margin: 30px auto;
}
.circle {
width: 100%;
height: 100%;
border-radius: 50%;
position: absolute;
}
.animate {
-webkit-transition: 0.2s cubic-bezier(.74,1.13,.83,1.2);
-moz-transition: 0.2s cubic-bezier(.74,1.13,.83,1.2);
-o-transition: 0.2s cubic-bezier(.74,1.13,.83,1.2);
transition: 0.2s cubic-bezier(.74,1.13,.83,1.2);
}
.animate:hover {
transform: scale(1.1);
transform-origin: center center;
}
#part1 {
background-color: #E64C65;
-webkit-clip-path: polygon(50% 0, 50% 50%, 100% 41.2%, 100% 0);
clip-path: polygon(50% 0, 50% 50%, 100% 41.2%, 100% 0);
}
#part2 {
background-color: #11A8AB;
-webkit-clip-path: polygon(50% 50%, 100% 41.2%, 100% 100%, 63.4% 100%);
clip-path: polygon(50% 50%, 100% 41.2%, 100% 100%, 63.4% 100%);
}
#part3 {
background-color: #4FC4F6;
-webkit-clip-path: polygon(50% 50%, 36.6% 100%, 63.4% 100%);
clip-path: polygon(50% 50%, 36.6% 100%, 63.4% 100%);
}
#part4 {
background-color: #FFED0D;
-webkit-clip-path: polygon(50% 50%, 0 100%, 36.6% 100%);
clip-path: polygon(50% 50%, 0 100%, 36.6% 100%);
}
#part5 {
background-color: #F46FDA;
-webkit-clip-path: polygon(50% 50%, 0 36.6%, 0 100%);
clip-path: polygon(50% 50%, 0 36.6%, 0 100%);
}
#part6 {
background-color: #15BFCC;
-webkit-clip-path: polygon(50% 50%, 0 36.6%, 0 0, 50% 0);
clip-path: polygon(50% 50%, 0 36.6%, 0 0, 50% 0);
}
<div id="skills">
<div id="part1" class="circle animate"></div>
<div id="part2" class="circle animate"></div>
<div id="part3" class="circle animate"></div>
<div id="part4" class="circle animate"></div>
<div id="part5" class="circle animate"></div>
<div id="part6" class="circle animate"></div>
</div>
回答by Nolan
I have another solution.
我有另一个解决方案。
#pie {
position: relative;
width: 100px;
height: 100px;
background-color: #76dd76;
border-radius: 50%;
border: 1px solid #76dd76;
}
#pie:before,
#pie:after {
position: absolute;
content: "";
display: block;
width: 50%;
height: 50%;
-webkit-transform-origin: right bottom;
-moz-transform-origin: right bottom;
-ms-transform-origin: right bottom;
transform-origin: right bottom;
background-color: white;
border-top-left-radius: 100%;
}
#pie:after {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
<div id="pie"></div>
回答by Racil Hilan
All the answers here are creative. It's amazing how people solve the same problem in so many ways. The accepted answer by Sampson is really cool, but I don't know why he decided to draw the white part instead of the green, so I thought of sharing a modified version that actually draws the green. I just find it a bit more straightforward this way, so I'm sharing it in case others find it useful too.
这里的所有答案都很有创意。人们如何以多种方式解决同一问题,真是太神奇了。桑普森接受的答案真的很酷,但我不知道他为什么决定绘制白色部分而不是绿色,所以我想分享一个实际绘制绿色的修改版本。我只是觉得这样更简单一些,所以我分享它,以防其他人也觉得它有用。
pie {
width: 5em;
height: 5em;
display: block;
border-radius: 50%;
border: 2px solid green;
float: left;
margin: 1em;
}
.ten {
background-image:
linear-gradient(-54deg, white 50%, transparent 50%),
linear-gradient(-90deg, green 50%, transparent 50%);
}
.twentyfive {
background-image:
linear-gradient(0deg, white 50%, transparent 50%),
linear-gradient(-90deg, green 50%, transparent 50%);
}
.fifty {
background-image:
linear-gradient(-90deg, green 50%, transparent 50%);
}
/* Slices greater than 50% require first gradient to be green -> transparent */
.seventyfive {
background-image:
linear-gradient(0deg, green 50%, transparent 50%),
linear-gradient(-90deg, green 50%, transparent 50%);
}
.onehundred {
background-color: green;
}
<pie class="ten"></pie>
<pie class="twentyfive"></pie>
<pie class="fifty"></pie>
<pie class="seventyfive"></pie>
<pie class="onehundred"></pie>
回答by MichaB
See this to get an idea how to solve your problem.
请参阅此内容以了解如何解决您的问题。
<div class="circle"></div>
.circle{
width: 100px;
height: 100px;
background-color: green;
border-radius: 100px;
position: relative;
}
.circle:before,
.circle:after {
border: 50px solid white;
border-color: transparent transparent white white;
border-radius: 100px;
content: '';
height: 0;
position: absolute;
top: 0;
left: 0;
width: 0;
/* this is to have it white from 180 to 360 degrees on the left side */
transform:rotate(45deg);
-ms-transform:rotate(45deg); /* IE 9 */
-webkit-transform:rotate(45deg); /* Safari and Chrome */
}
/* the green sector is now 180 minus 45 plus 0 degree */
.circle:after {
transform:rotate(0deg);
-ms-transform:rotate(0deg); /* IE 9 */
-webkit-transform:rotate(0deg); /* Safari and Chrome */
}
/* the green sector is now 180 minus 45 plus -75 degree */
/*.circle:after {
transform:rotate(-75deg);
-ms-transform:rotate(-75deg);
-webkit-transform:rotate(-75deg);
}*/
回答by mahemoff
Since I needed this dynamically, here's a little jQuery plugin. e.g. call $('selector').pieChart(0.4, 'white' 'green')
to show a 40% green segment on a white circle.
由于我动态需要这个,这里有一个小的 jQuery 插件。例如调用$('selector').pieChart(0.4, 'white' 'green')
以在白色圆圈上显示 40% 的绿色段。
// LIBRARY FUNCTION
$.fn.pieChart = function(proportion, bg, fg) {
var angle, grads;
angle = Math.round(360 * (proportion % 0.5) - 90);
grads = [
"linear-gradient(" + angle + "deg, " + (proportion < 0.5 ? bg : fg) + " 50%, transparent 50% )",
"linear-gradient(-90deg, " + fg + " 50%, transparent 50%)"
];
return $(this).css({
'background-color': proportion==1 ? fg : bg,
'background-image': grads.join(','),
'border': '1px solid '+fg
});
};
// DEMO
for (var i=0; i <= 10; i++) {
$('<div class="pie" />').appendTo('body').pieChart(i/10, 'white', 'green');
}
.pie {
display: inline-block;
margin: 10px;
border-radius: 50%;
width: 100px;
height: 100px;
}
<script src="https://code.jquery.com/jquery-3.0.0.js"></script>
This is based on Racil's example here. (Note I couldn't use OP's plugin in the edited answer as it doesn't work for sectors spanning more than 180 degrees.)
这是基于 Racil 的示例 here。(请注意,我无法在编辑后的答案中使用 OP 的插件,因为它不适用于跨度超过 180 度的扇区。)
回答by Karine Larouche
You can use a circle with a dashed line.
您可以使用带虚线的圆圈。
<svg viewBox="-8 -8 16 16">
<circle
cx="0"
cy="0"
r="4"
transform="rotate(270)"
stroke-width="8"
stroke-dasharray="4, 26"
stroke="green"
fill="none"
/>
</svg>
- Make the line twice as thick as the radius of the circle, so that it reaches the center of the circle.
- Play with the
stroke-dasharray
value to determine how big of a pie size you want to see.
- 使线的厚度为圆半径的两倍,使其到达圆的中心。
- 使用该
stroke-dasharray
值来确定您想要看到的饼图大小。
Bonus: The advantage of using a circle instead of a path is that you can easily animate it when you change the pie size: Just add something like transition: stroke-dasharray .5s;
to the css of the circle.
奖励:使用圆而不是路径的优点是,当您更改饼图大小时,您可以轻松地为其设置动画:只需transition: stroke-dasharray .5s;
在圆的 css 中添加类似内容即可。