Yanıtlar:
Metin sarma, şu anda uygulanan spesifikasyon olan SVG1.1'in bir parçası değildir. <foreignObject/>
Öğe aracılığıyla HTML kullanmayı tercih etmelisiniz .
<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>
İşte bir alternatif:
<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>
ForeignObject öğesinin bu özellik dizisiyle desteklendiği bildirilse bile, SVG 1.1 belirtimi tarafından gerekli olmadığı için HTML'nin görüntülenebileceğine dair hiçbir garanti bulunmadığına dikkat edin. Şu anda html-in-foreignobject desteği için bir özellik yok. Bununla birlikte, birçok tarayıcıda hala desteklenmektedir, bu nedenle gelecekte muhtemelen uygun bir özellik ile gerekli hale gelecektir.
Not o 'textarea' elemanı SVG Tiny 1.2 desteklerin tüm standart svg özellikleri, örneğin gelişmiş vb doldurma ve metin bu yönde serbestçe akabilir, yani ya otomatik olarak genişlik ve yükseklikte belirtebildiklerinden. ForeignObject, kırpma görünüm alanı olarak işlev görür.
Not: Yukarıdaki örnek geçerli SVG 1.1 içeriği olsa da, SVG 2'de "requiredFeatures" özelliği kaldırılmıştır, bu, "switch" öğesinin SVG 1.2 'textArea desteğine sahip olup olmadığına bakılmaksızın ilk "g" öğesini oluşturmaya çalışacağı anlamına gelir. ' elementler. SVG2 anahtar öğesi özelliklerine bakın .
xhtml:div
yerine kullanmam gerekiyordu div
, ancak bunun nedeni d3.js olabilir. TextFlow hakkında yararlı bir referans bulamadım, (hala) var mı yoksa sadece bir taslakta mıydı?
TextPath bazı durumlarda iyi olabilir.
<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>
@Mike Gledhill'in koduna dayanarak, bunu bir adım daha ileri götürdüm ve daha fazla parametre ekledim. Bir SVG RECT'iniz varsa ve metnin içine sarılmasını istiyorsanız, bu kullanışlı olabilir:
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'))
sadece piksel olarak genişliği kabul eder, ancak boxwidth = parseInt(boxObject.getBBox().width)
her tür ölçü birimini kabul ederdi
Bu işlevsellik, JavaScript kullanılarak da eklenebilir. Carto.net'in bir örneği var:
http://old.carto.net/papers/svg/textFlow/
Düzenlenebilir metin alanları olmanız da yararlı olabilecek başka bir şey:
Aşağıdaki kod iyi çalışıyor. Kod parçacığını ne yaptığını çalıştırın.
Belki temizlenebilir veya SVG'deki tüm metin etiketleriyle otomatik olarak çalışmasını sağlayabilir.
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>
Burada bir SVG "metin" öğesine bazı sahte kelime kaydırma eklemek için aşağıdaki izlenecek yolu yayınladım:
SVG Word Wrap - Durdurucu gösterilsin mi?
Yalnızca dizenizi daha kısa "tspan" öğelerine bölen basit bir JavaScript işlevi eklemeniz gerekir. İşte nasıl göründüğüne dair bir örnek:
Bu yardımcı olur umarım !