隐藏时获取SVG的GetBBox

时间:2015-02-02 16:31:45

标签: javascript jquery svg inline

我现在试图解决这个问题超过一天,但我无法找到答案。我的问题是我需要扩展SVG图像(响应式设计)。我需要在客户端操作SVG代码,因此通过img标签嵌入它不是一种选择。因此我尝试使用内嵌图像。但是,为了正确地缩放它,似乎我需要设置viewBox属性。 SVG文件是由某些软件生成的,这些软件无法在其上设置边界框,因此我的想法是使用JavaScript来实现此目的。

问题是我的软件使用了库中的各种标签控件,我无法修改。我无法获得边界框,因为它最初没有呈现,因此我只是返回零(在Chrome中)或错误消息(在Firefox中)。

我需要的是一种在不实际渲染对象的情况下获取边界框大小的方法。无法操纵显示参数,库用于显示和隐藏选项卡。

有什么想法吗?

一个想法是将SVG复制到另一个可见的div中,但我不知道这是否能解决问题。我不知道该怎么做。

祝你好运

3 个答案:

答案 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
}