最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Click event coordinates in SVG - Stack Overflow

programmeradmin3浏览0评论

This HTML containing SVG:

<div class="container">
  <div class="spacer"></div>
  <svg>
    <g id="polygonGroup" transform="translate(80, 50)">
      <polygon points="-60,-10 -35,-30 -10,-10 -10,30 -60,30"></polygon>
      <polygon points="10,-10 35,-30 60,-10 60,30 10,30"></polygon>
      <polygon class="origin" points="-4,0 0,4 4,0 0,-4"></polygon>
    </g>
    <g id="textGroup" transform="translate(80, 50)">
      <text x="-35" y="10">Text</text>
      <text x="35" y="10">Text</text>
    </g>
  </svg>
</div>

and this simple jQuery click event handler:

function clicked(event) {
    console.log(event.offsetX, event.offsetY);
}

$('svg').click(clicked);

as seen here: / have different behaviors in different browsers:

Chrome: The coordinates are based on the top left of the SVG element, no matter where I click inside the SVG. This is the behavior I want.

Firefox: The coordinates are based on the top left of whatever element I'm in, which may be SVG, polygon, or text.

IE and Edge:

  • When in the SVG but not in any of its sub-elements, the coordinates are based on the SVG element.
  • When in a polygon, the coordinates are based on the origin of the <g> group, with its translate offset (i.e., the black diamond). Negative coordinates are possible this way, unlike in Chrome or Firefox.
  • I have observed a different behavior for text elements in these browsers: They would give coordinates based on the bottom middle of the text element. But I couldn't manage to reproduce this in the fiddle; in the fiddle text elements behave the same as polygons in these browsers.

What is a reliable cross-browser way to get the coordinates of the click?

This HTML containing SVG:

<div class="container">
  <div class="spacer"></div>
  <svg>
    <g id="polygonGroup" transform="translate(80, 50)">
      <polygon points="-60,-10 -35,-30 -10,-10 -10,30 -60,30"></polygon>
      <polygon points="10,-10 35,-30 60,-10 60,30 10,30"></polygon>
      <polygon class="origin" points="-4,0 0,4 4,0 0,-4"></polygon>
    </g>
    <g id="textGroup" transform="translate(80, 50)">
      <text x="-35" y="10">Text</text>
      <text x="35" y="10">Text</text>
    </g>
  </svg>
</div>

and this simple jQuery click event handler:

function clicked(event) {
    console.log(event.offsetX, event.offsetY);
}

$('svg').click(clicked);

as seen here: https://jsfiddle/1ht0L8y6/6/ have different behaviors in different browsers:

Chrome: The coordinates are based on the top left of the SVG element, no matter where I click inside the SVG. This is the behavior I want.

Firefox: The coordinates are based on the top left of whatever element I'm in, which may be SVG, polygon, or text.

IE and Edge:

  • When in the SVG but not in any of its sub-elements, the coordinates are based on the SVG element.
  • When in a polygon, the coordinates are based on the origin of the <g> group, with its translate offset (i.e., the black diamond). Negative coordinates are possible this way, unlike in Chrome or Firefox.
  • I have observed a different behavior for text elements in these browsers: They would give coordinates based on the bottom middle of the text element. But I couldn't manage to reproduce this in the fiddle; in the fiddle text elements behave the same as polygons in these browsers.

What is a reliable cross-browser way to get the coordinates of the click?

Share Improve this question edited Mar 29, 2019 at 14:45 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Feb 21, 2019 at 4:32 Sam KauffmanSam Kauffman 1,24011 silver badges31 bronze badges 1
  • I can reproduce your problem but I'm afraid it's going to take more time than I have right now to respond to it. You might try this SO answer: stackoverflow./a/30708924/3330613 – MSC Commented Feb 21, 2019 at 5:11
Add a ment  | 

1 Answer 1

Reset to default 17

I've added to your code a function to detect the mouse position in SVG.

let svg = document.querySelector('svg')

function clicked(event) {
  let m = oMousePosSVG(event);
    console.log(m.x,m.y);
}

svg.addEventListener("click", clicked)


function oMousePosSVG(e) {
      var p = svg.createSVGPoint();
      p.x = e.clientX;
      p.y = e.clientY;
      var ctm = svg.getScreenCTM().inverse();
      var p =  p.matrixTransform(ctm);
      return p;
}
svg{border:1px solid}
<div class="container">
  <div class="spacer"></div>
  <svg>
    <g id="polygonGroup" transform="translate(80, 50)">
      <polygon points="-60,-10 -35,-30 -10,-10 -10,30 -60,30"></polygon>
      <polygon points="10,-10 35,-30 60,-10 60,30 10,30"></polygon>
      <polygon class="origin" points="-4,0 0,4 4,0 0,-4"></polygon>
    </g>
    <g id="textGroup" transform="translate(80, 50)" fill="red">
      <text x="-35" y="10">Text</text>
      <text x="35" y="10">Text</text>
    </g>
  </svg>
</div>

To read more about mouse detection in SVG I remend this book: Using SVG with CSS3 and HTML5: Vector Graphics for Web Design

I hope it helps.

发布评论

评论列表(0)

  1. 暂无评论