Javascript 如何获取相对于持有 onclick 侦听器的 SVG 元素的点击坐标?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29261304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the click coordinates relative to SVG element holding the onclick listener?
提问by oabarca
I haven't been able to calculate the click coordinates (x and y) relative to the element triggering the event. I have not found an easy example online.
我无法计算相对于触发事件的元素的点击坐标(x 和 y)。我还没有在网上找到一个简单的例子。
I have a simple svg(with 100px left margin) in an HTML page. It contains a group(translated 30px 30px) which has an onclicklistener attached. And inside that groupI have a rectwith 50px width and height.
我svg在 HTML 页面中有一个简单的(左边距为 100 像素)。它包含一个group(translated 30px 30px)onclick附加了一个监听器。在里面group我有一个rect50px 的宽度和高度。
After I click any part of the groupelement, I get an event object with coordinates relative to the HTML page (evt.clientXand evt.clientY).
单击group元素的任何部分后,我会得到一个事件对象,其中包含相对于 HTML 页面(evt.clientX和evt.clientY)的坐标。
What I need to know is where exactly the user clicked inside the groupelement (the element holding the onclick listener).
我需要知道的是用户在group元素(包含 onclick 侦听器的元素)内单击的确切位置。
How do I convert clientXand clientYcoordinates to the groupelement coordinates. So say, if I click the top leftmost part of the rectit should give me x=0 and y=0.
如何转换clientX和clientY坐标的group元素的坐标。所以说,如果我点击最rect左上角的部分,它应该给我 x=0 和 y=0。
Here is currently what I have:
这是目前我所拥有的:
<!DOCTYPE html>
<html>
<head>
<style>
body{
background:black;
}
svg{
fill:white;
background:white;
position: absolute;
top:100px;
left:100px;
}
</style>
<script>
function clicked(evt){
alert("x: "+evt.clientX+" y:"+evt.clientY);
}
</script>
</head>
<body>
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<g transform="translate(30 30)" onclick="clicked(evt)">
<rect x="0" y="0" width="50" height="50" fill="red"/>
</g>
</svg>
</div>
</body>
</html>
采纳答案by Tolokoban
Try to use getBoundingClientRect(): http://jsfiddle.net/fLo4uatw/
尝试使用getBoundingClientRect():http: //jsfiddle.net/fLo4uatw/
function clicked(evt){
var e = evt.target;
var dim = e.getBoundingClientRect();
var x = evt.clientX - dim.left;
var y = evt.clientY - dim.top;
alert("x: "+x+" y:"+y);
}
回答by Alexander Jank
Tolokoban's solution has the limitation that it doesn't work if your viewBox deviates from the default, that is if it is different from viewBox="0 0 width height". A better solution that also takes viewBox into account is this:
Tolokoban 的解决方案有一个限制,即如果您的 viewBox 偏离默认值,即它与viewBox="0 0 width height". 一个更好的解决方案也考虑了 viewBox 是这样的:
var pt = svg.createSVGPoint(); // Created once for document
function alert_coords(evt) {
pt.x = evt.clientX;
pt.y = evt.clientY;
// The cursor point, translated into svg coordinates
var cursorpt = pt.matrixTransform(svg.getScreenCTM().inverse());
console.log("(" + cursorpt.x + ", " + cursorpt.y + ")");
}
(Credit goes to Smerk, who posted the code)
(归功于 Smerk,他发布了代码)
If the viewBox is not set or set to the default, this script will return the same values as Tolokoban's script. But if you have an SVG like <svg width="100px" height="100" viewBox="0 0 200 200">, only this version will give you the correct results.
如果 viewBox 未设置或设置为默认值,此脚本将返回与 Tolokoban 脚本相同的值。但是如果你有一个像 的 SVG <svg width="100px" height="100" viewBox="0 0 200 200">,只有这个版本才能给你正确的结果。
回答by NVRM
Adding notes after many researchs (and fails!).
在多次研究后添加注释(失败了!)。
For a css translated svg, to get the coordinates of a clicked point for drawing.
对于css 翻译的 svg,获取用于绘制的单击点的坐标。
In my case, using a mouse wheel event to translateX, so the actual rendering depends of the screen size and of the actual translated value.
在我的情况下,使用鼠标滚轮事件来 translateX,因此实际渲染取决于屏幕大小和实际翻译值。
I recommend for your use case to make a little drawing like the following, it will help a lot for figuring out what's going on.
我建议您为您的用例绘制如下所示的小图,这将有助于弄清楚发生了什么。
Let's say my svg has for id: shokeTo get the total computed width, in pixels:
假设我的 svg 有 id:shoke要获得总计算宽度,以像素为单位:
shoke.getBoundingClientRect()["width"]
Need to know the actual translateX value. (From the right, so it is a negative number, on this case)
需要知道实际的 translateX 值。(从右边开始,所以它是一个负数,在这种情况下)
shoke.style.transform.substr(11).slice(0,-3)
Note that it return a string and not an integer, so:
请注意,它返回一个字符串而不是整数,因此:
+shoke.style.transform.substr(11).slice(0,-3)
Now to get the coordinates of the mouse, related to the pixel x0 of the screen.
现在获取鼠标的坐标,与屏幕的像素 x0 相关。
let pt = document.querySelector('svg').createSVGPoint();
pt.matrixTransform(shoke.getScreenCTM().inverse())["x"]
So, at the end, to obtain the precise xpoint:
所以,最后,要获得精确的x点:
svg_width - (svg_width + translated) + from_pixel x0 of the screen_click
Is something like this:
是这样的:
shoke.getBoundingClientRect()["width"] - (shoke.getBoundingClientRect()["width"] + +shoke.style.transform.substr(11).slice(0,-3)) + pt.matrixTransform(shoke.getScreenCTM().inverse())["x"]


