我正在使用 Raphael 库创建一个 SVG 文本框,并将其中填充一个从 XML 文档中提取的动态字符串。
有时,这个字符串比我放置文本框的画布还要长,因此我需要限制盒子的宽度以强制换行(我找不到任何证据表明这是可能的),或者确保在一定数量的字符之后插入 '\n' 换行符。
所以,(1) 这是最好的选择吗? (2) 我该如何做到这一点?
我正在使用 Raphael 库创建一个 SVG 文本框,并将其中填充一个从 XML 文档中提取的动态字符串。
有时,这个字符串比我放置文本框的画布还要长,因此我需要限制盒子的宽度以强制换行(我找不到任何证据表明这是可能的),或者确保在一定数量的字符之后插入 '\n' 换行符。
所以,(1) 这是最好的选择吗? (2) 我该如何做到这一点?
虽然没有文本换行的属性,但是有一个简单的技巧可以使用。将一个单词一个单词地添加到文本对象中,当它变得太长时,添加一个换行符。您可以使用getBBox()函数确定宽度。基本上,您模拟了一台老式打字机。这是一些代码示例,可以为您完成此操作。您可以轻松地将其转换为接受文本和宽度的简单函数。
var r = Raphael(500, 500);
var t = r.text(100, 100).attr('text-anchor', 'start');
var maxWidth = 100;
var content = "Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate. ";
var words = content.split(" ");
var tempText = "";
for (var i=0; i<words.length; i++) {
t.attr("text", tempText + " " + words[i]);
if (t.getBBox().width > maxWidth) {
tempText += "\n" + words[i];
} else {
tempText += " " + words[i];
}
}
t.attr("text", tempText.substring(1));
function textWrap(t, width) {
var content = t.attr("text");
var abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
t.attr({
'text-anchor' : 'start',
"text" : abc
});
var letterWidth = t.getBBox().width / abc.length;
t.attr({
"text" : content
});
var words = content.split(" ");
var x = 0, s = [];
for ( var i = 0; i < words.length; i++) {
var l = words[i].length;
if (x + (l * letterWidth) > width) {
s.push("\n");
x = 0;
}
x += l * letterWidth;
s.push(words[i] + " ");
}
t.attr({
"text" : s.join("")
});
}
'text-anchor': 'start'
。我将其删除后,似乎一切正常,并保留了我的原始格式。 - rwalter对于大量文本,Mark的解决方案速度较慢(Firefox 11)。我认为这是因为为了获取BBOX而多次重新呈现文本。以下函数对于大量文本来说更加高效,但或许不够精准(代码来源于raphaelmarkup项目):
/**
* @param t a raphael text shape
* @param width - pixels to wrapp text width
* modify t text adding new lines characters for wrapping it to given width.
*/
rm._textWrapp = function(t, width) {
var content = t.attr("text");
var abc="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
t.attr({'text-anchor': 'start', "text": abc});
var letterWidth=t.getBBox().width / abc.length;
t.attr({"text": content});
var words = content.split(" "), x=0, s=[];
for ( var i = 0; i < words.length; i++) {
var l = words[i].length;
if(x+l>width) {
s.push("\n")
x=0;
}
else {
x+=l*letterWidth;
}
s.push(words[i]+" ");
}
t.attr({"text": s.join("")});
};
if(x+l>width) {
看起来像是一个错误 - 它将每个测试中最后一个单词的平均字宽视为1像素。如果你失去了 else
子句并在每个 for
循环的开头放置 x+=l*letterWidth;
,它会工作得更好。此外,'text-anchor': 'start',
是不必要的 - 没有必要强制左对齐。编辑 刚刚看到 Evan 的答案考虑了这些问题,并针对此代码做出了回应,而不是 Mark 的答案。 - user56reinstatemonica8嗯,我稍微调整了一下就解决了
var words = server.split( " " );
var length = words.length;
var temp_text = "";
for( var i = 0; i < length; i++ ) {
temp_text = temp_text + ' ' + words[i];
t.attr( "text", temp_text );
if( t.getBBox().width > width ) {
temp_text = temp_text.replace(/( *)(\w+)$/, "\n$2");
}
}
t.attr( "text", temp_text.trim() );
我知道现在有点晚了,但你可能会对我的Raphael-paragraph项目感兴趣,它可以自动完成这个任务。
Raphael-paragraph允许您创建自动换行的多行文本,并设置最大宽度和高度限制、行高和文本样式配置。它可以断字长单词并截断超出垂直边界的部分。它仍然处于测试阶段,需要进行很多优化,但应该能够满足您的需求。
使用示例和文档可在GitHub页面上找到。
dist/paragraph.js
文件复制到您的项目中,要么运行 npm install raphael-paragraph
并且通过 import rp from 'raphael-paragraph/src/paragraph'
引入。 - Jimmy Breck-McKye