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 contenedor <rect> de la misma manera como texto HTML llena <div> elementos. Es allí una manera de hacerlo? No quiero líneas de posición por otra mediante el uso de <tspan>s.

InformationsquelleAutor tillda | 2011-02-14

8 Kommentare

  1. 78

    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>
    • Que es el camino equivocado para el uso del interruptor, es necesario utilizar uno de los featurestrings definido en la especificación svg. La reserva no será utilizada en su ejemplo. Consulte w3.org/TR/SVG11/feature.html y w3.org/TR/SVG11/struct.html#SwitchElement.
    • También <foreignObject/> no es compatible con IE
    • Pero ser conscientes de que no todos los motores de render foreignObjects. En particular, batik, no.
    • lol. no lo hará.
    • No funciona en Chrome.
  2. 63

    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.

    Nota: mientras que el ejemplo anterior es válido SVG 1.1 contenido, en formato SVG 2 el ‘requiredFeatures’ atributo ha sido eliminado, lo que significa que el ‘interruptor’ elemento se intenta dar el primer ‘g’ elemento, independientemente de tener soporte para SVG 1.2 ‘textArea’ elementos. Ver SVG2 elemento de conmutación spec.

    • Estuve probando este código en FF, el navegador no me mostró el elemento textArea o la foreignObject niño. Luego, después de la lectura de la especificación, se encontró que requiredFeatures atributo se comporta de tal manera que, cuando su lista de evalutes a false, el elemento que tiene la requiredFeatures atributo y sus hijos no son procesados. Así que no habrá necesidad alguna de que el elemento de conmutación. Después de que me quita el elemento de conmutación, el foreignObject niños eran visibles (porque mi navegador(FF, 8.01) apoyo svg1.1 ). Así que yo creo que no hay necesidad de cambiar elemento aquí. Por favor, hágamelo saber.
    • Actualiza ahora a usar un <p> elemento. La especificación svg no decirle a los espectadores a mirar ‘requiredFeatures’ en los elementos desconocidos, así que uno tiene que usar un conocido svg elemento para que funcione como se pretende.
    • Gracias! Necesitaba usar xhtml:div en lugar de div, pero que podría ser debido a d3.js. No pude encontrar ninguna referencia útil acerca de TextFlow, ¿no es (todavía) existe o fue sólo en algún proyecto?
    • Cabe señalar que textarea parece no ser compatible en adelante bugzilla.mozilla.org/show_bug.cgi?id=413360
    • Ejemplo no funciona en Chrome. No lo he probado en otros navegadores.
    • No funciona en Chrome para mí tampoco. Utilizando sólo svg:texto en el interruptor funciona bien, pero parece que Chrome piensa que es compatible con TextFlow pero no soporta svg:textArea.
    • Sí, por desgracia el requiredFeatures atributo ha sido roto por los navegadores actuales (es prácticamente ignorado). Es posible que el uso de sólo foreignObject sin el modificador es la única opción real hoy en día, aunque yo no he probado recientemente para ver qué tan bien foreignObject es compatible en todos los navegadores.

  3. 13

    La 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>
    • Sólo en un caso donde wraping mediados de la palabra (y no por medio de separar con guiones) es aceptable. No puedo pensar en muchos casos más allá de los proyectos de arte donde eso está bien. http://jsfiddle.net/nilloc/vL3zj/
    • No todo el mundo utiliza el inglés, este método es totalmente bien para el Chino, el Japonés o el coreano.
    • Embalaje para el carácter (logográfico) idiomas parece totalmente diferentes casos de uso de la división de palabras. Lo que es importante en todos los romántica/latina/cirílico/árabe (fonográfica) idiomas, que era mi punto.
  4. 9

    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
    
    };
    • Mientras que este vínculo puede responder a la pregunta, es mejor incluir a las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Enlace-sólo respuestas puede ser válido si la página enlazada cambios.
    • Seguro. Thx @FDL.
    • gracias. que funciona perfectamente en Chrome. Pero no funciona en firefox. Se dice que en la versión de prueba enlace. Valor inesperado NaN análisis dy atributo. svgtext_clean2.htm:117 tratando de encontrar un trabajo a su alrededor.
    • Posteriormente consiguió trabajo en Firefox. Aquí vamos:
    • (Presiona ENTRAR demasiado pronto ahora.) Posteriormente consiguió trabajo en Firefox y IE. Si necesitas algo de ayuda, tener una mirada en democra.me/wrap_8_may_2014.htm. Hay un comentario acerca de Firefox en el código.
    • Como se puede ver, he ampliado el código de mucho para reducir el tamaño del cuadro delimitador hacia arriba o hacia abajo o truncar con puntos suspensivos en el lugar correcto.
    • Me gustaría modificar una línea en el MSC del código: boxwidth = parseInt(boxObject.getAttribute('width')), acaba de aceptar la anchura en píxeles, mientras que boxwidth = parseInt(boxObject.getBBox().width), aceptaría cualquier tipo de unidad de medida

  5. 5

    El siguiente código está funcionando bien. Ejecutar el fragmento de código lo que hace.

    Tal vez puede ser limpiado o hacer funcionar automáticamente con todas las etiquetas de texto en formato SVG.

    JS:

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

    CSS:

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

    HTML:

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

    • Auto de la línea de ajuste en SVG texto 🙂 Mi código javascript que crea líneas cuando el texto es largo. Será bueno si me funciona en todas las etiquetas de texto dentro de SVG. automática sin necesidad de cambiar el id=»» en javascript. A las malas SVG doenst tienen múltiples líneas por sí mismo.
  6. 4

    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:

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

    Espero que esto ayude !

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea