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

Je crée une boîte de texte SVG à l'aide de la bibliothèque Raphael et je la complète avec une chaîne dynamique extraite d'un document XML.

Parfois, cette chaîne est plus longue que la toile sur laquelle je place la zone de texte, donc je dois limiter la largeur de la case qui forcera elle-même les sauts de ligne (je ne peux pas trouver la preuve que cela est possible) OU assurez-vous Qu'une insertion de ligne '\ n' est insérée après une certaine quantité de caractères.

Donc (1) est-ce la meilleure option? Et (2) comment ferais-je cela?

  • L'attr () dans jQuery force-t-il les minuscules?
  • Quelle est la meilleure façon de sérialiser SVG du client DOM?
  • Highcharts + Plotband tooltip hover + style par défaut
  • Comment puis-je implémenter Offset Path Effect dans SVG sans utiliser de Javascript ou de dilater / éroder des filtres?
  • Tableau de barres groupé D3.js
  • Obtenez la boîte de contournement de l'élément pour sa transformation
  • JQuery Selector + SVG Incompatible?
  • Obtenir la dimension d'un chemin dans SVG
  • 5 Solutions collect form web for “Comment déterminer la largeur de la zone de texte SVG ou forcer les sauts de ligne après les caractères 'x'?”

    Il n'y a pas d'attribut pour l'envoi de texte, mais il est possible d'utiliser un simple truc. Ajoutez un mot à la fois à un objet texte et, lorsqu'il est trop large, ajoutez un flux de ligne. Vous pouvez utiliser la fonction getBBox () pour déterminer la largeur. Fondamentalement, vous imitez une machine à écrire ancienne. Voici un exemple de code qui fera cela pour vous. Vous pourriez 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)); 

    Merci d'avoir répondu. Cependant, j'ai constaté 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 ont été:

    • La comparaison devait être utilisée (l * maille de lettre) … pas seulement l
    • Si if / else a changé pour un if – de sorte qu'une rupture de ligne définira toujours X à 0
    • Et ajoute toujours la nouvelle maille l * à la valeur x

    J'espère que cela t'aides.

    La solution de la marque 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 ta 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("")}); }; 

    Eh bien, je l'ai résolu de le peaufiner 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() ); 

    Je sais que c'est un peu tard, mais vous pourriez être intéressé par mon projet Raphael-paragraph qui le fait automatiquement.

    Le paragraphe Raphael vous permet de créer un texte multiligne auto-enveloppé avec des contraintes de largeur et de hauteur maximales, hauteur de ligne et configuration de style de texte. Il peut diviser les mots longs et les tronquer s'ils dépassent les limites verticales. Il est encore assez bêta-ish et nécessite beaucoup d'optimisation, mais il devrait fonctionner pour vos besoins.

    Les exemples d'utilisation et la documentation sont fournis sur la page GitHub.

    JavaScript rend le site Web intelligent, beauté et facile à utiliser.