Svg: Why Does Getboundingclientrect Return 190 When Y Attribute Is 200?
Solution 1:
.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);
<svgid="rootBox"width="500"height="800"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"><rectx="0%"y="0%"width="100%"height="100%"fill="beige" /><svgid="textBox1"x="0%"y="200"width="100%"height="25%"><rectclass="background"x="0%"y="0%"width="100%"height="100%"fill="gray"fill-opacity="0.5" /><textclass="textGroup"x="0"y="0"><tspanx="50%"dy="-0.25em"text-anchor="middle">tspan line 0</tspan><tspanx="50%"dy="1.5em"text-anchor="middle">tspan line 1</tspan><tspanx="50%"dy="1.5em"text-anchor="middle">tspan line 2</tspan></text></svg></svg>
Solution 2:
getBoundingClientRect
takes things like scroll position into account. Any margin or padding on the HTML body would also factor in, but adding to the result rather than subtracting.
If you make sure you aren't scrolled down, and the margins do not factor in, you will get 200:
functionlog() {
var textBox = $("#textBox1");
var textBBox = textBox[0].getBoundingClientRect();
console.log("The y-pos is: " + textBBox.y);
}
log();
setInterval(log, 1000);
html,
body {
margin: 0;
padding: 0;
}
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><svgid="rootBox"width="500"height="800"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"><rectx="0%"y="0%"width="100%"height="100%"fill="beige" /><svgid="textBox1"x="0%"y="200"width="100%"height="25%"><rectclass="background"x="0%"y="0%"width="100%"height="100%"fill="gray"fill-opacity="0.5" /><textclass="textGroup"x="0"y="0"><tspanx="50%"dy="-0.25em"text-anchor="middle">tspan line 0</tspan><tspanx="50%"dy="1.5em"text-anchor="middle">tspan line 1</tspan><tspanx="50%"dy="1.5em"text-anchor="middle">tspan line 2</tspan></text></svg></svg>
Post a Comment for "Svg: Why Does Getboundingclientrect Return 190 When Y Attribute Is 200?"