Uzyskaj szerokość / wysokość elementu SVG

85

Jaki jest właściwy sposób uzyskania wymiarów svgelementu?

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"

Dostępne są właściwości width i height svg1, ale .width.baseVal.valuesą one ustawiane tylko wtedy, gdy ustawię atrybuty width i height w elemencie.


Skrzypce wygląda tak:

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
źródło

Odpowiedzi:

104

Użyj funkcji 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
źródło
10
Czy nie ma sposobu, aby traktować go jak element HTML i uzyskać rzeczywisty rozmiar, jaki svgzajmuje element, pomimo tego, co zostało narysowane? jsfiddle.net/Xkv3X/4
Langdon,
3
Przy okazji, próbuję określić rozmiar płótna, na którym mogę rysować przed renderowaniem kształtów.
Langdon
1
Myślę, że lepiej byłoby sprawdzić dostępny rozmiar kontenera (div, który zawiera twój svg), a następnie ustawić odpowiedni rozmiar svg
Pavel Gruba
1
@Langdon, który właśnie został naprawiony w Firefoksie. Firefox 33 zgłosi coś podobnego do Chrome.
Robert Longson,
2
Dzisiaj zgłosiłem problem z getBoundingClientRect dla FireFox 38, gdy używane są symbole / użycie. W tym przypadku getBoundingClientRect rozszerza element do granicy viewBox. Istnieje również znany problem dotyczący szerokości obrysu. Więc getBoundingClientRect nie jest na razie rozwiązaniem dla wielu przeglądarek.
Dzenly
50

FireFox ma problemy z getBBox (), muszę to zrobić w vanillaJS.

Mam lepszy sposób i jest to ten sam wynik, co prawdziwa funkcja svg.getBox ()!

W tym dobrym poście: Uzyskaj rzeczywisty rozmiar elementu 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
źródło
ten ! jak wspomniano, firefox ma problemy, ale działa to w większości przeglądarek :)
thatOneGuy
1
zwraca zero, gdy svg jest ukryty (na przykład w zakładce bootstrap)
Alexey Sh.
caniuse.com/#feat=getboundingclientrect - teraz wszystko wygląda dobrze, FF12 +, Chrome 4+
marksyzm
8

Używam Firefoksa, a moje działające rozwiązanie jest bardzo bliskie obysky. Jedyną różnicą jest to, że wywoływana metoda w elemencie svg zwróci wiele prostokątów i musisz wybrać pierwszą.

var chart = document.getElementsByClassName("chart")[0];
var width = chart.getClientRects()[0].width;
var height = chart.getClientRects()[0].height;
Cichelero
źródło
W ten sposób można uzyskać rozmiar przed transformzastosowaniem CSS .
Marko,
7

SVG ma właściwości widthi height. Zwracają obiekt SVGAnimatedLengthz dwiema właściwościami: animVali baseVal. Ten interfejs jest używany do animacji, gdzie baseValjest wartością przed animacją. Z tego, co widzę, ta metoda zwraca spójne wartości zarówno w przeglądarce Chrome, jak i Firefox, więc myślę, że można jej również użyć do obliczenia rozmiaru SVG.

afkatja
źródło
gdzie svg to twój element ... let svgWidth = svg.width.baseVal.value; let svgHeight = svg.height.baseVal.value;
Bob
Niestety w tej chwili nie działa to w przeglądarce Firefox - da ci to początkową wartość, ale jeśli zmienisz wymiary svg i spróbujesz ponownie, otrzymasz oryginalną wartość.
Bob
3

Oto spójny sposób, jaki znalazłem w różnych przeglądarkach:

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
źródło
3

Od Firefox 33 możesz wywołać metodę getBoundingClientRect () i będzie działać normalnie, tj. W powyższym pytaniu zwróci 300 x 100.

Firefox 33 zostanie wydany 14 października 2014 r., Ale poprawka jest już w nocnych koszach Firefoksa, jeśli chcesz ją wypróbować.

Robert Longson
źródło
-2

Metoda zapisu w celu określenia jednostki szerokości i wysokości dowolnego elementu (bez dopełnienia, bez marginesu) jest następująca:

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
źródło