Jawaban:
Pembungkusan teks bukan bagian dari SVG1.1, spesifikasi yang saat ini diterapkan. Anda sebaiknya menggunakan HTML melalui <foreignObject/>
elemen.
<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>
Berikut alternatifnya:
<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>
Memperhatikan bahwa meskipun foreignObject mungkin dilaporkan didukung dengan featureestring itu, tidak ada jaminan bahwa HTML dapat ditampilkan karena itu tidak diwajibkan oleh spesifikasi SVG 1.1. Saat ini tidak ada fitur uji fitur untuk html-in-foreignobject support. Namun, fitur ini masih didukung di banyak browser, jadi fitur ini kemungkinan akan dibutuhkan di masa mendatang, mungkin dengan tanda fitur yang sesuai.
Perhatikan bahwa elemen 'textArea' di SVG Tiny 1.2 mendukung semua fitur svg standar, misalnya pengisian lanjutan dll, dan Anda dapat menentukan lebar atau tinggi sebagai otomatis, yang berarti teks dapat mengalir dengan bebas ke arah itu. ForeignObject bertindak sebagai kliping area pandang.
Catatan: meskipun contoh di atas adalah konten SVG 1.1 yang valid, di SVG 2 atribut 'requiredFeatures' telah dihapus, yang berarti elemen 'switch' akan mencoba merender elemen 'g' pertama terlepas dari dukungan untuk SVG 1.2 'textArea 'elemen. Lihat spesifikasi elemen sakelar SVG2 .
xhtml:div
alih-alih div
, tetapi itu bisa jadi karena d3.js. Saya tidak dapat menemukan referensi yang berguna tentang TextFlow, apakah itu (masih) ada atau hanya dalam beberapa draf?
TextPath mungkin bagus untuk beberapa kasus.
<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>
Membangun kode @Mike Gledhill, saya telah mengambil langkah lebih jauh dan menambahkan lebih banyak parameter. Jika Anda memiliki SVG RECT dan ingin teks dibungkus di dalamnya, ini mungkin berguna:
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
};
boxwidth = parseInt(boxObject.getAttribute('width'))
hanya akan menerima lebar dalam piksel, sementara boxwidth = parseInt(boxObject.getBBox().width)
, akan menerima semua jenis satuan ukuran
Fungsionalitas ini juga dapat ditambahkan menggunakan JavaScript. Carto.net memiliki contoh:
http://old.carto.net/papers/svg/textFlow/
Hal lain yang juga mungkin berguna adalah Anda adalah area teks yang dapat diedit:
Kode berikut berfungsi dengan baik. Jalankan cuplikan kode apa yang dilakukannya.
Mungkin itu bisa dibersihkan atau membuatnya otomatis bekerja dengan semua tag teks di SVG.
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();
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;
}
<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>
Saya telah memposting panduan berikut untuk menambahkan beberapa pembungkusan kata palsu ke elemen "teks" SVG di sini:
SVG Word Wrap - Tampilkan stopper?
Anda hanya perlu menambahkan fungsi JavaScript sederhana, yang membagi string Anda menjadi elemen "tspan" yang lebih pendek. Berikut adalah contoh tampilannya:
Semoga ini membantu !