从 PIXI.js 中的同级或父 DOM 元素捕获鼠标事件



我想在层上捕获鼠标事件:PIXI的画布和叠加div。我有以下类型的 HTML 设置,其中div.overlay高于canvas.pixi

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

canvas位于顶部时,PIXI 交互工作正常,但当画布覆盖div.overlay时,我无法捕获任何事件。

我发现了setTargetElement似乎让我们为捕获元素定义 DOM 元素,我尝试像这样使用它:

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

使用这种技术,我能够捕获mousemove事件,但不幸的是clickmousedown等不起作用。

我还尝试复制div.overlay捕获的原始事件,并复制并在canvas上调度事件,如下所示,但这也不能解决问题。

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);
});

有没有办法在覆盖的 DOM 元素上捕获鼠标事件并将事件传递给 PIXI?

为什么?

我想与 PIXI 元素进行交互,同时能够利用 D3 的缩放和画笔功能,该功能目前正在叠加div 上处理。

更新和代码示例

我设法转发了事件,除了点击事件之外,所有事件都由 PIXI 注册。点击事件可以通过重新触发pointerdownpointerup事件来手动触发。退房 https://jsfiddle.net/v3chhhjk/1/

一种可能的解决方案是捕获父元素的所有事件并将其遍历回子元素。喜欢这个。这是为点击完成的,同样适用于鼠标移动。

function traverseEventToChild(e){
	if(e.type="click"){
	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
	);
console.log('parent handler');
	document.querySelector('.pixi').dispatchEvent(eventCopy);
}
}
function piximousemove(e){
	console.log('pixi click');
e.stopPropagation();
}
function overlaymousemove(e){
	console.log('overlay click');
}
document.querySelector('.pixi').onclick = piximousemove;
document.querySelector('.overlay').onclick = overlaymousemove;
<div class="parent" id='parent' onclick="traverseEventToChild(event);">
<canvas class="pixi" id='canvas'>pixi</canvas>
<div class="overlay" id='overlay'>overlay</div>
</div>

对于访问此页面但希望 PIXI 成为叠加层的用户,覆盖在仍然交互式的底层之上。然后,您仍然可以使用@F Lekschas中的示例,并进行一些修改。

设置指针事件:父级上无,然后设置指针事件:全部在底层图上,然后将事件从底层转发到 PIXI 画布,如示例中所示。

我把头发拉到这个上面。我在将事件从父层转发到底层时遇到了各种问题,但是将事件从底层转发到 PIXI 画布就像一个魅力。

如果你只需要通过覆盖层传递事件 - 使用 csspointer-events: none;.
更多详情请见:https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events

问题是 DOM 是分层的。这是一个关于完全相同的事情的旧问题。事实证明,你不能简单地将事件传播给兄弟姐妹,只能将父母和孩子传播。我建议把你的canvas放在.overlay里面,然后你既可以捕捉它,也可以在冒泡阶段捕捉它,这取决于你是想在画布之前还是之后处理那些。

我认为以下内容应该按预期工作。

.HTML:

<div id="parent">
<div id="overlay">
<canvas></canvas>
</div>
</div>

示例 JS:

(function() {
let parent = document.getElementById('parent');
let overlay = document.getElementById('overlay');
let canvas = document.querySelector('canvas');
parent.addEventListener('click', e => console.log('parent capture'), true);
overlay.addEventListener('click', e => console.log('overlay capture'), true);
canvas.addEventListener('click', e => console.log('canvas capture'), true);
canvas.addEventListener('click', e => console.log('canvas bubble'), false);
overlay.addEventListener('click', e => console.log('overlay bubble'), false);
parent.addEventListener('click', e => console.log('parent bubble'), false);
})()

我通过克隆事件并从mousedownmouseup事件中重建click事件,让它适用于mouseovermouseoutmousedownmouseupclick事件。从事件层克隆事件时,除click事件外,所有事件都可以开箱即用,但不知何故,单击事件不会触发。

因此,给定以下HTML结构:

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

我听了一堆这样的事件:

const overlay = document.getElementById('overlay');
overlay.addEventListener('pointerdown', forwardDown);
overlay.addEventListener('pointerup', forwardUp);
overlay.addEventListener('pointermove', forward);
overlay.addEventListener('pointerover', forward);
overlay.addEventListener('pointerout', forward);

然后转发/克隆事件:

const canvas = document.getElementById('pixi');
let mousedown = false;
const clone = e => new e.constructor(e.type, e);
const forward = (e) => { canvas.dispatchEvent(clone(e)); };
const forwardDown = (e) => { mousedown = true; forward(e); };
const forwardUp = (e) => {
forward(e);
if (mousedown) console.log('It's a click!');
mousedown = false;
};

例如,该事件也可以发送到其他地方,例如 D3 可以识别。

演示:https://jsfiddle.net/v3chhhjk/3/

左上角演示了使用 PIXI 直接捕获事件时它的工作原理。右上角显示了克隆事件时的问题。左下角显示了一种奇怪的行为,其中重新触发相同的事件实际上使PIXI识别点击事件,最后是右下角。

相关内容

  • 没有找到相关文章

最新更新