Подтвердить что ты не робот

Как определить ширину текстового окна SVG или разрывы силовой линии после символов "x"?

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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 * letterwidth к значению x

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

Ответ 3

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

Ответ 4

Ну, я решил немного настроить его

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

Ответ 5

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

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

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