126 votes

Auto habillage de ligne dans le texte SVG

Je voudrais afficher un <text> en SVG, ce qui serait automatique de la ligne pour le conteneur <rect> de la même manière que le texte HTML remplit <div> - éléments. Est-il un moyen de le faire? Je ne veux pas les lignes de position sparately en utilisant <tspan>s.

105voto

Tangui Points 811

L'habillage de texte n'est pas une partie de SVG1.1, qui est actuellement mis en œuvre spec. Vous devriez plutôt utiliser le HTML via l' <foreignObject/> élément.

<svg ...>

<switch>
<foreignObject x="20" y="90" width="150" height="200">
<p xmlns="http://www.w3.org/1999/xhtml">Text goes here</p>
</foreignObject>

<text x="20" y="20">Your SVG viewer cannot display html.</text>
</switch>

</svg>

71voto

Erik Dahlström Points 21519

Voici une autre:

<svg ...>
  <switch>
    <g requiredFeatures="http://www.w3.org/Graphics/SVG/feature/1.2/#TextFlow">
      <textArea width="200" height="auto">
       Text goes here
      </textArea>
    </g>
    <foreignObject width="200" height="200" 
     requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
      <p xmlns="http://www.w3.org/1999/xhtml">Text goes here</p>
    </foreignObject>
    <text x="20" y="20">No automatic linewrapping.</text>
  </switch>
</svg>

Notant que, même si foreignObject peut être signalé comme étant pris en charge avec qui featurestring, il n'y a aucune garantie que le HTML peut être affichée car ce n'est pas requise par le SVG 1.1. Il n'y a pas de featurestring pour html-en-foreignobject soutien à le moment. Cependant, il est toujours pris en charge dans la plupart des navigateurs, de sorte qu'il est probable que de devenir nécessaire dans l'avenir, peut-être avec un correspondant featurestring.

Notez que le 'textArea' élément SVG Tiny 1.2 prend en charge toutes les fonctionnalités svg, e.g avancé de remplissage, etc, et que vous pouvez spécifier la largeur ou la hauteur d'auto, ce qui signifie que le texte peut circuler librement dans cette direction. ForeignObject actes que l'écrêtage de la fenêtre d'affichage.

18voto

user2856765 Points 36

Le textPath peut être bon pour certains cas.

<svg width="200" height="200"
    xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
  <!-- define lines for text lies on -->
  <path id="path1" d="M10,30 H190 M10,60 H190 M10,90 H190 M10,120 H190"></path>
 </defs>
 <use xlink:href="#path1" x="0" y="35" stroke="blue" stroke-width="1" />
 <text transform="translate(0,35)" fill="red" font-size="20">
  <textPath xlink:href="#path1">This is a long long long text ......</textPath>
 </text>
</svg>

12voto

MSC Points 62

Bâtiment sur @Mike Gledhill du code, j'ai pris un peu plus loin et a ajouté plus de paramètres. Si vous avez un SVG RECT et voulez que le texte s'enrouler à l'intérieur, ce qui peut être utile:

function wraptorect(textnode, boxObject, padding, linePadding) {

    var x_pos = parseInt(boxObject.getAttribute('x')),
    y_pos = parseInt(boxObject.getAttribute('y')),
    boxwidth = parseInt(boxObject.getAttribute('width')),
    fz = parseInt(window.getComputedStyle(textnode)['font-size']);  // We use this to calculate dy for each TSPAN.

    var line_height = fz + linePadding;

// Clone the original text node to store and display the final wrapping text.

var wrapping = textnode.cloneNode(false);       // False means any TSPANs in the textnode will be discarded
wrapping.setAttributeNS(null, 'x', x_pos + padding);
wrapping.setAttributeNS(null, 'y', y_pos + padding);

// Make a copy of this node and hide it to progressively draw, measure and calculate line breaks.

var testing = wrapping.cloneNode(false);
testing.setAttributeNS(null, 'visibility', 'hidden');  // Comment this out to debug

var testingTSPAN = document.createElementNS(null, 'tspan');
var testingTEXTNODE = document.createTextNode(textnode.textContent);
testingTSPAN.appendChild(testingTEXTNODE);

testing.appendChild(testingTSPAN);
    var tester = document.getElementsByTagName('svg')[0].appendChild(testing);

var words = textnode.textContent.split(" ");
var line = line2 = "";
var linecounter = 0;
    var testwidth;

for (var n = 0; n < words.length; n++) {

      line2 = line + words[n] + " ";
      testing.textContent = line2;
      testwidth = testing.getBBox().width;

    if ((testwidth + 2*padding) > boxwidth)
    {

        testingTSPAN = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
        testingTSPAN.setAttributeNS(null, 'x', x_pos + padding);
        testingTSPAN.setAttributeNS(null, 'dy', line_height);

        testingTEXTNODE = document.createTextNode(line);
        testingTSPAN.appendChild(testingTEXTNODE);
        wrapping.appendChild(testingTSPAN);

        line = words[n] + " ";
        linecounter++;
    }
    else {
        line = line2;
    }
}

var testingTSPAN = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
testingTSPAN.setAttributeNS(null, 'x', x_pos + padding);
testingTSPAN.setAttributeNS(null, 'dy', line_height);

var testingTEXTNODE = document.createTextNode(line);
testingTSPAN.appendChild(testingTEXTNODE);

wrapping.appendChild(testingTSPAN);

    testing.parentNode.removeChild(testing);
    textnode.parentNode.replaceChild(wrapping,textnode);

    return linecounter;
}

document.getElementById('original').onmouseover = function () {

    var container = document.getElementById('destination');
    var numberoflines = wraptorect(this,container,20,1);
    console.log(numberoflines);  // In case you need it
};

(Exemple vivant au http://democra.me/svgtext_clean2.htm)

9voto

jbeard4 Points 5680

Cette fonctionnalité peut également être ajoutés à l'aide de JavaScript. Carto.net a un exemple:

http://www.carto.net/svg/textFlow/

Autre chose qui peut être utile pour vous sont les zones de texte éditable:

http://www.carto.net/svg/gui/textbox/

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