78 votos

Auto de la línea de ajuste de texto en formato SVG

Me gustaría mostrar un <text> en SVG ¿qué sería de auto-ajuste de línea para el recipiente <rect> de la misma manera como texto HTML rellenos <div> elementos. Es allí una manera de hacerlo? No quiero líneas de posición por otra mediante el uso de <tspan>s.

68voto

Tangui Puntos 811

Ajuste de texto no es parte de SVG1.1, el que actualmente se implementan las especificaciones. Deberías usar HTML a través de la <foreignObject/> elemento.

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

58voto

Erik Dahlström Puntos 21519

He aquí una alternativa:

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

Notar que aun cuando foreignObject pueden ser reportados como ser compatible con que featurestring, no hay ninguna garantía de que el HTML se puede mostrar debido a que no es requerida por el SVG 1.1 de la especificación. No hay featurestring para html-en-foreignobject apoyo en el momento. Sin embargo, todavía está soportado en la mayoría de los navegadores, por lo que es probable llegar a ser necesario en el futuro, tal vez con un correspondiente featurestring.

Tenga en cuenta que el 'textArea' elemento en SVG Tiny 1.2 es compatible con todos los estándar svg características, e.g avanzado de llenado, etc, y que se puede especificar de la anchura o la altura del auto, lo que significa que el texto puede fluir libremente en esa dirección. ForeignObject actúa como recorte de la ventanilla.

8voto

jbeard4 Puntos 5680

Esta funcionalidad también se puede añadir el uso de JavaScript. Carto.net tiene un ejemplo:

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

Otra cosa que también podría ser útil para los que son de texto editable áreas:

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

7voto

MSC Puntos 62

Edificio en @Mike Gledhill del código, me he tomado un paso más allá y agregó más parámetros. Si usted tiene un SVG RECT y desea que el texto se ajuste dentro de ella, esto puede ser útil:

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

(Ejemplo en vivo en http://democra.me/svgtext_clean2.htm)

4voto

Mike Gledhill Puntos 2105

He publicado el siguiente tutorial para añadir algunos falsos ajuste a un SVG "texto" elemento", " aquí:

SVG Word Wrap - Mostrar el tapón?

Sólo se necesita añadir una simple función de JavaScript, que divide la cadena en corto "tspan" elementos. He aquí un ejemplo de lo que parece:

Example SVG

Espero que esto ayude !

Mike

http://www.MikesKnowledgeBase.com

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X