Interact with two canvas in top of each other

Hi, I need to have two separate canvas (Babylon) on top of each others where both can be interact with. At the moment, I’m having issue because the inputs are only detected on the top one while I need to interacts with both of them at the same type. Both of them are only using the BABYLON GUI .

Is there a way to make that possible? I saw that some people suggest to use pointer-event : none but I’m not quite sure how it work or if it could be the solution to my problem.

Thanks

That’s quite an interesting scenario :slight_smile: First of all, why would two canvas one on top of the other be needed? Couldn’t the same thing be done using multiple cameras Layer Masks and Multi-Cam Textures | Babylon.js Documentation (babylonjs.com) or even multiple scenes? Using Multiple Scenes | Babylon.js Documentation (babylonjs.com).

If the two canvases are really a necessity, then you’ll need to implement some custom event handling. You’ll have to listen for events on the top canvas and then replay them on the bottom one.

2 Likes

I can’t really say much about the why :sweat_smile: but the canvas are not the same. These are two separate babylon project running on the same page on top of each other. Im currently trying to find a way to have both inputs triggered from the top canvas and the bottom canvas…

@carolhmj I’m currently able to click on any html element behind the canvas itself which is good, however, even if I’m able to send events to the other canvas, the elements within this canvas do no understand. Do you have any new suggestions ? :slight_smile:

public sendEventDispatcher(): void {
	this.scene.onPointerObservable.add((pointerInfo) => {
		const eventType = this.convertEventTypeToHTMLEvent(pointerInfo);

		if (eventType !== '') {
			const elms = document.elementsFromPoint(pointerInfo.event.x, pointerInfo.event.y);
			for (var i = 1; i < elms.length; i++) {
				if (!elms[i].contains(elms[0])) {
					(elms[i] as HTMLElement).dispatchEvent(new PointerEvent(this.convertEventTypeToHTMLEvent(pointerInfo)));
					break;
				}
			}
		}
	});
}

private convertEventTypeToHTMLEvent(pointerInfo: PointerInfo): string {
	switch (pointerInfo.type) {
		case PointerEventTypes.POINTERDOWN:
			return 'pointerdown';
		case PointerEventTypes.POINTERMOVE:
			return 'pointermove';
		case PointerEventTypes.POINTERUP:
			return 'pointerup';
		default:
			return '';
	}
}
1 Like

@PolygonalSun do you know if there is any issue with receiving events through dispatchEvent?

As far as I understand, dispatchEvent should be usable to send an event to any HTMLElement. I could see this not working if the recipient canvas doesn’t have any event listeners added to it. If any canvases don’t have controls attached to them, the event listeners that we use won’t be added in order to handle those dispatched events.

Without know what the code looks like, it’d be difficult to say what’s going on, but I’d at least recommend manually adding an event listener to the other canvases to see if they’re picking up your dispatched events.

Hello @Rangerz132 just checking if you still have questions?

Hello! My team and I figured a way to make it work even if it is not the prettiest way for now. Thanks!

1 Like