Получить ширину / высоту элемента SVG

86

Как правильно получить размеры svgэлемента?

http://jsfiddle.net/langdonx/Xkv3X/

Хром 28:

style x
client 300x100
offset 300x100

IE 10:

stylex 
client300x100 
offsetundefinedxundefined 

FireFox 23:

"style" "x"
"client" "0x0"
"offset" "undefinedxundefined"

Есть свойства ширины и высоты svg1, но они .width.baseVal.valueустанавливаются, только если я установил атрибуты ширины и высоты для элемента.


Скрипка выглядит так:

HTML

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <circle cx="50" cy="50" r="40" stroke="black" stroke-width="1" fill="red" />
    <circle cx="150" cy="50" r="40" stroke="black" stroke-width="1" fill="green" />
    <circle cx="250" cy="50" r="40" stroke="black" stroke-width="1" fill="blue" />
</svg>

JS

var svg1 = document.getElementById('svg1');

console.log(svg1);
console.log('style', svg1.style.width + 'x' + svg1.style.height);
console.log('client', svg1.clientWidth + 'x' + svg1.clientHeight);
console.log('offset', svg1.offsetWidth + 'x' + svg1.offsetHeight);

CSS

#svg1 {
    width: 300px;
    height: 100px;
}
Лэнгдон
источник

Ответы:

105

Используйте функцию getBBox

http://jsfiddle.net/Xkv3X/1/

var bBox = svg1.getBBox();
console.log('XxY', bBox.x + 'x' + bBox.y);
console.log('size', bBox.width + 'x' + bBox.height);
Павел Груба
источник
11
Нет ли способа рассматривать его как элемент HTML и получать фактический размер, который svgэлемент занимает, несмотря на то, что было нарисовано? jsfiddle.net/Xkv3X/4
Лэнгдон
3
Кстати, я пытаюсь определить размер холста, на котором я могу рисовать, перед рендерингом фигур.
Лэнгдон
1
Я думаю, было бы лучше проверить доступный размер контейнера (div, который содержит ваш svg), тогда вы можете установить соответствующий размер для вас svg
Павел Груба
1
@Langdon, это только что исправили в Firefox. Firefox 33 сообщит о чем-то похожем на Chrome.
Роберт Лонгсон 09
2
Сегодня я сообщил о проблеме с getBoundingClientRect для FireFox 38 при использовании символа / использования. В этом случае getBoundingClientRect расширяет элемент до границы viewBox. Также существует известная проблема с шириной штриха. Так что getBoundingClientRect на данный момент не является кроссбраузерным решением.
Дзенлы
51

У FireFox есть проблемы с getBBox (), мне нужно сделать это в vanillaJS.

У меня лучший способ, и результат такой же, как и у настоящей функции svg.getBBox ()!

В этом хорошем посте: Получите реальный размер элемента SVG / G

var el   = document.getElementById("yourElement"); // or other selector like querySelector()
var rect = el.getBoundingClientRect(); // get the bounding rectangle

console.log( rect.width );
console.log( rect.height);
обыский
источник
этот ! как сказано, у firefox есть проблемы, но это работает в большинстве браузеров :)
thatOneGuy 02 окт.15,
1
возвращает ноль, когда svg скрыт (например, во вкладке bootstrap)
Алексей Ш.
caniuse.com/#feat=getboundingclientrect - теперь все в порядке, FF12 +, Chrome 4+
marksyzm
8

Я использую Firefox, и мое рабочее решение очень близко к обычному. Единственное отличие состоит в том, что метод, который вы вызываете в элементе svg, вернет несколько прямоугольников, и вам нужно выбрать первый.

var chart = document.getElementsByClassName("chart")[0];
var width = chart.getClientRects()[0].width;
var height = chart.getClientRects()[0].height;
Cichelero
источник
Это способ получить размер до применения CSS transform.
Марко
7

SVG имеет свойства widthи height. Они возвращают объект SVGAnimatedLengthс двумя свойствами: animValи baseVal. Этот интерфейс используется для анимации, где baseVal- значение перед анимацией. Насколько я могу судить, этот метод возвращает согласованные значения как в Chrome, так и в Firefox, поэтому я думаю, что его также можно использовать для получения расчетного размера SVG.

Афкатья
источник
где svg - ваш элемент ... let svgWidth = svg.width.baseVal.value; пусть svgHeight = svg.height.baseVal.value;
Боб
К сожалению, на данный момент это не работает в Firefox - он даст вам начальное значение, но если вы измените размеры svg и попытаетесь снова, он вернет вам исходное значение.
Боб
3

Я нашел последовательный кроссбраузерный способ:

var heightComponents = ['height', 'paddingTop', 'paddingBottom', 'borderTopWidth', 'borderBottomWidth'],
    widthComponents = ['width', 'paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'];

var svgCalculateSize = function (el) {

    var gCS = window.getComputedStyle(el), // using gCS because IE8- has no support for svg anyway
        bounds = {
            width: 0,
            height: 0
        };

    heightComponents.forEach(function (css) { 
        bounds.height += parseFloat(gCS[css]);
    });
    widthComponents.forEach(function (css) {
        bounds.width += parseFloat(gCS[css]);
    });
    return bounds;
};
Серджио
источник
3

Начиная с Firefox 33, вы можете вызывать getBoundingClientRect (), и он будет работать нормально, т.е. в приведенном выше вопросе он вернет 300 x 100.

Firefox 33 будет выпущен 14 октября 2014 года, но исправление уже есть в ночных сборниках Firefox, если вы хотите его попробовать.

Роберт Лонгсон
источник
-2

Метод сохранения для определения единицы ширины и высоты любого элемента (без отступов, без полей) следующий:

let div   = document.querySelector("div");
let style = getComputedStyle(div);

let width  = parseFloat(style.width.replace("px", ""));
let height = parseFloat(style.height.replace("px", ""));
Мартин Вантке
источник