我现在试图解决这个问题超过一天,但我无法找到答案。我的问题是我需要扩展SVG图像(响应式设计)。我需要在客户端操作SVG代码,因此通过img标签嵌入它不是一种选择。因此我尝试使用内嵌图像。但是,为了正确地缩放它,似乎我需要设置viewBox属性。 SVG文件是由某些软件生成的,这些软件无法在其上设置边界框,因此我的想法是使用JavaScript来实现此目的。
问题是我的软件使用了库中的各种标签控件,我无法修改。我无法获得边界框,因为它最初没有呈现,因此我只是返回零(在Chrome中)或错误消息(在Firefox中)。
我需要的是一种在不实际渲染对象的情况下获取边界框大小的方法。无法操纵显示参数,库用于显示和隐藏选项卡。
有什么想法吗?
一个想法是将SVG复制到另一个可见的div中,但我不知道这是否能解决问题。我不知道该怎么做。
祝你好运
答案 0 :(得分:2)
你可以将它克隆到一个可见的svg,然后是getBBox。
加入你的html:
<div style="position:absolute;left:-9999cm;top:-9999cm;visibility:hidden;">
<svg id="svg1" xmlns="http://www.w3.org/2000/svg"></svg>
</div>
添加到您的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;
}
答案 1 :(得分:2)
根据以前的答案,我在app init上monkeypatched getBBox
,这样就可以透明地应用hack。
现在我可以直接在任何元素上调用getBBox
,无论是否附加。
_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 :(得分:1)
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
}