【问题标题】:Control the order of visibility of the multiple paths of SVG element控制SVG元素多条路径的可见顺序
【发布时间】:2022-01-20 06:35:07
【问题描述】:

我正在寻找一种在 html 中显示带有圆形虚线边框的图像的方法,如下例所示

这样可以控制破折号的数量及其各自的颜色,类似的示例可以在 WhatsApp 应用程序状态选项卡中观察到,其中破折号的数量根据用户上传的状态数量而变化。

现在为了解决我应用以下步骤来产生所需输出的问题,显然代码不是我编写的,但我做了更改

  1. 在 SVG 中使用相等长度的相等值生成简单的 Pi 图表
  2. 根据需要为各个切片着色
  3. 在实际输出或几乎接近输出结果的 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">

【问题讨论】:

  • 这是按编码工作的。第 0 段的起点是右、中,之后按顺时针顺序绘制后续段。如果您希望使用另一个原点绘制线段,请将 startAngle 和 endAngle 更改为您喜欢的值。如果您希望它从顶部开始绘图,则: var startAngle=Math.PI*1.5, endAngle=Math.PI*1.5;
  • 按照 Michael 的建议减去一半的 PI,或者切换你的 sin()cos()。 IE。 (Math.sin(startAngle)*radius+radius)+","+(-Math.cos(startAngle)*radius+radius).

标签: javascript html css svg


【解决方案1】:

最后我从@Michael 的评论中找到了解决方案,顺序是正确的,但渲染起点不是从圆圈的顶部开始,因此将startAngleendAngle 初始化为Math.PI * 1.5 可以解决问题,例如换行

var startAngle=0, endAngle=0;

var startAngle=Math.PI * 1.5, endAngle=Math.PI * 1.5;

【讨论】:

    猜你喜欢
    • 2020-09-15
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多