javascriptkonvajskonva

How can I suppress a click on a konva shape after a contextmenu click?


I have two handlers assigned to a konvajs shape with the shape's on function. They respond to the 'click' event and 'contextmenu' event. After it responds to a 'contextmenu' event, a 'click' event is also emitted. I want to suppress the 'click' event if there is a 'contextmenu' event. How can I do that?

I have tried using:

e.evt.preventDefault();
e.evt.stopPropagation();
e.cancelBubble = true;

but that does not work.

const width = 400;
const height = 300;

const stage = new Konva.Stage({
      container: '.static-canvas', 
      width: width, 
      height: height
});

const layer = new Konva.Layer();

const pentagon = new Konva.RegularPolygon({
      x: stage.getWidth() / 2,
      y: stage.getHeight() / 2,
      sides: 5,
      radius: 70,
      fill: 'red',
      stroke: 'black',
      strokeWidth: 4
});

layer.add(pentagon);
stage.add(layer);

pentagon.on( 'click', (e) => {
    e.evt.preventDefault();
    e.evt.stopPropagation();
    e.cancelBubble = true;
    console.log( 'click' ) 
});

pentagon.on( 'contextmenu', (e) => {
    e.evt.preventDefault();
    e.evt.stopPropagation();
    e.cancelBubble = true;
    console.log( 'contextclick' );
});
body {
  margin: 0;
  padding: 0;
  background-color: #F0F0F0;
}
.canvas {
    float: left;
    width: 50%; 
}
.static-canvas {
    .konvajs-content {
        background: orange;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/9.0.0/konva.min.js"></script>
<div class="canvas static-canvas"></div>


Solution

  • To handle this properly, you should filter the event based on the event's button code.

    Even if both click and contextmenu are fired, you can ignore the right-click by checking e.evt.button. The right-click event is identified when button === 2.

     pentagon.on("contextmenu", (e) => {
            e.evt.preventDefault();
            e.evt.stopPropagation();
            e.cancelBubble = true;
            console.log("contextclick");
     });
    
     pentagon.on("click", (e) => {
            const isRightClick = e.evt.button === 2;
            if (!isRightClick) {
              e.evt.preventDefault();
              e.evt.stopPropagation();
              e.cancelBubble = true;
              console.log("click");
            }
     });
    

    More details here:

    https://github.com/konvajs/konva/issues/1854