Obter largura / altura do elemento SVG

85

Qual é a maneira correta de obter as dimensões de um svgelemento?

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

Chrome 28:

style x
client 300x100
offset 300x100

IE 10:

stylex 
client300x100 
offsetundefinedxundefined 

FireFox 23:

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

Existem propriedades de largura e altura ativadas svg1, mas .width.baseVal.valuesó são definidas se eu definir os atributos de largura e altura no elemento.


O violino é assim:

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;
}
Langdon
fonte

Respostas:

104

Use a função 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);
Pavel Gruba
fonte
10
Não há como tratá-lo como um elemento HTML e obter o tamanho real que o svgelemento está ocupando, apesar do que foi desenhado? jsfiddle.net/Xkv3X/4
Langdon
3
A propósito, estou tentando determinar o tamanho da tela que posso desenhar antes de renderizar as formas.
Langdon
1
Acho que pode ser melhor verificar o tamanho disponível do contêiner (o div que contém seu svg), então você pode definir o tamanho apropriado para você svg
Pavel Gruba
1
@Langdon que acabou de ser corrigido no Firefox. O Firefox 33 relatará algo semelhante ao Chrome.
Robert Longson
2
Hoje relatei um problema com getBoundingClientRect para FireFox 38 quando o símbolo / uso são usados. Nesse caso, getBoundingClientRect estende o elemento até a borda de viewBox. Também há um problema conhecido sobre a largura do traço. Portanto, getBoundingClientRect não é uma solução para vários navegadores por enquanto.
Dzenly
50

FireFox tem problemas para getBBox (), eu preciso fazer isso no vanillaJS.

Eu tenho uma maneira melhor e é o mesmo resultado da função svg.getBBox () real!

Com esta boa postagem: Obtenha o tamanho real de um elemento 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);
Obysky
fonte
este ! como disse o firefox tem problemas, mas isso funciona na maioria dos navegadores :)
thatOneGuy
1
retorna zero quando o svg está oculto (por exemplo, na guia bootstrap)
Alexey Sh.
caniuse.com/#feat=getboundingclientrect - tudo parece bem agora, FF12 +, Chrome 4+
marksyzm
8

Estou usando o Firefox e minha solução de trabalho está muito próxima do obysky. A única diferença é que o método que você chama em um elemento svg retornará vários retos e você precisa selecionar o primeiro.

var chart = document.getElementsByClassName("chart")[0];
var width = chart.getClientRects()[0].width;
var height = chart.getClientRects()[0].height;
Cichelero
fonte
Esta é a maneira de obter o tamanho antes de transformaplicar o CSS .
Marko
7

SVG tem propriedades widthe height. Eles retornam um objeto SVGAnimatedLengthcom duas propriedades: animVale baseVal. Essa interface é usada para animação, onde baseValé o valor antes da animação. Pelo que posso ver, esse método retorna valores consistentes no Chrome e no Firefox, então acho que também pode ser usado para obter o tamanho calculado do SVG.

afkatja
fonte
onde svg é o seu elemento ... deixe svgWidth = svg.width.baseVal.value; let svgHeight = svg.height.baseVal.value;
Bob
Infelizmente, isso não funciona no Firefox no momento - ele fornecerá um valor inicial, mas se você alterar as dimensões do svg e tentar novamente, ele fornecerá o valor original.
Bob
3

Esta é a maneira consistente entre navegadores que encontrei:

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;
};
Sergio
fonte
3

Do Firefox 33 em diante, você pode chamar getBoundingClientRect () e funcionará normalmente, ou seja, na pergunta acima retornará 300 x 100.

O Firefox 33 será lançado em 14 de outubro de 2014, mas a correção já está no Firefox Nightlies se você quiser experimentá-lo.

Robert Longson
fonte
-2

Um método de salvar para determinar a unidade de largura e altura de qualquer elemento (sem preenchimento, sem margem) é o seguinte:

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

let width  = parseFloat(style.width.replace("px", ""));
let height = parseFloat(style.height.replace("px", ""));
Martin Wantke
fonte