Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trigger mouseover event on stacked SVG elements

Tags:

javascript

svg

While the CSS tag pointer-events:none will make an SVG element not be the target of mouse events, only one stacked element can be the target of the event. Is there a simple way to make mouse events target ALL elements that are under the cursor, so that a stacked set of elements will all have their events triggered if the event occurs within their bounding box?

like image 885
sakurashinken Avatar asked Nov 01 '22 10:11

sakurashinken


1 Answers

There is a method on SVGSVGElement (<svg>) called getIntersectionList() which will return all elements that intersect with a given rectangle.

As an example, here is a code snippet which will give every SVG shape under the click a random colour.

var  mysvg = document.getElementById("mysvg");

mysvg.addEventListener('click', function(evt) {

  var  hitRect = mysvg.createSVGRect();
  hitRect.x = evt.clientX;
  hitRect.y = evt.clientY;
  // (leave width & height as 0)
  
  var  elems = mysvg.getIntersectionList(hitRect, null);
  for (i=0; i<elems.length; i++) {
    // Give each element under the mouse a random fill colour
    elems.item(i).setAttribute('fill', "rgb("+rnd()+","+rnd()+","+rnd()+")");
  }
  
});


function rnd() {
  return Math.floor(Math.random() * 255.99);
}
<svg id="mysvg">
  
  <rect width="150" height="100" fill="#393"/>
  <rect x="120" y="20" width="140" height="130" fill="orange"/>
  <rect x="220" y="0" width="80" height="130" fill="red"/>
  
</svg>

Unfortunately, this currently only works in Chrome (maybe Safari also?). Supposedly FF implemented partial support for this, but it currently seems to have been removed.

like image 114
Paul LeBeau Avatar answered Nov 09 '22 10:11

Paul LeBeau