如何使用JS动态创建SVG文本元素

4

我有一个SVG元素,里面是一段文本。我想用JavaScript动态创建更多完全相同的SVG文本元素。(最好使用某种for循环)。一种选项是硬编码输入值,但我不想这样做。以下是我的代码:

var overlapThreshold = "50%";
var name_count = 0;
Draggable.create(".seat_name", {
  bounds: "svg",
  onDrag: function(e) {
    if (this.hitTest("#test1", overlapThreshold)) {
      document.getElementById("test1").setAttribute('fill', 'url(#gradRed)');
    } else {
      document.getElementById("test1").setAttribute('fill', 'url(#gradGreen)');
    }
  }
});

function change_name(event) {
  var name = prompt("Enter a New Name:");
  if (name != null && name != "") {
    event.target.textContent = name;
  }
}
  <button id="test_button" onclick="create_name_tags()">Test</button> <svg height="1000" width="1000">
  <defs>
    <lineargradient id="gradGreen" x1="0%" x2="100%" y1="0%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(152, 251, 152);stop-opacity:1"></stop>
      <stop offset="100%" style="stop-color:rgb(0, 128, 0);stop-opacity:1"></stop>
    </lineargradient>
    <lineargradient id="gradRed" x1="0%" x2="100%" y1="0%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255, 0, 0);stop-opacity:1"></stop>
      <stop offset="100%" style="stop-color:rgb(178, 34, 34);stop-opacity:1"></stop>
    </lineargradient>
  </defs>
  <g class="circle_seat" id="circle_seats">
    <circle cx="70" cy="200" fill="url(#gradGreen)" id="test1" id="seat1" r="40" stroke="black" stroke-width="1"></circle>
  </g>
  <g class="seat_name" id="seat_name1">
    <text fill="#black" font-family="Verdana" font-size="20" id="seat1_details" ondblclick="change_name(event)" x="250" y="210">
      BLANK
    </text>
  </g>
  </svg>


当使用“运行代码片段”时,它返回一个错误,“Draggable”未定义。 - SPlatten
TL;dr: var el = document.createElementNS("http://www.w3.org/2000/svg", "text"); ....将 text 替换为元素类型(例如,path 等)。要设置属性,请使用 setAttributeNS,例如 el.setAttributeNS(null, 'x', x); 更多信息请参见此答案 - ashleedawg
3个回答

2
这是我动态创建文本的方法。您需要定义一个包含文本属性和文本内容的对象。

const SVG_NS = "http://www.w3.org/2000/svg";
// an object to define the properties and text content of the text element 
let o = {
  props: {
    x: 50,
    y: 15,
    "dominant-baseline": "middle",
    "text-anchor": "middle"
  },
  txtConent: "test text"
};

// a function to create a text element 
function drawText(o, parent) {
  // create a new text element
  let text = document.createElementNS(SVG_NS, "text");
  //set the attributes for the text
  for (var name in o.props) {
    if (o.props.hasOwnProperty(name)) {
      text.setAttributeNS(null, name, o.props[name]);
    }
  }
  // set the text content
  text.textContent = o.txtConent;
  // append the text to an svg element of your choice
  parent.appendChild(text);
  return text;
}

drawText(o, theSvg);
svg{border:1px solid}
<svg id="theSvg" viewBox="0 0 100 30"></svg>

如果您也需要一种动态更改文本内容的方法,我会这样做:

const SVG_NS = "http://www.w3.org/2000/svg";
// an object to define the initial properties and text content of the text element 
let o = {
  props: {
    x: 50,
    y: 15,
    "dominant-baseline": "middle",
    "text-anchor": "middle"
  },
  txtConent: "your name"
};

// a function to create a text element 
function drawText(o, parent) {
  var text = document.createElementNS(SVG_NS, "text");
  for (var name in o.props) {
    if (o.props.hasOwnProperty(name)) {
      text.setAttributeNS(null, name, o.props[name]);
    }
  }
  text.textContent = o.txtConent;
  parent.appendChild(text);
  return text;
}

// a function to update the text
function updateText(text,txtConent){
  text.textContent = txtConent;
}


//you save the text in a variable
let txt = drawText(o, theSvg);
// you update the text content when the user is changing the value of the input
theName.addEventListener("input", ()=>{updateText(txt,theName.value)})
svg{border:1px solid}
<p>The name: <input type="text" id="theName" /></p>
<svg id="theSvg" viewBox="0 0 100 30"></svg>

我希望它有所帮助。


2

简化示例 (可以选择使用Google字体)

addText("Your Text Here", 20, 50);

function addText(txt, x, y) {
  var el = document.createElementNS("http://www.w3.org/2000/svg", "text");
  el.textContent = txt;
  el.setAttributeNS(null, 'x', x);
  el.setAttributeNS(null, 'y', y);
  document.getElementById('svg').appendChild(el);
}
#svg{ width:100vw; height:100vw; font-family:'Crafty Girls'; font-size:50px;
      stroke:red; fill:yellow; }
<link href="https://fonts.googleapis.com/css2?family=Crafty+Girls&display=swap" rel="stylesheet">

<svg id='svg'></svg>


Documentation:


-1

var shape = document.createElementNS("http://www.w3.org/2000/svg", "circle");   
shape.setAttribute("cx", 25);
shape.setAttribute("cy", 25);
shape.setAttribute("r",  20);
shape.setAttribute("fill", "url(#gradGreen)");
shape.setAttribute("stroke","black");
shape.setAttribute("class","circle_seat");
document.getElementById("circle_seats").appendChild(shape);


这似乎不会创建文本元素,而这正是问题所要求的。 - Robert Longson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接