[英]How to find nested and transformed SVG element (e.g. circle / path / …) based on click position
我是Web开发和SVG相关主题的初学者。
我认为这对您的svg专家来说应该很容易,但是我现在已经为此苦苦挣扎了一段时间。 我在此主题上找到的所有资源似乎都无法达到我的简单目标。
我的应用程序应在Chrome浏览器中运行。
DOM结构如下:
<div>
<svg>
<g>
<circle></circle>
</g>
<svg>
</div>
虽然里面可能会有更多的svg标签或嵌套的svg元素,但这是常规设置。
目标:
我想单击某处并找到位于我点击位置的svg子元素(例如圆圈)。 我想到的基本功能是:
document.elementFromPoint(x, y)
问题:
1)所有元素都可以应用变换,例如平移,缩放和旋转,这会使事情变得复杂。
2)我只希望能够单击svg节点的子元素。
我的一些尝试:
https://jsfiddle.net/a6uLn9cn/3/
我试图在DIV和/或SVG节点上放置“ pointer-events:none”。 这样,我可以避免这些是“可点击的”。 但是,这里有两个问题:我需要SVG节点上的指针事件,因为它需要缩放和平移,并且还需要以某种方式使圆圈上的单击事件“冒泡”(直到后来升到DIV)。
确保只有svg节点的子级是“可单击的”,另一种方法是检查element.ownerSVGDocument中是否找到了元素。 如果它为null或未定义,我知道找到的元素不是svg子级。
为了解决实际单击已转换的元素(本身或通过其父元素)的问题,我尝试使用element.getBoundingClientRect(),它为我提供了元素周围的矩形。 这样,我创建了一个函数来确定单击是否在矩形周围的元素内:
e是单击事件,elem是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;
}
}
但是在我的jsfiddle中,您将无法“单击”该路径,例如在boundingClientRect的最右边。如果您想象boundingClientRect在哪里,这对我来说毫无意义。
另外,如果我在添加圆圈之后将路径添加到DOM,则将不再能够单击圆圈,而只能单击路径。 我完全理解为什么,但是如果我需要同时单击两者怎么办?
我不确定我是否能够解决这里的问题,但是对于你们可以给我的任何意见,我将非常感谢。 非常感谢你。
我发现我在问题中所做的大多数事情只是使事情复杂化。 解决方案只是检查找到的元素是否具有任何ownerSVGDElement,如果没有则不调度click事件。 对元素的应用转换似乎没有问题,因为document.elementFromPoint()足够强大,可以找到转换后的元素。 现在,这个问题似乎没有用,所以我回答并关闭该问题只是出于罕见的条件,即任何人都将遇到或尝试像我一样无脑的事情。
编辑:好像我只能在2天内接受此作为答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.