Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetBBox of SVG when hidden

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

like image 792
André R. Avatar asked Feb 02 '15 16:02

André R.


People also ask

Why can't I set the bounding box of an SVG file?

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.

How to remove the SVG element from the DOM using jQuery?

const box = svg.querySelector("[name=content]").getBBox(); // Remove the SVG element from the DOM. svg.remove(); // Set the viewBox.

What happens if visibility attribute is set to hidden?

Note: If the visibility attribute is set to hidden on a text element, then the text is invisible but still takes up space in text layout calculations. Depending on the value of attribute pointer-events, graphics elements which have their visibility attribute set to hidden still might receive events.

How to find the coordinates of the smallest rectangle in SVG?

The SVGGraphicsElement.getBBox () method allows us to determine the coordinates of the smallest rectangle in which the object fits. The coordinates returned are with respect to the current SVG space (after the application of all geometry attributes on all the elements contained in the target element).


2 Answers

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;
  }
};
like image 75
Diego Mijelshon Avatar answered Nov 14 '22 22:11

Diego Mijelshon


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;
}
like image 24
cuixiping Avatar answered Nov 14 '22 22:11

cuixiping