How to add a path with 'd' attributes to a svg dynamically [duplicate]

两盒软妹~` 提交于 2021-01-04 09:17:16

问题


I'm having a problem dynamically generating path elements inside an empty svg with javascript. I'm not interested in using third-party libraries, I'd like to understand how it works in vanilla javascript. For the following codepen, I'm using jQuery for simplicity's sake.

here is the javascript for those not interested in visiting the codepen link:

$(function() {
  function calculateX(degrees, radius) {
    var radians = Math.PI * degrees / 180;
    return Math.ceil(radius + (radius * Math.cos(radians)));
  }

  function calculateY(degrees, radius) {
    var radians = Math.PI * degrees / 180;
    return Math.ceil(radius + (radius * Math.sin(radians)));
  }
  var d, opacity, len = 6,
    path, endAngle, degrees = 360 / len,
    startAngle = 270;
  for (var i = 0; i < len; i++) {
    opacity = 'rgba(255,0,0,' +parseFloat((i / len).toPrecision(2)) + ')';
    endAngle = (startAngle + degrees) % 360;
    d = 'M100 100 L' + calculateX(startAngle, 100) + ' ' +
      calculateY(startAngle, 100) + ' A100 100 0 0 1 ' +
      calculateX(endAngle, 100) + ' ' +
      calculateY(endAngle, 100) + ' Z';
    path = $('<path>').appendTo('svg');
    path.css({'background': opacity, 'fill': opacity});
    path[0].setAttribute('d', d);
    startAngle = endAngle;
  }

});

If I cut and paste the generated html from the developer console into the html section of the codepen, the result is exactly what I want, so I think my d attributes are being generated correctly, it just seems the DOM is not being updated properly or needs some sort of signal to redraw the svg?

here is the html fragment that is generated:

<svg viewBox="0 0 200 200"><path d="M100 100 L100 0 A100 100 0 0 1 187 50 Z" style="fill: rgba(255, 0, 0, 0); background: rgba(255, 0, 0, 0);"></path><path d="M100 100 L187 50 A100 100 0 0 1 187 150 Z" style="fill: rgba(255, 0, 0, 0.168627); background: rgba(255, 0, 0, 0.168627);"></path><path d="M100 100 L187 150 A100 100 0 0 1 100 200 Z" style="fill: rgba(255, 0, 0, 0.329412); background: rgba(255, 0, 0, 0.329412);"></path><path d="M100 100 L100 200 A100 100 0 0 1 14 150 Z" style="fill: rgba(255, 0, 0, 0.498039); background: rgba(255, 0, 0, 0.498039);"></path><path d="M100 100 L14 150 A100 100 0 0 1 14 50 Z" style="fill: rgba(255, 0, 0, 0.670588); background: rgba(255, 0, 0, 0.670588);"></path><path d="M100 100 L14 50 A100 100 0 0 1 100 0 Z" style="fill: rgba(255, 0, 0, 0.831373); background: rgba(255, 0, 0, 0.831373);"></path></svg>

回答1:


When you create an object in a different namespace, you have to use document.createElementNS() instead of document.createElement().

JQuery's appendTo() function doesn't invoke createElementNS(), so although your code is creating a perfectly valid SVG element, you aren't seeing anything because the HTML parser doesn't understand it.

This works:

$(function() {
  function calculateX(degrees, radius) {
    var radians = Math.PI * degrees / 180;
    return Math.ceil(radius + (radius * Math.cos(radians)));
  }

  function calculateY(degrees, radius) {
    var radians = Math.PI * degrees / 180;
    return Math.ceil(radius + (radius * Math.sin(radians)));
  }
  var d, opacity, len = 6,
    path, endAngle, degrees = 360 / len,
    startAngle = 270,
    svg = document.getElementById('piechart'),
    ns = 'http://www.w3.org/2000/svg';
  for (var i = 0; i < len; i++) {
    fill = 'rgba(255,0,0,' +parseFloat((i / len).toPrecision(2)) + ')';
    endAngle = (startAngle + degrees) % 360;
    d = 'M100 100 L' + calculateX(startAngle, 100) + ' ' +
      calculateY(startAngle, 100) + ' A100 100 0 0 1 ' +
      calculateX(endAngle, 100) + ' ' +
      calculateY(endAngle, 100) + ' Z';
    path = document.createElementNS(ns,'path');
    path.setAttribute('fill', fill);
    path.setAttribute('d', d);
    svg.appendChild(path);
    startAngle = endAngle;
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<svg id="piechart" xmlns="http://www.w3.org/2000/svg"
     width="200" height="200" viewBox="0 0 200 200">
</svg>


来源:https://stackoverflow.com/questions/31977330/how-to-add-a-path-with-d-attributes-to-a-svg-dynamically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!