Pertanyaan Bagaimana menempatkan dan memusatkan teks dalam persegi panjang SVG


Saya memiliki persegi panjang berikut ...

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

Saya ingin memusatkan kata "Fiksi" di dalamnya. Untuk persegi panjang lainnya, apakah bungkus svg kata tetap berada di dalamnya? Saya tidak dapat menemukan apa pun secara khusus tentang memasukkan teks dalam bentuk yang berpusat baik secara horizontal dan vertikal dan bungkus kata. Juga, teks tidak dapat meninggalkan persegi panjang.

Melihat ke http://www.w3.org/TR/SVG/text.html#TextElement contoh tidak membantu karena elemen teks x dan y berbeda dari x dan y persegi panjang. Sepertinya tidak ada lebar dan tinggi untuk elemen teks. Saya tidak yakin matematika di sini.

(Tabel html saya tidak akan berfungsi.)


76
2018-04-05 02:00


asal


Jawaban:


SVG 1.2 Pembungkus teks kecil yang ditambahkan, tetapi sebagian besar implementasi SVG yang akan Anda temukan di browser (dengan pengecualian Opera) belum menerapkan fitur ini. Biasanya terserah Anda, pengembang, untuk memposisikan teks secara manual.

Spesifikasi SVG 1.1 memberikan gambaran umum yang bagus tentang batasan ini, dan solusi yang mungkin untuk mengatasinya:

Setiap elemen ‘teks’ menyebabkan satu   string teks yang akan diberikan. SVG   tidak melakukan pemutus baris otomatis atau   pembungkusan kata. Untuk mencapai efeknya   beberapa baris teks, gunakan salah satu   metode berikut:

  • Penulis atau paket authoring membutuhkan   untuk pra-menghitung jeda baris dan gunakan   banyak elemen 'teks' (satu untuk masing-masing   baris teks).
  • Penulis atau penulis   paket perlu pra-menghitung garis   pecah dan gunakan elemen 'teks' tunggal   dengan satu atau lebih anak ‘tspan’   elemen dengan nilai yang sesuai untuk   atribut ‘x’, ‘y’, ‘dx’, dan ‘dy’ untuk   menetapkan posisi awal baru bagi mereka   karakter yang memulai baris baru.   (Pendekatan ini memungkinkan teks pengguna   seleksi di beberapa baris   teks - lihat Pilihan teks dan   operasi clipboard.)
  • Ekspresikan   teks yang akan diberikan dalam XML lain   namespace seperti XHTML [XHTML]   tertanam sebaris dalam   Elemen 'foreignObject'. (Catatan:   semantik yang tepat dari pendekatan ini   tidak sepenuhnya ditentukan saat ini.)

http://www.w3.org/TR/SVG11/text.html#Introduction

Sebagai pembungkus teks primitif, dapat disimulasikan dengan menggunakan atribut dy dan elemen tspan, dan seperti yang disebutkan dalam spesifikasi, beberapa alat dapat mengotomatisasi ini. Misalnya, di Inkscape, pilih bentuk yang Anda inginkan, dan teks yang Anda inginkan, dan gunakan Text -> Flow into Frame. Ini akan memungkinkan Anda untuk menulis teks Anda, dengan pembungkus, yang akan membungkus berdasarkan batas-batas bentuk. Selain itu, pastikan Anda mengikuti petunjuk ini untuk memberi tahu Inkscape untuk menjaga kompatibilitas dengan SVG 1.1: http://wiki.inkscape.org/wiki/index.php/FAQ#What_about_flowed_text.3F

Selain itu, ada beberapa pustaka JavaScript yang dapat digunakan untuk mengotomatiskan pembungkusan teks secara dinamis: http://www.carto.net/papers/svg/textFlow/

Sangat menarik untuk mencatat solusi CSVG untuk membungkus bentuk ke elemen teks (mis. Lihat "tombol" contoh mereka), meskipun penting untuk menyebutkan bahwa penerapannya adalah tidak dapat digunakan di browser: http://www.csse.monash.edu.au/~clm/csvg/about.html

Saya menyebutkan ini karena saya telah mengembangkan pustaka yang terinspirasi CSVG yang memungkinkan Anda melakukan hal serupa dan bekerja di peramban web, meskipun saya belum merilisnya.


33
2018-04-05 04:10



Solusi mudah untuk memusatkan teks secara horizontal dan vertikal di SVG:

  1. Atur posisi teks ke pusat mutlak dari elemen di mana Anda ingin memusatkannya:

    • Jika itu orang tua, Anda bisa melakukannya x="50%" y ="50%".
    • Jika itu elemen lain, x akan menjadi x dari elemen itu + setengah lebarnya (dan serupa untuk y tetapi dengan tinggi).
  2. Menggunakan text-anchor properti untuk memusatkan teks secara horizontal dengan nilai middle:

    tengah

    Karakter yang ditampilkan disejajarkan sedemikian rupa sehingga bagian geometrik dari teks yang dihasilkan ditampilkan pada posisi teks awal saat ini.

  3. Menggunakan alignment-baseline properti untuk memusatkan teks secara vertikal dengan nilai middle (atau tergantung pada bagaimana Anda ingin terlihat seperti itu, Anda mungkin ingin melakukannya central)

Berikut ini adalah demo sederhana:

<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



Jawaban sebelumnya memberi hasil buruk ketika menggunakan sudut membulat atau stroke-width itu> 1. Sebagai contoh, Anda akan mengharapkan kode berikut untuk menghasilkan persegi panjang bulat, tetapi sudut-sudutnya dipotong oleh induknya svg komponen:

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

Sebaliknya, saya sarankan untuk membungkus text di sebuah svg dan kemudian menumpuknya svg dan rect bersama di dalam g elemen, seperti pada contoh berikut:

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

Ini memperbaiki masalah kliping yang terjadi dalam jawaban di atas. Saya juga menerjemahkan grup rect / text menggunakan transform="translate(x,y)" atribut untuk menunjukkan bahwa ini memberikan pendekatan yang lebih intuitif untuk memposisikan rekti / teks di layar.


7
2017-07-01 04:16



Anda dapat langsung menggunakan text-anchor = "middle" milik. Saya menyarankan untuk membuat elemen svg wrapper di atas persegi panjang dan teks Anda. Dengan begitu Anda dapat menggunakan seluruh elemen menggunakan satu selektor css. Pastikan Anda menempatkan properti 'x' dan 'y' teks sebanyak 50%.

<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



Blog Detail Lengkap: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



Saya memiliki bugger waktu mendapatkan sesuatu yang berpusat menggunakan SVG, jadi saya menggulirkan fungsi kecil saya sendiri. semoga ini akan membantu Anda. Perhatikan bahwa ini hanya berfungsi untuk elemen SVG.

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



Salah satu cara untuk memasukkan teks di dalam persegi panjang adalah memasukkan objek asing, yang merupakan DIV, di dalam objek rektal.

Dengan cara ini, teks akan memenuhi batasan DIV.

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