28 votes

Comment déterminer la largeur de la zone de texte SVG ou forcer les sauts de ligne après les caractères 'x'?

Je suis de la création d'un SVG zone de texte en utilisant le Raphaël de la bibliothèque, et de le remplir avec une chaîne dynamique qui est un extrait d'un document XML.

Parfois, cette chaîne est plus longue que la toile je suis de placer la zone de texte, donc j'ai besoin de limiter la largeur de la zone qui sera lui-même la force de les sauts de ligne (je ne trouve pas de preuves de ce qui est possible) OU de s'assurer qu'un '\n' saut de ligne est inséré après un certain nombre de caractères.

Si (1) est-ce la meilleure option? Et (2) comment puis-je faire?

47voto

Mark Points 3491

Il n'y a pas d'attribut pour l'habillage du texte, mais il existe une astuce simple que vous pouvez utiliser. Ajoutez un mot à la fois à un objet texte et lorsqu'il devient trop large, ajoutez un saut de ligne. Vous pouvez utiliser la fonction getBBox () pour déterminer la largeur. Fondamentalement, vous émulez une machine à écrire à l'ancienne. Voici un exemple de code qui le fera pour vous. Vous pouvez facilement transformer cela en une fonction simple qui prend le texte et une largeur.

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

9voto

Evan Points 101

Merci d'avoir répondu. Cependant, j'ai trouvé que j'avais besoin de quelques ajustements pour travailler pour moi:

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

Les changements étaient les suivants:

  • la comparaison nécessaire pour utiliser (l * largeur de lettre) ... pas seulement l
  • si / sinon changé en juste si - de sorte qu'un saut de ligne mettra toujours X à 0
  • et ajoutez toujours la nouvelle largeur de lettre l * à la valeur x

J'espère que cela t'aides.

3voto

cancerbero Points 136

La solution de Mark est lente pour de grandes quantités de texte (firefox 11). Je pense que c'est parce que le texte est rendu plusieurs fois pour obtenir BBOX. la fonction suivante est plus efficace pour de grandes quantités de texte mais peut-être moins exacte (code du projet 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("")});
};
 

0voto

Carlos J. Points 38

Eh bien, je l'ai résolu en le peaufinant un peu

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X