user3057661
user3057661

Reputation: 21

nested/concentric group and mouseenter/mouseleave

I've been having some trouble with adding an event listener to a concentric group of circles. My intended functionality is this: when the mouse is over the group, a new black dot (a "Bullseye" -- circle3 in the code below) should appear at the center of the group. When the mouse is not above the group, black dot should not appear.

The following code comes close to accomplishing this:

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.4.min.js"></script>
    <script defer="defer">

var stage = new Kinetic.Stage({
    container: 'container',
    width: 578,
    height: 200
});

var layer = new Kinetic.Layer({});
var group = new Kinetic.Group({
    x: 0, // 
    y: 0 //

}); 


var circle = new Kinetic.Circle({
    x: stage.getWidth() / 2,
    y: stage.getHeight() / 2,
    radius: 70,
    fill: 'red',
    stroke: 'black',
    strokeWidth: 4
});
var circle2 = new Kinetic.Circle({
    x: stage.getWidth() / 2,
    y: stage.getHeight() / 2,
    radius: 50,
    fill: 'white',
    stroke: 'black',
    strokeWidth: 4
});


var circle3 = new Kinetic.Circle({
    x: stage.getWidth() / 2,
    y: stage.getHeight() / 2,
    radius: 20,
    fill: 'black',
    stroke: 'black',
    strokeWidth: 4,
    visible: false
});



group.add(circle); 

group.add(circle2); 

group.add(circle3); 

group.on("mouseenter", function(event){ 
    circle3.setVisible(true);
    stage.draw();
}); 


group.on("mouseleave", function(event){ 
    circle3.setVisible(false); 
    stage.draw(); 
}); 


// add the shape to the layer
layer.add(group);

// add the layer to the stage
stage.add(layer);


    </script>
  </body>
</html>

However, the problem is that "bulleye" flickers as it leaves the outercircle (circle) and enters the inner circle (circle2).

(*) I have tried various solutions -- but nothing seems to be working. For one, I tried to capture the mouseposition (layerX and layerY) and detect a collision with the group region on the canvas. That is, if x and y are within its boundaries, I paint the bullseye. Otherwise, I get rid of it. However, the problem with this solution is that the bullseye is sometimes orphaned in the group even if the mouse has left the group. That is because the mouseout/mouseleave event sometimes has a layerX or layerY position that is still within the circle.

(*) Using mouseover and mouseout instead of mouseenter/mouseleave doesn't seem to affect anything.

(*) I can't add the eventlistener to the outer circle alone, since that makes the bullseye disappear when the mouse is over the innercircle.

Upvotes: 2

Views: 109

Answers (1)

Noah Heldman
Noah Heldman

Reputation: 6874

You can prevent the flickering by turning off event listening for the nested circles, like so:

group.add(circle); 
group.add(circle2); 
group.add(circle3); 

// Don't listen for any events (e.g. mouseenter/leave) on the inner circles
circle2.setListening(false);
circle3.setListening(false);

It fixes the issue you describe, but I'm not sure if you need to listen for other events on those circles... If so, you may need to cancel propagation of events from the inner circles.

Upvotes: 1

Related Questions