Как определить ширину текстового поля SVG или сделать разрывы строк после символов «х»? - PullRequest
28 голосов
/ 29 июня 2010

Я создаю текстовое поле SVG с использованием библиотеки Raphael и заполняю его динамической строкой, извлеченной из документа XML.

Иногда эта строка длиннее, чем холст, на который я помещаю текстовое поле, поэтому мне нужно либо ограничить ширину поля, что само по себе приведет к разрывам строк (я не могу найти никаких доказательств того, что это возможно) ) ИЛИ убедитесь, что после определенного количества символов вставляется разрыв строки '\ n'.

Итак (1) это лучший вариант? И (2) как бы я это сделал?

Ответы [ 5 ]

47 голосов
/ 01 июля 2010

Нет атрибута для переноса текста, но есть простой прием, который вы можете использовать.Добавляйте по одному слову за раз к текстовому объекту, а когда он станет слишком широким, добавьте перевод строки.Вы можете использовать функцию 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));
9 голосов
/ 28 марта 2012

спасибо за ответ. Однако я обнаружил, что мне нужно несколько настроек, чтобы работать для меня:

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("")
    });
}

Изменения были:

  • сравнение, необходимое для использования (l * letterwidth) ... не просто l
  • if / else изменилось на просто if - так, чтобы разрыв строки всегда устанавливал X в 0
  • и всегда добавляйте новую ширину буквы l * к значению x

надеюсь, это поможет.

3 голосов
/ 22 марта 2012
* Метка

работает медленно для больших объемов текста (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("")});
};
0 голосов
/ 25 мая 2015

Я знаю, что это немного запоздало, но вас может заинтересовать мой Рафаэль-абзац , который делает это автоматически.

Рафаэль-абзац позволяет создавать автоматически упакованные многострочныетекст с максимальными ограничениями ширины и высоты, высотой строки и конфигурацией стиля текста.Он может переносить длинные слова и обрезать их, если они превышают вертикальные границы.Это все еще бета-версия и требует большой оптимизации, но она должна работать для ваших целей.

Примеры использования и документация приведены на странице GitHub.

0 голосов
/ 11 сентября 2013

Ну, я решил это немного подправив

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() );
...