Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何确定SVG文本框宽度,或在';x';角色?_Javascript_Html_Svg_Raphael - Fatal编程技术网

Javascript 如何确定SVG文本框宽度,或在';x';角色?

Javascript 如何确定SVG文本框宽度,或在';x';角色?,javascript,html,svg,raphael,Javascript,Html,Svg,Raphael,我正在使用Raphael库创建一个SVG文本框,并用从XML文档中提取的动态字符串填充它 有时,此字符串比我放置文本框的画布长,因此我需要限制框的宽度,这将强制换行(我找不到任何可能的证据),或者确保在一定数量的字符后插入“\n”换行符 那么(1)这是最好的选择吗?(2)我将如何做到这一点?文本包装没有属性,但有一个简单的技巧可以使用。每次向文本对象添加一个单词,当它变得太宽时,添加换行符。您可以使用getBBox()函数来确定宽度。基本上,你模仿一台老式打字机。下面是一些代码的示例,它们将为您

我正在使用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));
var r=Raphael(500500);
var t=r.text(100100).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,孕妇,调味品sit amet,nunc.Nam a nibh.Donec suscipit eros.Nam mi.Proin viverra leo ut odio.Curabitur malesuada.前庭a velit eu ante scelerisque Vulpute.”;
var words=content.split(“”);
var=”;
对于(变量i=0;i最大宽度){
TENTEXT+=“\n”+单词[i];
}否则{
TENTEXT+=“”+单词[i];
}
}
t、 attr(“text”,testext.substring(1));

马克的解决方案对于大量文本的处理速度很慢(firefox 11)。我认为这是因为为了得到BBOX,文本被重新渲染了好几次。以下函数对于大量文本更有效,但可能不太精确(来自的代码):

/**
*@param t a raphael文本形状
*@param width-像素到包装文本宽度
*修改t文本添加新行字符以将其包装到给定宽度。
*/
rm._textWrapp=函数(t,宽度){
var内容=t.attr(“文本”);
var abc=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz”;
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宽度){
s、 推送(“\n”)
x=0;
}
否则{
x+=l*字体宽度;
}
s、 推(字[i]+“”);
}
t、 attr({“text”:s.join(“”)});
};

谢谢你的回答。然而,我发现我需要一些调整来为我工作:

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("")
    });
}
函数文本换行(t,宽度){
var内容=t.attr(“文本”);
var abc=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz”;
t、 属性({
“文本锚定”:“开始”,
“文本”:abc
});
var letterWidth=t.getBBox().width/abc.length;
t、 属性({
“文本”:内容
});
var words=content.split(“”);
var x=0,s=[];
for(var i=0;i宽度){
s、 推送(“\n”);
x=0;
}
x+=l*字体宽度;
s、 推(字[i]+“”);
}
t、 属性({
“文本”:s.join(“”)
});
}
这些变化是:

  • 需要使用的比较(l*字母宽度)。。。不只是我
  • if/else仅更改为if-以便换行符始终将X设置为0
  • 并始终将新的l*字母宽度添加到x值

希望这有帮助。

嗯,我解决了它,稍微调整了一下

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() );
var words=server.split(“”);
var-length=words.length;
var temp_text=“”;
对于(变量i=0;iwidth){
临时文本=临时文本。替换(/(*)(\w+)$/,“\n$2”);
}
}
t、 attr(“text”,temp_text.trim());

我知道现在有点晚了,但你可能会对我的项目感兴趣,它会自动完成这项工作

Raphael段落允许您创建具有最大宽度和高度约束、线条高度和文字样式配置的自动包装多行文字。它可以将长单词连字号,并在它们超过垂直边界时将其截断。它仍然是测试版,需要大量优化,但它应该适合您的目的


GitHub页面上提供了使用示例和文档。

谢谢您的帮助-尽管我不确定您为什么需要在顶部使用此代码:
“text-anchor”:“start”
。我删除了它,它似乎工作正常,并保留了我的原始格式。+1这是对Cancerbero代码的改进,如果性能是一个因素,这是页面上的最佳选项。一个可能的改进:letterwidth是每个字体和字体大小的常量,因此如果在大量文本上运行此操作,则可以通过将letterwidth存储在适当范围的变量中,而不是使用每个元素的文本属性切换来重新计算它,从而获得适度的性能提升。我建议将其存储在一个对象中,由font-family和font-size.Nice设置键,但是
if(x+l>width){
看起来像是一个错误-它将每个测试中最后一个单词的平均字母宽度视为1px。如果丢失
else
子句,并将
x+=l*letterWidth;
放在
for
循环的每个
开头。另外
文本锚定:'start',
是不必要的-无需强制左对齐。只需编辑即可看到Evan的答案考虑到了这些,并且是对这段代码的回应,而不是Mark的。我已经编写了一个基本上就是这样做的库,名为raphael段落。见下面我的答案。你能提供关于如何使用库的详细信息吗?导入哪个文件
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() );