I am a beginner in web development & svg related topics.
I think this should be easy for you svg experts, but I am struggling with this for a while now. All the resources I found on this topic don't seem to work for my fairly simple goal.
My application should run in Chrome browser.
The DOM structure like this:
<div>
<svg>
<g>
<circle></circle>
</g>
<svg>
</div>
There could be way more svg tags or nested svg elements inside though, but this is the general setup.
The goal:
I want to click somewhere and find the svg child element (e.g. the circle) which is at the position of my click. The basic function I was thinking of was:
document.elementFromPoint(x, y)
The problems:
1) All the elements can have transformations, like translate, scale and rotation applied to them, which complicates things.
2) I only want to be able to click elements, which are children of an svg node.
Some of my tries:
https://jsfiddle.net/a6uLn9cn/3/
I tried to put "pointer-events:none" on the DIV and / or the SVG node. This way, I am able to avoid that these are "clickable". There are two problems here though: I need pointer-events on the SVG node, as it needs to be zoomed & panned, and also the click events on e.g. the circle "bubbles" up to the DIV afterwards somehow.
Another way to make sure that only children of an svg node are "clickable" can be to check the element.ownerSVGDocument for the found element. If it is null or undefined, I know the found element is not a svg child.
To tackle the problem of actually clicking on an element which has been transformed (either by itself or through its parent), I tried to use element.getBoundingClientRect() which gives me the surrounding rectangle of an element. With this, I made a function to determine if the click was inside of an elements surrounding rectangle:
e is the click event, elem is the found element recieved by document.elementFromPoint()
function clickIsInside(e, elem){
var clickX = e.clientX;
var clickY = e.clientY;
var boxLeft = elem.getBoundingClientRect().left;
var boxRight = elem.getBoundingClientRect().right;
var boxTop = elem.getBoundingClientRect().top;
var boxBottom = elem.getBoundingClientRect().bottom;
if(clickX >= boxLeft && clickX <= boxRight && clickY >= boxTop && clickY <= boxBottom){
return true;
} else {
return false;
}
}
But in my jsfiddle, you will not be able to "click" the path for example on the far right side of its boundingClientRect, which makes no sense to me if you imagine where the boundingClientRect is.
Also if i add the path to the DOM after i added the circles, I will not be able to click the circles anymore, but only the path. I totally understand why, but what if i need to click both?
I am not sure if I was able to clearify my troubles here, but I will be very thankful for any input you guys can possibly give me. Thank you very much.