.getBoundingClientRect()
is part of the generic Element
interface, and computes the rectangle in relation to the screen viewport. SVG offer some more specific methods:
SVGGraphicsElement.getBBox()
computes the bounding box in the local coordinate system the element is drawn in.
SVGGraphicsElement.getCTM()
computes the transformation matrix getween the local coordinate system and the nearest SVG viewport (a <svg>
element, for example).
SVGGraphicsElement.getScreenCTM()
computes the transformation matrix getween the local coordinate system and the screen viewport.
In addition, the DOMMatrix
interface has an .inverse()
method, so you can easily compute positions in the opposite direction. (For example, if you transform a mouse event screenx/screenY position with the result of element.getScreenCTM().inverse()
, you'll get the mouse position in relation to that element.)
The one thing a bit awkward is that you have to construct a SVGPoint
object, which can only be achieved by the SVGSVGElement.createSVGPoint()
method on an <svg>
element, to have something to apply your matrix to.
As for your question, consider the different return values for the three doordinate systems for the rect inside the inner <svg>
:
var textBox = document.querySelector('#textBox1 rect');
var svg = document.querySelector('#rootBox');
var point = svg.createSVGPoint();
var local = textBox.getBBox();
point.x = local.x, point.y = local.y;
console.log("local: ", local.x, local.y);
var nearest = textBox.getCTM();
var point2 = point.matrixTransform(nearest);
console.log("nearest viewport: ", point2.x, point2.y);
var screen = textBox.getScreenCTM();
var point3 = point.matrixTransform(screen);
console.log("screen viewport: ", point3.x, point3.y);
<svg id="rootBox" width="500" height="800" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="0%" y="0%" width="100%" height="100%" fill="beige" />
<svg id="textBox1" x="0%" y="200" width="100%" height="25%">
<rect class="background" x="0%" y="0%" width="100%" height="100%" fill="gray" fill-opacity="0.5" />
<text class="textGroup" x="0" y="0"><tspan x="50%" dy="-0.25em" text-anchor="middle">tspan line 0</tspan><tspan x="50%" dy="1.5em" text-anchor="middle">tspan line 1</tspan><tspan x="50%" dy="1.5em" text-anchor="middle">tspan line 2</tspan></text>
</svg>
</svg>