2013-03-15 17 views
40

Dimensioni della scatola note. Lunghezza della stringa di testo sconosciuta. Adatta testo a scatola senza rovinare il suo rapporto aspetto.Modo SVG puro per adattare il testo a una casella

enter image description here

Dopo una serata di googling e leggere le specifiche SVG, sono abbastanza sicuro che questo non è possibile senza javascript. Il più vicino che potevo ottenere era usare gli attributi textLength e lengthAdjust text, ma che allunga il testo lungo un solo asse.

<svg width="436" height="180" 
    style="border:solid 6px" 
    xmlns="http://www.w3.org/2000/svg"> 
    <text y="50%" textLength="436" lengthAdjust="spacingAndGlyphs">UGLY TEXT</text> 
</svg> 

enter image description here

Sono consapevole SVG Scaling Text to fit container e fitting text into the box

+1

Ho finito per fare un ciclo in javascript che aumenta la dimensione del font fino a quando getBBox mostra che non sarebbe più adatto. Brutto, sperando ancora che ci sarebbe un altro modo. – Bemmu

+0

Ho anche cercato di far funzionare questa stessa funzionalità. Il miglior metodo che ho trovato era lo stesso che hai fatto. Passa attraverso JS e cambia carattere finché non si adatta. Ma anche nei font ci sono ancora degli spazi bianchi sopra e sotto, quindi non riesci a ottenere il risultato giusto. – Chad

+0

Questo fa schifo, sembra una cosa così basilare, ma la specifica è chiara che si estende solo in una direzione.Dopo aver giocato intorno, sono stato in grado di avvicinarlo modificando solo la scala Y usando la trasformazione, ovvero: 'transform =" scale (0,5) "' - http://jsfiddle.net/G5L8W/ – streetlogics

risposta

30

non ho trovato un modo per farlo direttamente senza Javascript, ma ho trovato un abbastanza facile soluzione di JS, senza per loop e senza modificare la dimensione del font e si adatta bene a tutte le dimensioni, cioè il testo cresce fino al limite del lato più corto.

Fondamentalmente, utilizzo la proprietà transform, calcolando la giusta proporzione tra la dimensione desiderata e quella corrente.

Questo è il codice:

<?xml version="1.0" encoding="UTF-8" ?> 
<svg version="1.2" viewBox="0 0 1000 1000" width="1000" height="1000" xmlns="http://www.w3.org/2000/svg" > 
<text id="t1" y="50" >MY UGLY TEXT</text> 
<script type="application/ecmascript"> 

    var width=500, height=500; 

    var textNode = document.getElementById("t1"); 
    var bb = textNode.getBBox(); 
    var widthTransform = width/bb.width; 
    var heightTransform = height/bb.height; 
    var value = widthTransform < heightTransform ? widthTransform : heightTransform; 
    textNode.setAttribute("transform", "matrix("+value+", 0, 0, "+value+", 0,0)"); 

</script> 
</svg> 

Nell'esempio precedente il testo cresce fino a quando il width == 500, ma se io uso un formato della scatola di width = 500 e height = 30, quindi il testo cresce fino height == 30.

+6

O semplicemente ... textNode.setAttribute ("transform", "scale (" + value + ")"); –

+2

Nota rapida: l'attributo della scala influisce anche sul sistema di coordinate dell'elemento corrente, quindi se si desidera che l'elemento si trovi nella stessa posizione, sarà necessario dividere entrambe le posizioni xey per lo scalare per ottenere la stessa posizione relativa – MDragon00

9

prima di tutto: appena visto che la risposta non affronta appunto il vostro bisogno - potrebbe ancora essere un'opzione, ecco noi go:

stai osservando correttamente che svg non supporta direttamente il word-wrapping. tuttavia, è possibile trarre vantaggio dagli elementi foreignObject che fungono da wrapper per i frammenti xhtml in cui è disponibile il word-wrapping.

uno sguardo a questa demo autonomo (disponibile online):

<?xml version="1.0" encoding="utf-8"?> 
<!-- SO: http://stackoverflow.com/questions/15430189/pure-svg-way-to-fit-text-to-a-box --> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xhtml="http://www.w3.org/1999/xhtml" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    version="1.1" 
    width="20cm" height="20cm" 
    viewBox="0 0 500 500" 
    preserveAspectRatio="xMinYMin" 
    style="background-color:white; border: solid 1px black;" 
> 
    <title>simulated wrapping in svg</title> 
    <desc>A foreignObject container</desc> 

    <!-- Text-Elemente --> 
    <foreignObject 
     x="100" y="100" width="200" height="150" 
     transform="translate(0,0)" 
    > 
     <xhtml:div style="display: table; height: 150px; overflow: hidden;"> 
     <xhtml:div style="display: table-cell; vertical-align: middle;"> 
      <xhtml:div style="color:black; text-align:center;">Demo test that is supposed to be word-wrapped somewhere along the line to show that it is indeed possible to simulate ordinary text containers in svg.</xhtml:div> 
     </xhtml:div> 
     </xhtml:div> 
    </foreignObject> 

    <rect x="100" y="100" width="200" height="150" fill="transparent" stroke="red" stroke-width="3"/> 
</svg> 
+0

Grazie, ma non era interessato al word wrapping. – Bemmu

+0

Mi serviva solo questo :) –

0

Non penso sia la soluzione per ciò che si vuole fare ma è possibile utilizzare textlenght con la percentuale ="100%" per la larghezza completa.

<svg width="436" height="180" 
    style="border:solid 6px" 
    xmlns="http://www.w3.org/2000/svg"> 
    <text x="0%" y="50%" textLength="100%">blabla</text> 
</svg> 

è anche possibile aggiungere textanchor="middle" e cambiare la posizione x per centrare perfettamente il testo

questo non cambierà il fontsize e si avrà strano spazio tra lettere ...

JSFIDDLE DEMO

Problemi correlati