问题
I'm trying to solve this problem for more than one day now, but I can't find an answer. My problem is that I need to scale an SVG image (responsive design). I need to manipulate the SVG code on the client side, so embedding it via img tag is not an option. Therefore I tried to use an inline image instead. However, to scale it properly it seems that I need to set the viewBox property. The SVG files are generated by some software which can't set the bounding box on it's own, so my idea was to use JavaScript for that purpose.
The problem is that my software uses various tab controls from a library which I can't modify. I can't just get the bounding box, because it's not rendered initially and therefore I just get back zeros (in Chrome) or error messages (in Firefox).
What I need is a way to get the size of the bounding box without actually rendering the object. It is not possible to manipulate the display parameter, which the library uses to show and hide tabs.
Any ideas?
One idea was to copy the SVG into another, visible div, but I don't know if that would solve the problem. And I don't know how to do it.
Best regards
回答1:
Based on the previous answers, I monkeypatched getBBox on my app init so it will transparently apply the hack.
Now I can call getBBox directly on any element, whether it's attached or not.
_getBBox = SVGGraphicsElement.prototype.getBBox;
SVGGraphicsElement.prototype.getBBox = function() {
var bbox, tempDiv, tempSvg;
if (document.contains(this)) {
return _getBBox.apply(this);
} else {
tempDiv = document.createElement("div");
tempDiv.setAttribute("style", "position:absolute; visibility:hidden; width:0; height:0");
if (this.tagName === "svg") {
tempSvg = this.cloneNode(true);
} else {
tempSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
tempSvg.appendChild(this.cloneNode(true));
}
tempDiv.appendChild(tempSvg);
document.body.appendChild(tempDiv);
bbox = _getBBox.apply(tempSvg);
document.body.removeChild(tempDiv);
return bbox;
}
};
回答2:
you can clone it to a visible svg and then getBBox.
Add into you html:
<div style="position:absolute;left:-9999cm;top:-9999cm;visibility:hidden;">
<svg id="svg1" xmlns="http://www.w3.org/2000/svg"></svg>
</div>
Add into your javascript:
function getBBox(elem){
var svg1 = document.getElementById('svg1'), e = elem.cloneNode(true);
e.style.display = "inline";
svg1.appendChild(e);
var b = e.getBBox();
svg1.removeChild(e);
return b;
}
回答3:
cuixiping's answer as a function:
function svgBBox (svgEl) {
let tempDiv = document.createElement('div')
tempDiv.setAttribute('style', "position:absolute; visibility:hidden; width:0; height:0")
document.body.appendChild(tempDiv)
let tempSvg = document.createElementNS("http://www.w3.org/2000/svg", 'svg')
tempDiv.appendChild(tempSvg)
let tempEl = svgEl.cloneNode(true)
tempSvg.appendChild(tempEl)
let bb = tempEl.getBBox()
document.body.removeChild(tempDiv)
return bb
}
来源:https://stackoverflow.com/questions/28282295/getbbox-of-svg-when-hidden