Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture mouse events from sibling or parent DOM element in PIXI.js

I would like to capture mouse events on two layers: PIXI's canvas and and overlaying div. I have the following kind of HTML setup where div.overlay is above canvas.pixi:

<div class="parent">
  <canvas class="pixi"></canvas>
  <div class="overlay"></div>
</div>

PIXI interaction work fine when the canvas is on top but I am unable to capture any events when the canvas is overlaid with div.overlay.

I found setTargetElement which seem to let us define the DOM element for capture elements and I tried to use it like so:

const renderer = PIXI.autoDetectRenderer(...);
renderer.plugins.interaction.setTargetElement(document.querySelector('.overlay'));

Using this technique I am able to capture mousemove events but unfortunately click, mousedown, etc. do not work.

I've also tried to copy the original events captured on div.overlay and duplicate ans dispatch the events on canvas as shown below but that also doesn't do the trick.

document.querySelector('.overlay').addEventListener('mousedown', (e) => {
  const eventCopy = document.createEvent('MouseEvents');
  eventCopy.initMouseEvent(
    e.type, e.bubbles, e.cancelable, e.view,
    e.detail, e.pageX || e.layerX,
    e.pageY || e.layerY, e.clientX,
    e.clientY, e.ctrlKey, e.altKey, e.shiftKey,
    e.metaKey, e.button, e.relatedTarget
  );

  document.querySelector('.pixi').dispatchEvent(eventCopy);
});

Is there any way to capture mouse events on an overlaid DOM element and to pass the events to PIXI?

Why?

I would like to interact with PIXI elements while at the same time being able to utilize D3's zoom and brush functionality, which is currently being handled on the overlaying div.

Update & Code Example

I managed to forward events and all but click events are registered by PIXI. Click events can be manually triggered by re-firing pointerdown and pointerup events. Check out https://jsfiddle.net/v3chhhjk/1/

like image 761
F Lekschas Avatar asked Dec 01 '17 01:12

F Lekschas


1 Answers

For people visiting this page, but want PIXI to be the overlay, over a still interactive underlying layer. Then you can still use the example from @F Lekschas with a small modification.

Set pointer-events: none on the parent, then pointer-events: all on the underlay and then forward events from the underlay to the PIXI canvas, like in the example.

I was pulling my hair out over this one. I was running into all kind of problems forwarding events from the parent to the underlay, but forwarding events from the underlay to the PIXI canvas works like a charm.

like image 58
karel Avatar answered Sep 19 '22 16:09

karel