SVG获取文本元素的宽度
我正在为SVG文件处理一些ECMAScript / JavaScript,并需要获取text
元素的width
和height
,以便可以调整围绕它的矩形的大小。 在HTML中,我可以使用元素上的offsetWidth
和offsetHeight
属性,但看起来这些属性是不可用的。
这是我需要处理的一个片段。 我需要改变矩形的宽度,每当我改变文字,但我不知道如何获得text
元素的实际width
(以像素为单位)。
<rect x="100" y="100" width="100" height="100" /> <text>Some Text</text>
有任何想法吗?
var bbox = textElement.getBBox(); var width = bbox.width; var height = bbox.height;
然后相应地设置矩形的属性。
链接:在SVG v1.1标准中的getBBox()
。
关于文本的长度,该链接似乎指示BBox和getComputedTextLength()可能会返回稍微不同的值,但是这些值彼此相当接近。
这样的兼容性如何?
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; }
这将返回三种方法的任何有效结果的平均值。 如果元素是一个文本元素,你可以改进它来抛出exception值,或者支持getComputedTextLength
。
警告:正如评论所说, getBoundingClientRect
是棘手的。 将其从方法中移除,或仅在getBoundingClientRect
将返回良好结果的元素上使用此元素,所以不需要旋转并且可能不会缩放(?)
document.getElementById('yourTextId').getComputedTextLength();
为我工作
不知道为什么,但没有上述方法为我工作。 我用canvas方法取得了一些成功,但我必须应用各种比例因子。 即使使用比例因子,Safari,Chrome和Firefox之间的结果仍然不一致。
所以,我尝试了以下几点:
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;