2013-03-15 4 views
40

Box Größe bekannt. Textstringlänge unbekannt. Passen Sie den Text an die Box an, ohne das Seitenverhältnis zu beeinträchtigen.Pure SVG Weg, Text in eine Box zu passen

enter image description here

Nach einem Abend googeln und die SVG-Spezifikation zu lesen, ich bin ziemlich sicher, dass dies ohne Javascript nicht möglich ist. Am ehesten konnte ich TextLength und lengthAdjust Textattribute verwenden, aber das streckt den Text nur entlang einer Achse.

<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

Ich bin mir bewusst, SVG Scaling Text to fit container und fitting text into the box

+1

Ich habe eine Schleife in Javascript gemacht, die die Schriftgröße erhöht, bis getBBox zeigt, dass es nicht mehr passt. Hässlich, so hoffend, dass es noch einen anderen Weg geben würde. – Bemmu

+0

Ich habe auch versucht, die gleiche Funktionalität zu funktionieren. Die beste Methode, die ich gefunden habe, war die gleiche, die du gemacht hast. Durchstreichen Sie JS und ändern Sie die Schriftart, bis sie passt. Aber selbst in Schriften gibt es immer noch ein paar Leerzeichen oben und unten, so dass Sie es scheinbar nicht richtig finden. – Chad

+0

Das ist zum Kotzen, es scheint so eine einfache Sache, aber die Spezifikation ist klar, dass es nur in eine Richtung streckt.Nachdem ich herumgespielt hatte, konnte ich es näher bringen, indem ich nur die Y-Skala mit Hilfe der Transformation änderte, alias: 'transform =" scale (0,5) "' - http://jsfiddle.net/G5L8W/ – streetlogics

Antwort

30

ich es nicht einen Weg finden, um direkt ohne Javascript, aber ich fand eine JS ganz einfache Lösung, ohne für Schleifen und ohne die Schriftgröße zu ändern und passt gut in allen Dimensionen, das heißt, der Text wächst bis zur Grenze der kürzesten Seite.

Grundsätzlich verwende ich die transform Eigenschaft, Berechnung der richtigen Verhältnis zwischen der gewünschten Größe und der aktuellen.

Dies ist der Code:

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

Im vorherigen Beispiel der Text bis zum width == 500 wächst, aber wenn ich eine Box Größe width = 500 und height = 30 verwenden, dann wächst der Text bis height == 30.

+6

Oder einfach ... textNode.setAttribute ("transform", "scale (" + value + ")"); –

+2

Kurzer Hinweis: Das Skalierungsattribut wirkt sich auch auf das Koordinatensystem des aktuellen Elements aus. Wenn Sie also das Element an der gleichen Position haben möchten, müssen Sie die X- und Y-Positionen durch den Skalar teilen, um die gleiche relative Position zu erhalten – MDragon00

9

vor allem: gerade gesehen, dass die Antwort genau nicht Ihren Bedarf adressiert - es könnte immer noch eine Option sein, wir so hier go:

Sie beobachten zu Recht, dass svg Word-Wrapping nicht direkt unterstützt. Sie können jedoch möglicherweise von foreignObject Elementen profitieren, die als Wrapper für xhtml-Fragmente dienen, für die das Umbruchwort verfügbar ist.

haben einen Blick auf diese Selbstversorger-Demo (erhältlich 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

Danke, aber war nicht in Wortverpackung interessiert. – Bemmu

+0

Ich brauchte nur das :) –

0

Ich denke nicht, es ist die Lösung für das, was Sie tun möchten, aber Sie können textlenght mit Prozent ="100%" für die volle Breite verwenden.

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

Sie auch textanchor="middle" und ändern Sie die x Position hinzufügen können perfekt Ihren Text

dies die Schriftgröße verändern wird nicht zum Zentrum und Sie werden seltsame Raum letterSpacing haben ...

JSFIDDLE DEMO