Frage So platzieren und zentrieren Sie Text in einem SVG-Rechteck


Ich habe das folgende Rechteck ...

<rect x="0px" y="0px" width="60px" height="20px"/>

Ich würde gerne das Wort "Fiction" darin zentrieren. Für andere Rechtecke, wird Svg-Wortumbruch in ihnen bleiben? Ich kann anscheinend nichts speziell über das Einfügen von Text in Formen finden, die sowohl horizontal als auch vertikal zentriert sind, und Wortumbruch. Außerdem kann der Text das Rechteck nicht verlassen.

Mit Blick auf die http://www.w3.org/TR/SVG/text.html#TextElement Beispiel hilft nicht, da die x und y des Textelements sich von den x und y des Rechtecks ​​unterscheiden. Für Textelemente scheint es keine Breite und Höhe zu geben. Ich bin mir hier nicht sicher.

(Meine HTML-Tabelle wird einfach nicht funktionieren.)


76
2018-04-05 02:00


Ursprung


Antworten:


SVG 1.2 Tiny hinzugefügt Textumbruch, aber die meisten Implementierungen von SVG, die Sie im Browser finden (mit Ausnahme von Opera) haben diese Funktion nicht implementiert. Es ist normalerweise Sache des Entwicklers, den Text manuell zu positionieren.

Die SVG 1.1-Spezifikation bietet einen guten Überblick über diese Einschränkung und die möglichen Lösungen, um sie zu überwinden:

Jedes 'text' Element verursacht eine einzelne   Zeichenkette, die gerendert werden soll. SVG   führt keine automatische Zeilenumschaltung oder aus   Zeilenumbruch. Um den Effekt zu erzielen   Verwenden Sie eines von mehreren Textzeilen   die folgenden Methoden:

  • Der Autor oder das Authoring-Paket benötigt   die Zeilenumbrüche vorberechnen und verwenden   mehrere 'Text' Elemente (eins für jeden   Textzeile).
  • Der Autor oder das Authoring   Paket muss die Zeile vorberechnen   bricht und verwendet ein einzelnes "Text" -Element   mit einem oder mehreren "tspan" -Kindern   Elemente mit geeigneten Werten für   Attribute 'x', 'y', 'dx' und 'dy' zu   Legen Sie für diese neue Startpositionen fest   Zeichen, die neue Zeilen beginnen.   (Dieser Ansatz ermöglicht Benutzertext   Auswahl über mehrere Zeilen von   Text - siehe Textauswahl und   Zwischenablage-Operationen.)
  • Drücken Sie die   Text, der in einem anderen XML gerendert werden soll   Namensraum wie XHTML [XHTML]   eingebettet in einem   'Fremdobjekt' Element. (Beachten Sie das   genaue Semantik dieses Ansatzes sind   zu diesem Zeitpunkt nicht vollständig definiert.)

http://www.w3.org/TR/SVG11/text.html#Einführung

Als Grundelement kann Textumbruch simuliert werden, indem das dy-Attribut und die tspan-Elemente verwendet werden, und wie in der Spezifikation erwähnt, können einige Werkzeuge dies automatisieren. Wählen Sie beispielsweise in Inkscape die gewünschte Form und den gewünschten Text aus und verwenden Sie Text -> In Frame einfließen. Auf diese Weise können Sie Ihren Text mit Umbruch schreiben, der basierend auf den Grenzen der Form umbrochen wird. Stellen Sie außerdem sicher, dass Sie diese Anweisungen befolgen, um Inkscape mitzuteilen, dass die Kompatibilität mit SVG 1.1 erhalten bleiben soll: http://wiki.inkscape.org/wiki/index.php/FAQ#What_about_flowed_text.3F

Darüber hinaus gibt es einige JavaScript-Bibliotheken, mit denen der Textumbruch dynamisch automatisiert werden kann: http://www.carto.net/papers/svg/textFlow/

Es ist interessant, die CSVG-Lösung zum Umhüllen einer Form mit einem Textelement zu beachten (siehe zum Beispiel ihr "Knopf" -Beispiel), obwohl es wichtig ist, zu erwähnen, dass ihre Implementierung dies ist nicht verwendbar in einem Browser: http://www.csse.monash.edu.au/~clm/csvg/about.html

Ich erwähne das, weil ich eine CSVG-inspirierte Bibliothek entwickelt habe, mit der Sie ähnliche Dinge tun können und die in Webbrowsern funktioniert, obwohl ich sie noch nicht veröffentlicht habe.


33
2018-04-05 04:10



Eine einfache Lösung, um Text in SVG horizontal und vertikal zu zentrieren:

  1. Setze die Position des Textes auf die absolutes Zentrum des Elements, in dem Sie es zentrieren möchten:

    • Wenn es das Elternteil ist, könntest du es einfach tun x="50%" y ="50%".
    • Wenn es ein anderes Element ist, x wäre das x dieses Elements + halbe Breite (und ähnlich für y aber mit der Höhe).
  2. Benutze die text-anchor Eigenschaft, um den Text horizontal mit dem Wert zu zentrieren middle:

    Mitte

    Die gerenderten Zeichen werden so ausgerichtet, dass sich die geometrische Mitte des resultierenden gerenderten Texts an der ursprünglichen aktuellen Textposition befindet.

  3. Benutze die alignment-baseline Eigenschaft, um den Text vertikal mit dem Wert zu zentrieren middle (oder je nachdem, wie Sie es aussehen möchten, möchten Sie vielleicht tun central)

Hier ist eine einfache Demo:

<svg width="200" height="100">
  <rect x="0" y="0" width="200" height="100" stroke="red" stroke-width="3px" fill="white"/>
  <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">TEXT</text>    
</svg>


103
2017-07-20 16:50



Die vorherigen Antworten ergaben schlechte Ergebnisse bei Verwendung von abgerundeten Ecken oder stroke-width das ist> 1. Beispielsweise würden Sie erwarten, dass der folgende Code ein abgerundetes Rechteck erzeugt, die Ecken jedoch vom übergeordneten Objekt abgeschnitten werden svg Komponente:

<svg width="200" height="100">
  <!--this rect should have rounded corners-->
  <rect x="0" y="0" rx="5" ry="5" width="200" height="100" stroke="red" stroke-width="10px" fill="white"/>
  <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">CLIPPED BORDER</text>    
</svg>

Stattdessen empfehle ich, den text in einem svg und dann das neue verschachteln svg und das rect zusammen in einem g Element, wie im folgenden Beispiel:

<!--the outer svg here-->
<svg width="400px" height="300px">

  <!--the rect/text group-->
  <g transform="translate(50,50)">
    <rect rx="5" ry="5" width="200" height="100" stroke="green" fill="none" stroke-width="10"/>
    <svg width="200px" height="100px">
      <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">CORRECT BORDER</text>      
    </svg>
  </g>

  <!--rest of the image's code-->
</svg>

Dies behebt das Clipping-Problem, das in den obigen Antworten auftritt. Ich übersetzte auch die Rekt / Textgruppe mit der transform="translate(x,y)" Attribut, um zu demonstrieren, dass dies einen intuitiveren Ansatz zur Positionierung des rect / text auf dem Bildschirm bietet.


7
2017-07-01 04:16



Sie können direkt verwenden text-anchor = "middle" Eigentum. Ich rate, ein Wrapper-Svg-Element über Ihr Rechteck und Text zu erstellen. Auf diese Weise können Sie das gesamte Element mit einem CSS-Selektor verwenden. Stellen Sie sicher, dass Sie 'x' und 'y' Eigenschaft des Textes als 50% setzen.

<svg class="svg-rect" width="50" height="40">
        <rect x="0" y="0" rx="3" ry="3" width="50" height="40" fill="#e7e7e7"></rect>
        <text x="50%" y="50%" text-anchor="middle" stroke="black" stroke-width="1px" dy=".3em">N/A</text>
    </svg>

4
2017-08-11 21:10



Voller Detail-Blog:http://blog.techhysahil.com/svg/how-to-center-text-in-svg-shapes/

<svg width="600" height="600">
  <!--   Circle -->
  <g transform="translate(50,40)">
    <circle cx="0" cy="0" r="35" stroke="#aaa" stroke-width="2" fill="#fff"></circle>
    <text x="0" y="0" alignment-baseline="middle" font-size="12" stroke-width="0" stroke="#000" text-anchor="middle">HueLink</text>
  </g>
  
  <!--   In Rectangle text position needs to be given half of width and height of rectangle respectively -->
  <!--   Rectangle -->
  <g transform="translate(150,20)">
    <rect width="150" height="40" stroke="#aaa" stroke-width="2" fill="#fff"></rect>
    <text x="75" y="20" alignment-baseline="middle" font-size="12" stroke-width="0" stroke="#000" text-anchor="middle">HueLink</text>
  </g>
  
  <!--   Rectangle -->
  <g transform="translate(120,140)">
    <ellipse cx="0" cy="0" rx="100" ry="50" stroke="#aaa" stroke-width="2" fill="#fff"></ellipse>
    <text x="0" y="0" alignment-baseline="middle" font-size="12" stroke-width="0" stroke="#000" text-anchor="middle">HueLink</text>
  </g>
  
  
</svg>


3
2017-11-15 23:50



Ich hatte eine Zeit lang nichts mit SVG zentriert, also rollte ich meine eigene kleine Funktion. hoffentlich sollte es dir helfen. Beachten Sie, dass dies nur für SVG-Elemente funktioniert.

function centerinparent(element) { //only works for SVG elements
    var bbox = element.getBBox();
    var parentwidth = element.parentNode.width.baseVal.value;
    var parentheight = element.parentNode.height.baseVal.value;
    var newwidth = ((parentwidth / 2) - (bbox.width / 2)) - 2; //i start everything off by 2 to account for line thickness
    var newheight = ((parentheight / 2) - (bbox.height / 2)) - 2;
    //need to adjust for line thickness??

    if (element.classList.contains("textclass")) { //text is origined from bottom left, whereas everything else origin is top left
        newheight += bbox.height; //move it down by its height
    }

    element.setAttributeNS(null, "transform", "translate(" + newwidth + "," + newheight + ")");
    // console.log("centering BOXES:  between width:"+element.parentNode.width.baseVal.value + "   height:"+parentheight);
    // console.log(bbox);
}

1
2017-11-02 04:02



Eine Möglichkeit, Text in ein Rechteck einzufügen, besteht darin, ein fremdes Objekt, das ein DIV ist, in das rect-Objekt einzufügen.

Auf diese Weise wird der Text die Grenzen des DIV betreffen.

var g = d3.select("svg");
					
g.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width","100%")
.attr("height","100%")
.attr("fill","#000");


var fo = g.append("foreignObject")
 .attr("width","100%");

fo.append("xhtml:div")
  .attr("style","width:80%;color:#FFF;margin-right: auto;margin-left: auto;margin-top:40px")
  .text("Mussum Ipsum, cacilds vidis litro abertis Mussum Ipsum, cacilds vidis litro abertis Mussum Ipsum, cacilds vidis litro abertis");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.js"></script>
<svg width="200" height="200"></svg>


1
2018-06-20 14:52