SVG ottiene la larghezza dell’elemento di testo

Sto lavorando su alcuni ECMAScript / JavaScript per un file SVG e ho bisogno di ottenere la width e l’ height di un elemento di text modo da poter ridimensionare un rettangolo che lo circonda. In HTML sarei in grado di utilizzare gli attributi offsetWidth e offsetHeight sull’elemento, ma sembra che tali proprietà non siano disponibili.

Ecco un frammento con cui ho bisogno di lavorare. Devo cambiare la larghezza del rettangolo ogni volta che cambio il testo, ma non so come ottenere la width effettiva (in pixel) dell’elemento di text .

  Some Text 

Qualche idea?

 var bbox = textElement.getBBox(); var width = bbox.width; var height = bbox.height; 

e quindi impostare gli attributi del retto di conseguenza.

Link: getBBox() nello standard SVG v1.1.

Per quanto riguarda la lunghezza del testo, il collegamento sembra indicare che BBox e getComputedTextLength () potrebbero restituire valori leggermente diversi, ma che sono abbastanza vicini tra loro.

http://bl.ocks.org/MSCAU/58bba77cdcae42fc2f44

Che ne dici di qualcosa di simile per la compatibilità:

 function svgElemWidth(elem) { var methods = [ // name of function and how to process its result { fn: 'getBBox', w: function(x) { return x.width; }, }, { fn: 'getBoundingClientRect', w: function(x) { return x.width; }, }, { fn: 'getComputedTextLength', w: function(x) { return x; }, }, // text elements only ]; var widths = []; var width, i, method; for (i = 0; i < methods.length; i++) { method = methods[i]; if (typeof elem[method.fn] === 'function') { width = method.w(elem[method.fn]()); if (width !== 0) { widths.push(width); } } } var result; if (widths.length) { result = 0; for (i = 0; i < widths.length; i++) { result += widths[i]; } result /= widths.length; } return result; } 

Ciò restituisce la media di tutti i risultati validi dei tre metodi. Potresti migliorarlo per escludere i getComputedTextLength anomali o per privilegiare getComputedTextLength se l'elemento è un elemento di testo.

Avvertenza: come dice il commento, getBoundingClientRect è complicato. O rimuovilo dai metodi o getBoundingClientRect solo su elementi dove getBoundingClientRect restituirà buoni risultati, quindi nessuna rotazione e probabilmente nessun ridimensionamento (?)

 document.getElementById('yourTextId').getComputedTextLength(); 

lavorato per me in

Non so perché, ma nessuno dei metodi sopra funziona per me. Ho avuto qualche successo con il metodo canvas, ma ho dovuto applicare tutti i tipi di fattori di scala. Anche con i fattori di scala ho ancora avuto risultati incoerenti tra Safari, Chrome e Firefox.

Quindi, ho provato quanto segue:

  var div = document.createElement('div'); div.style.position = 'absolute'; div.style.visibility = 'hidden'; div.style.height = 'auto'; div.style.width = 'auto'; div.style.whiteSpace = 'nowrap'; div.style.fontFamily = 'YOUR_FONT_GOES_HERE'; div.style.fontSize = '100'; div.style.border = "1px solid blue"; // for convenience when visible div.innerHTML = "YOUR STRING"; document.body.appendChild(div); var offsetWidth = div.offsetWidth; var clientWidth = div.clientWidth; document.body.removeChild(div); return clientWidth; 

Le specifiche SVG hanno un metodo specifico per restituire queste informazioni: getComputedTextLength()

 var width = textElement.getComputedTextLength(); // returns a pixel number