Ottieni larghezza / altezza dell'elemento SVG


86

Qual è il modo corretto per ottenere le dimensioni di 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"

Ci sono proprietà di larghezza e altezza su svg1, ma .width.baseVal.valueviene impostato solo se imposto gli attributi di larghezza e altezza sull'elemento.


Il violino ha questo aspetto:

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

Risposte:


105

Usa la funzione 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
Non c'è modo di trattarlo come un elemento HTML e ottenere la dimensione effettiva che l' svgelemento occupa nonostante ciò che è stato disegnato? jsfiddle.net/Xkv3X/4
Langdon

3
A proposito, sto cercando di determinare la dimensione della tela su cui posso disegnare prima di eseguire il rendering delle forme.
Langdon

1
Penso che potrebbe essere meglio controllare la dimensione disponibile del contenitore (il div che contiene il tuo svg), quindi puoi impostare la dimensione appropriata per il tuo svg
Pavel Gruba

1
@Langdon che è stato appena corretto in Firefox. Firefox 33 riporterà qualcosa di simile a Chrome.
Robert Longson

2
Oggi ho segnalato un problema con getBoundingClientRect per FireFox 38 quando vengono utilizzati simboli / usi. In questo caso getBoundingClientRect estende l'elemento fino al bordo di viewBox. Inoltre esiste un problema noto relativo alla larghezza del tratto. Quindi getBoundingClientRect non è una soluzione cross browser per ora.
Dzenly

51

FireFox ha problemi con getBBox (), devo farlo in vanillaJS.

Ho un modo migliore ed è lo stesso risultato della vera funzione svg.getBBox ()!

Con questo buon post: ottieni la dimensione reale di 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);

questo ! come detto firefox ha problemi ma funziona nella maggior parte dei browser :)
thatOneGuy

1
restituisce zero quando svg è nascosto (ad esempio nella scheda bootstrap)
Alexey Sh.

caniuse.com/#feat=getboundingclientrect - sembra tutto a posto ora, FF12 +, Chrome 4+
marksyzm

8

Sto usando Firefox e la mia soluzione di lavoro è molto simile a obysky. L'unica differenza è che il metodo che chiami in un elemento svg restituirà più rects e dovrai selezionare il primo.

var chart = document.getElementsByClassName("chart")[0];
var width = chart.getClientRects()[0].width;
var height = chart.getClientRects()[0].height;

Questo è il modo per ottenere la dimensione prima dell'applicazione del CSS transform.
Marko

7

SVG ha proprietà widthe height. Restituiscono un oggetto SVGAnimatedLengthcon due proprietà: animVale baseVal. Questa interfaccia viene utilizzata per l'animazione, dove baseValè il valore prima dell'animazione. Da quello che posso vedere, questo metodo restituisce valori coerenti sia in Chrome che in Firefox, quindi penso che possa essere utilizzato anche per ottenere la dimensione calcolata di SVG.


dove svg è il tuo elemento ... let svgWidth = svg.width.baseVal.value; let svgHeight = svg.height.baseVal.value;
Bob il

Sfortunatamente questo non funziona su Firefox al momento: ti darà un valore iniziale, ma se modifichi le dimensioni di svg e riprovi ti dà il valore originale.
Bob

3

Questo è il modo coerente cross-browser che ho trovato:

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

Da Firefox 33 in poi puoi chiamare getBoundingClientRect () e funzionerà normalmente, cioè nella domanda sopra restituirà 300 x 100.

Firefox 33 verrà rilasciato il 14 ottobre 2014, ma la correzione è già nei nightly di Firefox se vuoi provarlo.


-2

Un metodo di salvataggio per determinare l'unità di larghezza e altezza di qualsiasi elemento (nessun riempimento, nessun margine) è il seguente:

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

let width  = parseFloat(style.width.replace("px", ""));
let height = parseFloat(style.height.replace("px", ""));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.