texto xml text svg linewrap

xml - Ajuste de línea automático en texto SVG



svg text center (8)

Aquí hay 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>

Teniendo en cuenta que aunque se puede informar que foreignObject es compatible con esa cadena de características, no hay garantía de que se pueda mostrar HTML porque no lo requiere la especificación de SVG 1.1. No hay una cadena de rasgos para el soporte de html-in-foreignobject en este momento. Sin embargo, todavía es compatible con muchos navegadores, por lo que es probable que se vuelva necesario en el futuro, tal vez con una cadena de características correspondiente.

Tenga en cuenta que el elemento ''textArea'' en SVG Tiny 1.2 admite todas las características svg estándar, por ejemplo, llenado avanzado, etc., y que puede especificar el ancho o alto como automático, lo que significa que el texto puede fluir libremente en esa dirección. ForeignObject actúa como una ventana gráfica de recorte.

Nota: mientras que el ejemplo anterior es un contenido SVG 1.1 válido, en SVG 2 se ha eliminado el atributo ''requiredFeatures'', lo que significa que el elemento ''switch'' intentará representar el primer elemento ''g'' independientemente de que sea compatible con el campo de texto SVG 1.2 '' ''elementos. Ver especificación del elemento de interruptor SVG2 .

Me gustaría mostrar un <text> en SVG, lo que se ajustaría automáticamente al contenedor <rect> del mismo modo que el texto HTML llena los elementos <div> . ¿Hay una manera de hacerlo? No quiero colocar líneas por separado usando <tspan> s.


Basándome en el código de @Mike Gledhill, lo llevé un paso más allá y agregué más parámetros. Si tiene un SVG RECT y quiere que el texto se ajuste a su contenido, 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 };


El ajuste de texto no es parte de SVG1.1, la especificación implementada actualmente. Debería usar HTML a través del elemento <foreignObject/> .

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


El siguiente código funciona bien. Ejecute el fragmento de código de lo que hace.

Tal vez se pueda limpiar o hacer que funcione automáticamente con todas las etiquetas de texto en SVG.

function svg_textMultiline() { var x = 0; var y = 20; var width = 360; var lineHeight = 10; /* get the text */ var element = document.getElementById(''test''); var text = element.innerHTML; /* split the words into array */ var words = text.split('' ''); var line = ''''; /* Make a tspan for testing */ element.innerHTML = ''<tspan id="PROCESSING">busy</tspan >''; for (var n = 0; n < words.length; n++) { var testLine = line + words[n] + '' ''; var testElem = document.getElementById(''PROCESSING''); /* Add line in testElement */ testElem.innerHTML = testLine; /* Messure textElement */ var metrics = testElem.getBoundingClientRect(); testWidth = metrics.width; if (testWidth > width && n > 0) { element.innerHTML += ''<tspan x="0" dy="'' + y + ''">'' + line + ''</tspan>''; line = words[n] + '' ''; } else { line = testLine; } } element.innerHTML += ''<tspan x="0" dy="'' + y + ''">'' + line + ''</tspan>''; document.getElementById("PROCESSING").remove(); } svg_textMultiline();

body { font-family: arial; font-size: 20px; } svg { background: #dfdfdf; border:1px solid #aaa; } svg text { fill: blue; stroke: red; stroke-width: 0.3; stroke-linejoin: round; stroke-linecap: round; }

<svg height="300" width="500" xmlns="http://www.w3.org/2000/svg" version="1.1"> <text id="test" y="0">GIETEN - Het college van Aa en Hunze is in de fout gegaan met het weigeren van een zorgproject in het failliete hotel Braams in Gieten. Dat stelt de PvdA-fractie in een brief aan het college. De partij wil opheldering over de kwestie en heeft schriftelijke vragen ingediend. Verkeerde route De PvdA vindt dat de gemeenteraad eerst gepolst had moeten worden, voordat het college het plan afwees. "Volgens ons is de verkeerde route gekozen", zegt PvdA-raadslid Henk Santes.</text> </svg>


El textPath puede ser bueno para algunos casos.

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



He publicado el siguiente tutorial para agregar un ajuste de palabras falso a un elemento de "texto" de SVG aquí:

SVG Word Wrap - ¿Mostrar stopper?

Solo necesita agregar una función de JavaScript simple, que divide la cadena en elementos "tspan" más cortos. Aquí hay un ejemplo de cómo se ve:

Espero que esto ayude !