Javascript SVG:使用 getComputedTextLength 来包装文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7046986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SVG: using getComputedTextLength to wrap text
提问by EML
I'm trying to wrap text by building up a text string, and using getComputedTextLength
to find out when the text goes beyond the allowed width. However, I can't find a simple way to incrementally build up the text which will work with getComputedTextLength
.
我试图通过构建文本字符串来包装文本,并使用它getComputedTextLength
来找出文本何时超出允许的宽度。但是,我找不到一种简单的方法来逐步构建适用于getComputedTextLength
.
The general idea is:
总体思路是:
str = svgDocument.createTextNode(myText[word]); // first word on new line
word++;
obj = text.cloneNode(true); // new text element for this line
obj.appendChild(str);
svgDocument.documentElement.appendChild(obj); // reqd for getComputedTextLength?
for( ; word < myText.length; word++) {
next_width = obj.getComputedTextLength(); // get current line width
if(next_width >= extent)
break;
str += " "; // add next word to the line
str += myText[word];
...
}
Can anyone tell me how to get this to work? Presumably str
is copied rather than referenced in obj
, but I've also tried putting obj.removeChild(str)
and obj.appendChild(str)
in the loop, but the appendChild
crashes. I've also tried various combinations of moving around the documentElement.appendChild
, and removing obj
and re-appending it, and so on.
谁能告诉我如何让这个工作?大概str
是在 中复制而不是引用obj
,但我也尝试将obj.removeChild(str)
和obj.appendChild(str)
放入循环中,但appendChild
崩溃了。我还尝试了在 周围移动documentElement.appendChild
、删除obj
和重新附加它的各种组合,等等。
回答by Peter Collingridge
This should work:
这应该有效:
var svgNS = "http://www.w3.org/2000/svg";
var width = 200;
function init(evt)
{
if ( window.svgDocument == null ) {
svgDocument = evt.target.ownerDocument;
}
create_multiline("Whatever text you want here.");
}
function create_multiline(text) {
var words = text.split(' ');
var text_element = svgDocument.getElementById('multiline-text');
var tspan_element = document.createElementNS(svgNS, "tspan"); // Create first tspan element
var text_node = svgDocument.createTextNode(words[0]); // Create text in tspan element
tspan_element.appendChild(text_node); // Add tspan element to DOM
text_element.appendChild(tspan_element); // Add text to tspan element
for(var i=1; i<words.length; i++)
{
var len = tspan_element.firstChild.data.length; // Find number of letters in string
tspan_element.firstChild.data += " " + words[i]; // Add next word
if (tspan_element.getComputedTextLength() > width)
{
tspan_element.firstChild.data = tspan_element.firstChild.data.slice(0, len); // Remove added word
var tspan_element = document.createElementNS(svgNS, "tspan"); // Create new tspan element
tspan_element.setAttributeNS(null, "x", 10);
tspan_element.setAttributeNS(null, "dy", 18);
text_node = svgDocument.createTextNode(words[i]);
tspan_element.appendChild(text_node);
text_element.appendChild(tspan_element);
}
}
}
]]>
</script>
<text x="10" y="50" id="multiline-text"> </text>
It works by adding tspan elements to the text element and then adding text to each of them.
它的工作原理是将 tspan 元素添加到文本元素,然后向每个元素添加文本。
The result is something like:
结果是这样的:
<text>
<tspan>Whatever text</tspan>
<tspan>you want here.</tspan>
</text>
In order for getComputerTextLength to work, you need to create the tspan (or text) element first and make sure it is in DOM. Also note that in order to add text to a tspan element, you need to use createTextNode() and append the result.
为了让 getComputerTextLength 起作用,您需要先创建 tspan(或文本)元素并确保它在 DOM 中。另请注意,为了向 tspan 元素添加文本,您需要使用 createTextNode() 并附加结果。
回答by user2846569
a wrapper function for overflowing text:
用于溢出文本的包装函数:
function wrap() {
var self = d3.select(this),
textLength = self.node().getComputedTextLength(),
text = self.text();
while (textLength > (width - 2 * padding) && text.length > 0) {
text = text.slice(0, -1);
self.text(text + '...');
textLength = self.node().getComputedTextLength();
}
}
usage:
用法:
text.append('tspan').text(function(d) { return d.name; }).each(wrap);