Obtener el ancho / alto del elemento SVG

85

¿Cuál es la forma correcta de obtener las dimensiones de un 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"

Hay propiedades de ancho y alto activadas svg1, pero .width.baseVal.valuesolo se establecen si configuro los atributos de ancho y alto en el elemento.


El violín se ve así:

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
fuente

Respuestas:

104

Usar la función 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
fuente
10
¿No hay forma de tratarlo como un elemento HTML y obtener el tamaño real que svgocupa el elemento a pesar de lo que se ha dibujado? jsfiddle.net/Xkv3X/4
Langdon
3
Por cierto, estoy tratando de determinar el tamaño del lienzo en el que puedo dibujar antes de renderizar formas.
Langdon
1
Creo que sería mejor verificar el tamaño disponible del contenedor (el div que contiene su svg) y luego puede establecer el tamaño apropiado para usted svg
Pavel Gruba
1
@Langdon que se acaba de arreglar en Firefox. Firefox 33 informará algo similar a Chrome.
Robert Longson
2
Hoy informé un problema con getBoundingClientRect para FireFox 38 cuando se usan símbolo / uso. En este caso, getBoundingClientRect extiende el elemento hasta el borde de viewBox. También existe un problema conocido sobre el ancho de trazo. Por lo tanto, getBoundingClientRect no es una solución de navegador cruzado por ahora.
Dzenly
50

FireFox tiene problemas para getBBox (), necesito hacer esto en vanillaJS.

¡Tengo una mejor manera y es el mismo resultado que la función svg.getBBox () real!

Con esta buena publicación: Obtén el tamaño real de un 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
fuente
éste ! como dijo Firefox tiene problemas, pero esto funciona en la mayoría de los navegadores :)
thatOneGuy
1
devuelve cero cuando el svg está oculto (por ejemplo, en la pestaña bootstrap)
Alexey Sh.
caniuse.com/#feat=getboundingclientrect - todo se ve bien ahora, FF12 +, Chrome 4+
marksyzm
8

Estoy usando Firefox y mi solución de trabajo está muy cerca de obysky. La única diferencia es que el método al que llama en un elemento svg devolverá múltiples rects y debe seleccionar el primero.

var chart = document.getElementsByClassName("chart")[0];
var width = chart.getClientRects()[0].width;
var height = chart.getClientRects()[0].height;
Cichelero
fuente
Esta es la forma de obtener el tamaño antes de transformaplicar CSS .
Marko
7

SVG tiene propiedades widthy height. Devuelven un objeto SVGAnimatedLengthcon dos propiedades: animValy baseVal. Esta interfaz se utiliza para la animación, donde baseVales el valor antes de la animación. Por lo que puedo ver, este método devuelve valores consistentes tanto en Chrome como en Firefox, así que creo que también se puede usar para obtener el tamaño calculado de SVG.

afkatja
fuente
donde svg es su elemento ... let svgWidth = svg.width.baseVal.value; let svgHeight = svg.height.baseVal.value;
Bob
Desafortunadamente, esto no funciona en Firefox en este momento; le dará un valor inicial, pero si cambia las dimensiones de svg y lo vuelve a intentar, le dará el valor original.
Bob
3

Esta es la forma coherente entre navegadores que encontré:

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
fuente
3

Desde Firefox 33 en adelante, puede llamar a getBoundingClientRect () y funcionará normalmente, es decir, en la pregunta anterior devolverá 300 x 100.

Firefox 33 se lanzará el 14 de octubre de 2014, pero la solución ya está disponible en Firefox nightlies si quieres probarlo.

Robert Longson
fuente
-2

Un método de guardado para determinar la unidad de ancho y alto de cualquier elemento (sin relleno, sin margen) es el siguiente:

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
fuente