Ответ 1
var bbox = textElement.getBBox();
var width = bbox.width;
var height = bbox.height;
а затем соответствующим образом установите соответствующие атрибуты.
Ссылка: getBBox()
в стандарте SVG v1.1.
Я работаю над некоторыми ECMAScript/JavaScript для SVG файла и должен получить width
и height
элемента text
, чтобы изменить размер прямоугольника, который его окружает. В HTML я мог бы использовать атрибуты offsetWidth
и offsetHeight
для элемента, но кажется, что эти свойства недоступны.
Вот фрагмент, с которым мне нужно работать. Мне нужно изменить ширину прямоугольника всякий раз, когда я меняю текст, но я не знаю, как получить фактический width
(в пикселях) элемента text
.
<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;
а затем соответствующим образом установите соответствующие атрибуты.
Ссылка: getBBox()
в стандарте SVG v1.1.
Что касается длины текста, ссылка, по-видимому, указывает на то, что 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;
}
Это возвращает среднее значение любых действительных результатов трех методов. Вы можете улучшить его, чтобы изгнать outliers или одобрить getComputedTextLength
, если элемент является текстовым элементом.
Предупреждение. Как говорится в комментарии, getBoundingClientRect
сложно. Либо удалите его из методов, либо используйте его только в тех элементах, где getBoundingClientRect
вернет хорошие результаты, поэтому нет вращения и, вероятно, нет масштабирования (?)
Не уверен, почему, но ни один из вышеперечисленных методов не работает для меня. У меня был некоторый успех с методом 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;
document.getElementById('yourTextId').getComputedTextLength();
работал у меня в
function getSvgElementDims(selector) {
var c = document.querySelector("#filtered");
var matrix = c.getScreenCTM();
var r = c.getBoundingClientRect()
var pt_TopLeft = document.documentElement.createSVGPoint(r.x, r.y);
var pt_BottomRight = document.documentElement.createSVGPoint(r.right, r.bottom);
pt_TopLeft.x = r.x
pt_TopLeft.y = r.y
pt_BottomRight.x = r.right
pt_BottomRight.y = r.bottom
pt_TopLeft = pt_TopLeft.matrixTransform(matrix.inverse());
pt_BottomRight = pt_BottomRight.matrixTransform(matrix.inverse());
return {
width: pt_BottomRight.x - pt_TopLeft.x,
height: pt_BottomRight.y - pt_TopLeft.y
}
}
Спецификация SVG имеет специальный метод для возврата этой информации: getComputedTextLength()
var width = textElement.getComputedTextLength(); // returns a pixel number