itcropper
itcropper

Reputation: 772

svg bbox() always returns a value where x and y are 0 when they shouldn't be

I'm using SVG.js to draw shapes. One of the shapes needs to be a circle with a radius line so so get that behavior, I'm using an ellipse and a line inside of a "g" element.

The trouble is, whenever I reference that g element and try to get the bbox, I always get a value like this:

{
 x: 0, 
 y: 0, 
 width: widthOfBox, 
 height: heightOfBox, 
 cx: widthOfBox/2, 
 cy: heightOfBox/2
}

x and y should NOT be 0.

Below is the element in question that is clearly not at (0,0) but seems to be reporting that it is.

<g id="MLG1008" stroke="#000000" stroke-width="2" fill="#000000" transform="translate(100 200)" width="993.3559281546569" height="993.3559281546569" x="12.963409423828125" y="-290.0365905761719">
    <ellipse id="MLEllipse1009" rx="496.67796407732845" ry="496.67796407732845" cx="496.67796407732845" cy="496.67796407732845" stroke="#000000" stroke-width="2"></ellipse>
    <line id="MLLine1010" x1="496.67796407732845" y1="496.67796407732845" x2="801.6779640773284" y2="888.6779640773284" stroke="#000000" stroke-width="2"></line>
</g>

Is there a way to define the values that bbox should have? Or a way to set the values that bbox() looks at?

Upvotes: 1

Views: 2306

Answers (3)

I also had a similar case:

  1. you add setTimerOut is working. 2: I remove getBBox() and replace getAttribute("x") // x,y,width,height

Upvotes: 0

Kaiido
Kaiido

Reputation: 136698

From W3 specs on getBBox

SVGRect getBBox()
Returns the tight bounding box in current user space (i.e., after application of the ‘transform’ attribute, if any) on the geometry of all contained graphics elements, exclusive of stroking, clipping, masking and filter effects). [...]

Emphasis mine

As you can see in this definition, the SVGRect returned by getBBox is calculated against the contained graphics elements, this means that the translation you applied on your <g> element will not be taken into account in this SVGRect, since the transformation is applied on the element itself, and not on its graphic content.

You could get these x and y values by wrapping your transformed <g> element inside an other <g> from which you would call its getBBox() method,

console.log(document.getElementById("wrapper").getBBox());
<svg viewBox="0 0 1500 1500" width="300" height="300">
  <g id="wrapper">
    <g id="MLG1008" stroke="#000000" stroke-width="2" fill="#000000" transform="translate(100 200)">
        <ellipse id="MLEllipse1009" rx="496.67796407732845" ry="496.67796407732845" cx="496.67796407732845" cy="496.67796407732845" stroke="#000000" stroke-width="2"></ellipse>
        <line id="MLLine1010" x1="496.67796407732845" y1="496.67796407732845" x2="801.6779640773284" y2="888.6779640773284" stroke="#000000" stroke-width="2"></line>
    </g>
  </g>
</svg>

or even on the parent <svg> if all its graphic elements are inside this <g>:

console.log(document.querySelector("svg").getBBox());
<svg viewBox="0 0 1500 1500" width="300" height="300">
  <g id="MLG1008" stroke="#000000" stroke-width="2" fill="#000000" transform="translate(100 200)">
      <ellipse id="MLEllipse1009" rx="496.67796407732845" ry="496.67796407732845" cx="496.67796407732845" cy="496.67796407732845" stroke="#000000" stroke-width="2"></ellipse>
      <line id="MLLine1010" x1="496.67796407732845" y1="496.67796407732845" x2="801.6779640773284" y2="888.6779640773284" stroke="#000000" stroke-width="2"></line>
  </g>
</svg>


Also, even if unrelated with your issue, note that <g> element doesn't have width, height, x nor y attributes.

Upvotes: 3

Ihor Yanovchyk
Ihor Yanovchyk

Reputation: 786

Because your <g> positioned relative to <svg>. You need to use transform="translate(x, y)" to change the element position.

Upvotes: 1

Related Questions