GetBBox SVG when hiding

I have been trying to solve this problem for more than one day, but I can not find the answer. My problem is that I need to scale the SVG image (responsive design). I need to manipulate client side SVG code, so embedding it through the img tag is not an option. So I tried using the inline image. However, to scale it properly, it seems to me that I need to set the viewBox property. SVG files are created using some software that cannot set the bounding box on its own, so my idea was to use JavaScript for this purpose.

The problem is that my software uses various tab controls from a library that I cannot change. I can’t just get the bounding box because it doesn’t appear initially, and so I just return zeros (in Chrome) or error messages (in Firefox).

I need a way to get the size of the bounding box without actually rendering the object. It is not possible to manipulate the display option that the library uses to display and hide tabs.

Any ideas?

One idea was to copy the SVG to another, visible div, but I don't know if this will solve the problem. And I don’t know how to do it.

Regards

+4
3

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

cuixiping answer :

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
}
+1

Based on the previous answers, I neutralized getBBoxinit in my application so that it transparently uses the hack.

Now I can call getBBoxdirectly on any element, regardless of whether it is 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;
  }
};
+1
source

All Articles