Master_T
Master_T

Reputation: 7987

Konva.js - how to make only Konva objects interactive instead of the entire layer

I'm using Konva.js to draw interactive shapes on top of an existing HTML element on the page, like this:

<div id="mainContainer">
    <div id="otherStuff"></div>
    <div id="konvaContainer"></div>
</div>

where both inner divs are set to position: absolute; so they fill the container and overlap each other.

I'm then initializing Konva and drawing a shape like this:

const stage = new Konva.Stage({
    container: konvaContainer,
    width: konvaContainer.clientWidth,
    height: konvaContainer.clientHeight,
});

const layer = new Konva.Layer();
stage.add(layer);

const circle = new Konva.Circle({
    radius: 50,
    fill: 'red',
    draggable: true,
    x: stage.width() / 2,
    y: stage.height() / 2,
});
layer.add(circle);

The behavior I'm looking for is for the circle I've drawn to respond to mouse interactions (click, drag, etc.), but everywhere else on the stage (where there are no shapes) should be "transparent" to the mouse. In other words: the events should pass through and hit the underlying otherStuff div.

Is this possible?

Upvotes: 0

Views: 32

Answers (1)

lavrton
lavrton

Reputation: 20363

There is no official Konva API to do that. The workaround is:

  1. Add konva stage with absolute position
  2. Set pointer-events: none; on stage container so it will be "transparent" for any pointer events
  3. Manually proxy events from the main content into Konva stage

You may need to prevent the default behavior of the browser when drag&drop of konva is started, so it prevents selection of text.

const stage = new Konva.Stage({
    container: 'konvaContainer',
    width: window.innerWidth,
    height: window.innerHeight,
});

const layer = new Konva.Layer();
stage.add(layer);

const circle = new Konva.Circle({
    radius: 50,
    fill: 'red',
    draggable: true,
    x: stage.width() / 2,
    y: stage.height() / 2,
});
layer.add(circle);


const main = document.querySelector('#mainContainer');

// "proxy" all DOM events from canvas into Konva engine
var EVENTS = [
  'mouseenter',
  'mousedown',
  'mousemove',
  'mouseup',
  'wheel',
  'contextmenu',
  'pointerdown',
  'pointermove',
  'pointerup',
  'pointercancel',
  'lostpointercapture',
];
EVENTS.forEach((eventName) => {
  main.addEventListener(eventName, (e) => {
  // pass incoming events into the stage
   const event = eventName.replace('mouse', 'pointer');
   if (!stage['_' + event]) {
     console.log(event);
   }
   stage['_' + event](e);
  });
});
#mainContainer {
  position: relative;
}

#konvaContainer {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}
<script src="https://unpkg.com/konva@9/konva.min.js"></script>

  <div id="mainContainer">
    <div id="otherStuff">Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here.Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here.Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here.Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here.Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here.Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here. Some random text is here.Some random text is here. Some random text is here. Some random text is here</div>
    <div id="konvaContainer"></div>
</div>

Upvotes: 0

Related Questions