控制 SVG 元素多条路径的可见顺序
Control the order of visibility of the multiple paths of SVG element
我正在寻找一种方法来显示 html 中带有圆形虚线边框的图像,如下例所示
这样可以控制破折号的数量及其各自的颜色,可以在 WhatsApp 应用程序状态选项卡中观察到类似的示例,其中破折号的数量根据用户上传的状态数量而变化。
现在为了解决这个问题,我应用了以下步骤来产生所需的输出,显然代码不是我写的,但我进行了更改
- 使用等长的等值在 SVG 中生成简单圆周率图
- 根据需要给各个切片上色
- 在 SVG 元素实际输出之上或几乎接近输出结果生成显示图像
现在在下面的代码中我遇到了一个我无法解决的奇怪问题,虚线的顺序不一样,例如如上图所示,紫色应该先出现,然后是橙色,然后是其余的灰色条到圆圈的末端,但实际输出不同。
function pie(data){
// set size of <svg> element
$('#'+data.$id).attr("width", 2*data.radius);
$('#'+data.$id).attr("height", 2*data.radius);
// calculate sum of values
var sum=0;
var radius=data.radius;
for(var e=0; e<data.segments.length; e++){
sum+=data.segments[e].value;
}
// generate proportional pie for all segments
var startAngle=0, endAngle=0;
for(var i=0; i<data.segments.length; i++){
var element=data.segments[i];
var angle=element.value * 2 * Math.PI / sum;
endAngle+=angle;
var svgLine=makeSVG('line',{x1: radius, y1: radius, x2: (Math.cos(endAngle)*radius+radius), y2: (Math.sin(endAngle)*radius+radius), stroke: element.color});
$('#'+data.$id).append(svgLine);
var pathStr=
"M "+(radius)+","+(radius)+" "+
"L "+(Math.cos(startAngle)*radius+radius)+","+
(Math.sin(startAngle)*radius+radius)+" "+
"A "+(radius)+","+(radius)+
" 0 "+(angle<Math.PI?"0":"1")+" 1 "+
(Math.cos(endAngle)*radius+radius)+","+
(Math.sin(endAngle)*radius+radius)+" "+
"Z";
var svgPath=makeSVG('path',{"d": pathStr, "fill": element.color, stroke:"white", "stroke-width": "4" });
$('#'+data.$id).append(svgPath);
startAngle+=angle;
}
};
function makeSVG(tag, attrs) {
var el= document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
} //SVG Maker
var example={ //set parameters for pie chart
$id: "pie1", //set id of <svg> containning pie
radius: 56, //set radius of pie
segments: [
{value: 1, color: "#7E57F9"},
{value: 1, color: "#7E57F9"},
{value: 1, color: "#7E57F9"},
{value: 1, color: "#7E57F9"},
{value: 1, color: "#F9A657"},
{value: 1, color: "#D3D3D3"},
{value: 1, color: "#D3D3D3"}
]
};
pie(example);
svg {
margin-top: -10px;
margin-left: -10px;
}
img {
width: 100px;
height: 100px;
border-radius: 50%;
position: absolute;
top: 4px;
left: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg id="pie1"></svg>
<img src="https://5.imimg.com/data5/SELLER/Default/2020/8/ND/OY/KF/111699996/country-hen-500x500.jpg" width="100">
最后我从@Michael的评论中找到了解决方案,顺序是正确的但是渲染起点不是从圆的顶部所以初始化startAngle
和endAngle
到Math.PI * 1.5
解决了问题,例如替换行
var startAngle=0, endAngle=0;
和
var startAngle=Math.PI * 1.5, endAngle=Math.PI * 1.5;
我正在寻找一种方法来显示 html 中带有圆形虚线边框的图像,如下例所示
这样可以控制破折号的数量及其各自的颜色,可以在 WhatsApp 应用程序状态选项卡中观察到类似的示例,其中破折号的数量根据用户上传的状态数量而变化。
现在为了解决这个问题,我应用了以下步骤来产生所需的输出,显然代码不是我写的,但我进行了更改
- 使用等长的等值在 SVG 中生成简单圆周率图
- 根据需要给各个切片上色
- 在 SVG 元素实际输出之上或几乎接近输出结果生成显示图像
现在在下面的代码中我遇到了一个我无法解决的奇怪问题,虚线的顺序不一样,例如如上图所示,紫色应该先出现,然后是橙色,然后是其余的灰色条到圆圈的末端,但实际输出不同。
function pie(data){
// set size of <svg> element
$('#'+data.$id).attr("width", 2*data.radius);
$('#'+data.$id).attr("height", 2*data.radius);
// calculate sum of values
var sum=0;
var radius=data.radius;
for(var e=0; e<data.segments.length; e++){
sum+=data.segments[e].value;
}
// generate proportional pie for all segments
var startAngle=0, endAngle=0;
for(var i=0; i<data.segments.length; i++){
var element=data.segments[i];
var angle=element.value * 2 * Math.PI / sum;
endAngle+=angle;
var svgLine=makeSVG('line',{x1: radius, y1: radius, x2: (Math.cos(endAngle)*radius+radius), y2: (Math.sin(endAngle)*radius+radius), stroke: element.color});
$('#'+data.$id).append(svgLine);
var pathStr=
"M "+(radius)+","+(radius)+" "+
"L "+(Math.cos(startAngle)*radius+radius)+","+
(Math.sin(startAngle)*radius+radius)+" "+
"A "+(radius)+","+(radius)+
" 0 "+(angle<Math.PI?"0":"1")+" 1 "+
(Math.cos(endAngle)*radius+radius)+","+
(Math.sin(endAngle)*radius+radius)+" "+
"Z";
var svgPath=makeSVG('path',{"d": pathStr, "fill": element.color, stroke:"white", "stroke-width": "4" });
$('#'+data.$id).append(svgPath);
startAngle+=angle;
}
};
function makeSVG(tag, attrs) {
var el= document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
} //SVG Maker
var example={ //set parameters for pie chart
$id: "pie1", //set id of <svg> containning pie
radius: 56, //set radius of pie
segments: [
{value: 1, color: "#7E57F9"},
{value: 1, color: "#7E57F9"},
{value: 1, color: "#7E57F9"},
{value: 1, color: "#7E57F9"},
{value: 1, color: "#F9A657"},
{value: 1, color: "#D3D3D3"},
{value: 1, color: "#D3D3D3"}
]
};
pie(example);
svg {
margin-top: -10px;
margin-left: -10px;
}
img {
width: 100px;
height: 100px;
border-radius: 50%;
position: absolute;
top: 4px;
left: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg id="pie1"></svg>
<img src="https://5.imimg.com/data5/SELLER/Default/2020/8/ND/OY/KF/111699996/country-hen-500x500.jpg" width="100">
最后我从@Michael的评论中找到了解决方案,顺序是正确的但是渲染起点不是从圆的顶部所以初始化startAngle
和endAngle
到Math.PI * 1.5
解决了问题,例如替换行
var startAngle=0, endAngle=0;
和
var startAngle=Math.PI * 1.5, endAngle=Math.PI * 1.5;