Good time forum users. I apologize in advance for my English. I could not find the answer (I decided to ask the English-speaking audience).
Absolute positioning (coordinates) of an element nested in groups relative to the parent container ().
<svg width="100%" height="100%" viewBox="0 0 1000 1000" preserveAspectRatio="xMidYMin slice" x="0" y="0" tabindex="1"> <g transform="translate(100 100)"> <g transform="translate(100 100)"> <circle r="50" cx="25" cy="25" fill="yellow" /> </g> </g> <svg>
I would like to get using ES6 + circle coordinates relative to SVG. That is x = 100 + 100 + 25, y = 100 + 100 + 25 for.
How can I get these coordinates? (can be up to an infinite nesting of groups). Thanks for helping.
cx
and cy
values of the circle function getCirclePosition(circleElemId) { var elem = document.getElementById(circleElemId); var svg = elem.ownerSVGElement; // Get the cx and cy coordinates var pt = svg.createSVGPoint(); pt.x = elem.cx.baseVal.value; pt.y = elem.cy.baseVal.value; while (true) { // Get this elements transform var transform = elem.transform.baseVal.consolidate(); // If it has a transform, then apply it to our point if (transform) { var matrix = elem.transform.baseVal.consolidate().matrix; pt = pt.matrixTransform(matrix); } // If this element's parent is the root SVG element, then stop if (elem.parentNode == svg) break; // Otherwise step up to the parent element and repeat the process elem = elem.parentNode; } return pt; } var pos = getCirclePosition("thecircle"); console.log("Coordinates are: " + pos.x + "," + pos.y);
<svg width="100%" height="100%" viewBox="0 0 1000 1000" preserveAspectRatio="xMidYMin slice" x="0" y="0" tabindex="1"> <g transform="translate(100 100)"> <g transform="translate(100 100)"> <circle id="thecircle" r="50" cx="25" cy="25" fill="yellow" /> </g> </g> <svg>
Update
As @Vad0k pointed out, there is a simpler, but slighlty less accurate approach, that can be used instead:
function getCirclePosition(circleElemId) { var elem = document.getElementById(circleElemId); var svg = elem.ownerSVGElement; // Get the cx and cy coordinates var pt = svg.createSVGPoint(); pt.x = elem.cx.baseVal.value; pt.y = elem.cy.baseVal.value; return pt.matrixTransform(getTransformToElement(elem, svg)); } function getTransformToElement(fromElement, toElement) { return toElement.getCTM().inverse().multiply(fromElement.getCTM()); }; var pos = getCirclePosition("thecircle"); console.log("Coordinates are: " + pos.x + "," + pos.y);
<svg width="100%" height="100%" viewBox="0 0 1000 1000" preserveAspectRatio="xMidYMin slice" x="0" y="0" tabindex="1"> <g transform="translate(100 100)"> <g transform="translate(100 100)"> <circle id="thecircle" r="50" cx="25" cy="25" fill="yellow" /> </g> </g> <svg>
Obtain the childs and parents top and left and get the difference
const circleLeft = circleElement.getBoundingRect().offsetLeft
const circleTop = circleElement.getBoundingRect().top
const parentLeft = circleElement.parentElement.getBoundingRect().offsetLeft
const parentTop = circleElement.parentElement.getBoundingRect().top
const changeInX = parentLeft - cirleLeft
const changeInY = parentTop - circleTop
If you are registering events on this elements, Register them as capturing event rather than bubbling event by passing true
as third argument to addEventListener
I just found, that you can use getBBox() on a SVG element to get its visible rectangle.
var rect = document.getElementById("myrect");
var visibleRect = rect.getBBox();
console.log("x=" + visibleRect.x + ", y=" + visibleRect.y + ", width=" + visibleRect.width + ", height=" + visibleRect.height);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.