Making Mouse Event Listeners and GUI work together

I have a program with a subroutine that allows you to orbit an object by holding down a mouse button and moving the mouse - similar to how OrbitControls works. In order to listen for mouse events, the program includes the following three lines - which I believe are fairly standard:

renderer.domElement.addEventListener("mousedown", onMouseDown, false);
renderer.domElement.addEventListener("mouseup", onMouseUp, false);
renderer.domElement.addEventListener("mousemove", onMouseMove, false);

I am attempting to add some basic GUI inputs to the program and everything looks okay. However, the GUI does not appear to be receiving input. I suspect that my mouse event listeners are the problem.

If there a way to make these compatible?

From what I have read, OrbitControls was modified in recent years so that it does not interfere with GUI input.

Some older programs appeared to have a variation of the following for GUI:

document.getElementById('gui').appendChild(gui.domElement);

But that doesn’t seem to work.

So it appears that there are 3 possible solutions:

  1. Make my mouse event listeners inoperative when the pointer is over the GUI control panel area,
  2. Make GUI inputs take precedence over my mouse events.
  3. Give GUI a separate input (as above) - but that seems less helpful since GUI inputs would also cause orbit changes.

I have checked other questions posted on this board and they are not quite the same. One involved a “fake” GUI and others involve OrbitControls, TrackBallControls and Raycasting, none of which I am using.

The test GUI code that I am using is this:

var gcontrols = {
        Month: 6,
        DayMo: 15,
        Viewpoint: "Level"};

var gui = new dat.GUI();
var folder = gui.addFolder("Date");
	folder.add(gcontrols, "Month").min(1).max(12).step(1).name("Month").listen();
	folder.add(gcontrols, "DayMo").min(1).max(31).step(1).name("Day").listen();
	folder.add(gcontrols, "Viewpoint", ["Level", "Earth", "Fixed"] ).name("View").listen();
	folder.open();

EDIT
Here is a link to the Program.

Just this morning I used the ‘enabled’ property to temporarily disable OrbitControls. Maybe use a mouse0ver mouseOut event on the dat.GUI div to set this property?

I added a link to my test program.

When you say “div”, does that mean that the GUI should be referenced by a div command in the HTML? I have not seen anyone do that. Does GUI send out a signal when the pointer is over the GUI input area?

BTW - You may not have to disable OrbitControls. There is an excellent article online about “Rendering on Demand”. The last example shows OrbitControls and a sample GUI working well together. I assume that they would work together even if you were rendering all the time.

Don’t know if you ‘should’, but you could. In my case I have a key event for showing/hiding the dat.Gui.I enable/disable the OrbitControls accordingly.

That’s interesting. So the program automatically creates a div structure for GUI?
What command would I use to capture such a mouseOver mouseOut event?
Although I have been writing simple html programs for decades, I have never used GUI before, so this is new territory for me.

Also, as I am thinking what would make sense for this particular program - it seems that the kind of input that would work best is a vertical “roller”, something like the interface you use to set your alarm on an iphone. I’m not sure if that is available as a GUI. I could create a 3D model of one, but would have to figure out how to use the mouse to interact with it. Again, new territory.

What browser are you using? If am using Chrome and it does not appear to provide that amount of detail about the GUI div.

I think you should be able to get the div with something like:

var guidiv= document.querySelectorAll(‘[class=“dg main a”]’);

Then add a mouseover event to the div:

guidiv.addEventListener(“mouseover”, myScript );

The screenshot is from Edge Chromium, but Chromium can do the same

Shouldn’t you just use a calendar control instead?: Calendar input for dat.gui - Stack Overflow

That’s a great suggestion for the calendar input.

I tried adding the commands above and it didn’t get past the first without a syntax error. Looking at the elements, whenever I used that command, the div gui element was never formed. So I assume that the error was telling me that. Just in case it was a matter of the program needing time to create the div, I moved the commands to after my initialize section - which involves creating shapes and loading textures. But still no luck.

Regarding the second command, what should I be telling the listener to do (i.e. the myScript)? Turn off my other mouse listeners?

EDIT
Now that I think about it, I have used buttons in the past without any problem. Perhaps I will switch to something like that - if I can. A set of small buttons next to the items that I want to change.

Okay, I got the first command working by switching the " and ', like this:

var guidiv = document.querySelectorAll("[class='dg main a']");

But it still gets hung up on the second command.

EDIT
In the first command, it wasn’t the order of the " and the '. It works either way. I simply had to retype them - the program was not reading them correctly.

In the second command (after retyping everything), the error message I am getting is that guidiv.addEventListener is not a function.

Yes, guidiv is an element list, use guidiv[0].addEventListener

Okay, I found the problem.

I was correct in that something was blocking input from getting to the GUI, but wrong as to what it was.

While trying different variations of your suggestions, I noticed that if I replaced:

renderer.domElement.addEventListener("mousemove", onMouseMove, false);

with:

document.addEventListener("mousemove", onMouseMove, false);

that mouse moves would be recognized over the entire screen, whereas with the original command, they were not. In other words, with the original command, the mouse “respected the GUI”.

Except that wasn’t quite true. Playing around, I realized that the mouse was “respecting” an area that was a lot larger than the GUI. I turns out that, in designing the overlays required to print things on the screen, I had one overlay at the top that was 100% wide. (I did this to try to make the printed items look okay on a narrow iPhone screen.) So the mouse was respecting the overlays. But that was also blocking the GUI from getting any input. Once I changed the width of the top overlay to 50%, the GUI worked fine.

So it was very helpful that you showed me that the GUI program creates an html div element. I had previous situations where my overlays interfered with each other or with other div elements. As a result, I design my overlays so that they don’t share the same vertical space (just in case they are squeezed together by a narrow iPhone screen). The best fix here would be for me to leave my overlays alone and move the GUI element to the lower part of the screen - where there is no overlay. Or I might eventually replace my top overlay with a GUI.

Thanks for all your help in solving this mystery. I learned a lot.

2 Likes