svg
viewBox(minX,minY,width,height)
指定矩形区域,以自适应容器大小。
circle
(cx,cy)
圆心坐标r
圆半径fill
填充色stroke
描边stroke-width
描边宽度。
fill区域的径向宽度。
它的宽度分布在两个区域:fill区域内和fill区域外,且各占一半,即(stroke-width)/2
。
dasharray
以虚线的形式将描边分成多段。
dasharray:20 10
的意思是,每段的宽度是20
,段与段之间的间隔是10
。
title
每个svg
都可以提供一个title
描述性字符串,该描述只能是纯文本。
但title
的内容不会成为svg绘图的一部分,说白了,在界面上看不到。
通常title
元素必须是其父元素的第一个子元素。
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="50" fill="lightskyblue"></circle>
</svg>
</body>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="50" fill="lightskyblue"></circle>
</svg>
<br/><br/>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="50" fill="lightskyblue" stroke="lightseagreen" stroke-width="20"></circle>
</svg>
</body>
这里的stroke-width
设置为 20
,
于是海洋绿色的描边在fill区域内占用了10
,蓝色圆可视区域因此也变小了;
海洋绿色的描边在fill区域外也占用了10
,但由于svg
的尺寸就是100*100
,所以该尺寸外的区域被截,所以正如我们所见,fill区域外有部分圆弧。
那我们就把圆半径设置得小一点儿,比如30
,这样描边区域就不会超出100*100
这么个尺寸范围。
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="30" fill="lightskyblue"></circle>
</svg>
<br/><br/>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="30" fill="lightskyblue" stroke="lightseagreen" stroke-width="20"></circle>
</svg>
</body>
svg{
border: 1px solid lightgray;
}
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="20"
></circle>
</svg><br/><br/>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="20"
stroke-dasharray="20 10"
></circle>
</svg><br/><br/>
</body>
svg{
border: 1px solid lightgray;
}
当前circle
的半径r
是30
,要想让描边恰好完全覆盖fill区域,那么描边宽度stroke-width
就应该等于30*2=60
。
将stroke-width
设置为60
后,svg
的尺寸100*100
容不下,于是扩大svg
尺寸至120*120
,同时重新设置圆心坐标为(60,60)
。
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="20"
></circle>
</svg><br/><br/>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="20"
stroke-dasharray="20 10"
></circle>
</svg><br/><br/>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" >
<circle cx="50" cy="50" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="60"
stroke-dasharray="20 10"
></circle>
</svg><br/><br/>
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" >
<circle cx="60" cy="60" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="60"
stroke-dasharray="20 10"
></circle>
</svg>
</body>
svg{
border: 1px solid lightgray;
}
stroke-dasharray
可设置各分段长度和分段间隔,如果分段间隔大于或等于circle
周长,那么将有且只有一个分段。
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" >
<circle cx="60" cy="60" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="60"
stroke-dasharray="20 189"
></circle>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120">
<circle cx="60" cy="60" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="60"
stroke-dasharray="20 189"
></circle>
</svg>
</body>
svg:nth-of-type(2){
background-color: lightskyblue;
border-radius: 50%;
}
将上面的第二个图逆时针旋转90deg,就可以得到我们预期的饼图了。
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120">
<circle cx="60" cy="60" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="60"
stroke-dasharray="20 189"
></circle>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120">
<circle cx="60" cy="60" r="30" fill="lightskyblue"
stroke="lightseagreen"
stroke-width="60"
stroke-dasharray="20 189"
></circle>
</svg>
</body>
svg:nth-of-type(1){
background-color: lightskyblue;
border-radius: 50%;
}
svg:nth-of-type(2){
background-color: lightskyblue;
border-radius: 50%;
transform:rotate(-90deg);
}
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120">
<circle cx="60" cy="60" r="30"></circle>
</svg>
</body>
svg{
background-color: lightskyblue;
border-radius: 50%;
transform:rotate(-90deg);
}
circle{
fill: lightskyblue;
stroke: lightseagreen;
stroke-width: 60;
stroke-dasharray: 0 189;
animation: fillup 10s linear infinite;
}
@keyframes fillup{
to{
stroke-dasharray:189 189;
}
}
如果circle
周长是100
就好了,这样百分比就好算了。
恩,r=100/(2*3.14)
,约16
。
<body>
<div class="pie">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<circle cx="16" cy="16" r="16"></circle>
</svg>
</div>
</body>
svg{
background-color: lightskyblue;
border-radius: 50%;
transform:rotate(-90deg);
}
circle{
fill: lightskyblue;
stroke: lightseagreen;
stroke-width: 32;
stroke-dasharray: 60 100;
}
.pie{
width: 100px;
height: 100px;
}
<body>
<div class="pie">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<title>20%</title>
<circle cx="16" cy="16" r="16"
stroke-dasharray="20 100"
></circle>
</svg>
</div>
<div class="pie">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<title>60%</title>
<circle cx="16" cy="16" r="16"
stroke-dasharray="60 100"
></circle>
</svg>
</div>
</body>
svg{
background-color: lightskyblue;
border-radius: 50%;
transform:rotate(-90deg);
}
circle{
fill: lightskyblue;
stroke: lightseagreen;
stroke-width: 32;
}
.pie{
width: 100px;
height: 100px;
}
用js脚本生成以上内容。
<body>
<div class="pie">20%</div>
<div class="pie">60%</div>
<script>
document.querySelectorAll(".pie").forEach(function(pie){
var p = parseFloat(pie.textContent);
var NS = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(NS,"svg");
svg.setAttribute("viewBox","0 0 32 32");
var title = document.createElementNS(NS,"title");
title.textContent = pie.textContent;
pie.textContent = "";
svg.appendChild(title);
var circle = document.createElementNS(NS,"circle");
circle.setAttribute("cx",16);
circle.setAttribute("cy",16);
circle.setAttribute("r",16);
circle.setAttribute("stroke-dasharray",p+" 100");
svg.appendChild(circle);
pie.appendChild(svg);
})
</script>
</body>
svg{
background-color: lightskyblue;
border-radius: 50%;
transform:rotate(-90deg);
}
circle{
fill: lightskyblue;
stroke: lightseagreen;
stroke-width: 32;
}
.pie{
width: 100px;
height: 100px;
}
使用stroke-dashoffset
制作两种以上颜色的饼图。
<body>
<div class="pie">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" >
<circle cx="16" cy="16" r="16" stroke-dasharray="20 100" fill="lightskyblue" stroke="lightseagreen"></circle>
<circle cx="16" cy="16" r="16" stroke-dasharray="40 100" stroke-dashoffset="-20" fill="transparent" stroke="lightgoldenrodyellow"></circle>
</svg>
</div>
<div class="pie">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" >
<circle cx="16" cy="16" r="16" stroke-dasharray="20 100" fill="lightskyblue" stroke="lightseagreen"></circle>
<circle cx="16" cy="16" r="16" stroke-dasharray="40 100" stroke-dashoffset="-20" fill="transparent" stroke="lightgoldenrodyellow"></circle>
<circle cx="16" cy="16" r="16" stroke-dasharray="10 100" stroke-dashoffset="-60" fill="transparent" stroke="gold"></circle>
</svg>
</div>
<div class="pie">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" >
<circle cx="16" cy="16" r="16" stroke-dasharray="20 100" fill="lightskyblue" stroke="lightseagreen"></circle>
<circle cx="16" cy="16" r="16" stroke-dasharray="40 100" stroke-dashoffset="-20" fill="transparent" stroke="lightgoldenrodyellow"></circle>
<circle cx="16" cy="16" r="16" stroke-dasharray="10 100" stroke-dashoffset="-60" fill="transparent" stroke="gold"></circle>
<circle cx="16" cy="16" r="16" stroke-dasharray="10 100" stroke-dashoffset="-70" fill="transparent" stroke="orange"></circle>
</svg>
</div>
</body>
svg{
background-color: lightskyblue;
border-radius: 50%;
transform:rotate(-90deg);
}
circle{
stroke-width: 32;
}
.pie{
width: 100px;
height: 100px;
}