OrbitControls in THREE.JS fail to function properly when a DOM Element is layered on top of the scene

I am attempting to position labels as elements with position:absolute; over a THREEJS scene. The issue arises when the mouse hovers over one of the labels (the red box in the example below), causing the events that trigger OrbitControls to be "halted" by the labels and not propagate to the Renderer.

I have created a simplified version of the code to showcase the problem.

https://i.sstatic.net/iNQfY.png

<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            margin: 0px;
            overflow: hidden;
        }

        #overlay {
            position: absolute;
            top: 40%;
            left: 40%;
            width: 20%;
            height: 20%;
            background-color: #f00;
            padding: 3%;
            text-align: center;
            color: #fff;
            box-sizing: border-box;
        }
    </style>
</head>

<body>
    <div id="container"></div>

    <!-- This div below stops the OrbitControls events, why? -->
    <div id="overlay">I am a div with position:absolute</div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
    <!-- https://raw.githubusercontent.com/mrdoob/three.js/r87/examples/js/controls/OrbitControls.js -->
    <script src="orbit-controls.js"></script>
    <script>
        var container;
        var camera, scene, renderer;
        var uniforms, material, mesh;
        var controls;
        init();
        animate();

        function init() {
            container = document.getElementById('container');
            var aspect = window.innerWidth / window.innerHeight;
            camera = new THREE.PerspectiveCamera(45, aspect, 0.1, 1500);
            camera.position.set(1, 1, 1);
            scene = new THREE.Scene();
            renderer = new THREE.WebGLRenderer();
            container.appendChild(renderer.domElement);
            renderer.setSize(window.innerWidth, window.innerHeight);
            controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);

            var geometry = new THREE.BoxGeometry(1, 1, 1);
            var material = new THREE.MeshBasicMaterial({
                color: 0x00ff00
            });
            var cube = new THREE.Mesh(geometry, material);

            scene.add(cube);
        }

        function animate() {
            requestAnimationFrame(animate);
            render();
        }

        function render() {
            renderer.render(scene, camera);
        }
    </script>
</body>

</html>

Below is a link to a related project where the labels do not prevent the event propagation, allowing the camera to follow the mouse interaction. I have not yet identified why this example works and mine does not.

How can I ensure that OrbitControls continue to function behind the <div> labels?

Answer №1

Here is a summary of the answers provided in the comments:

If you do not require any mouse-events from the overlays, the simplest solution is to disable event-handling using CSS:

<div class="overlay" style="pointer-events: none">...</div>

Alternatively, you can utilize a shared parent element for event-handling:

<div class="parent" style="position:relative">
  <canvas ... /> <!-- this is the canvas from renderer.domElement -->
  <div class="overlay"></div>
</div>

And for the controls:

const controls = new THREE.OrbitControls(camera, document.querySelector('.parent'));

This method ensures that all mouse-events reaching the parent (including those from the overlays) will be managed by the controls. In cases where you want to handle specific events from the overlays, such as click events, you can prevent them from being forwarded to the orbit-controls by using stopPropagation():

overlayEl.addEventListener('click', event => {
  event.stopPropagation();

  // handle event
});

Answer №2

To implement orbit controls on the background scene, simply follow these steps:

const controls = new orbitControls.OrbitControls(camera, document.body);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When you hover over HTML tables, they dynamically rearrange or shift positions

Issue: I am encountering a problem with multiple tables where, upon hovering over a row, the tables are floating rather than remaining fixed in place. Additionally, when hovering over rows in the first or second table, the other tables start rendering unex ...

EmberJS add item to an object through pushObject

I'm currently working on setting up a property within an object that will also be an object itself. For example, let's say I have a property named 'cities' and I want to assign populations to different cities within this object. cities ...

At times, Mongoose may return null, while other times it returns data frequently

I have designed a unique mongoose schema for managing contacts, with a custom defined ID. Here is the schema structure: const mongooseSchema = new mongoose.Schema({ _id:{ type:String, unique:true, required:true }, firstN ...

Sending data through forms

I'm having trouble storing values input through a dropdown menu in variables event1 and event2, despite trying global declarations. How can I successfully store a value to both variables and pass it to the JavaScript code? Thank you. <!DOCTYPE HT ...

Is there a way to retrieve the dynamically generated text content of an element using document.write?

I am encountering an issue similar to the following: <div id="myDiv"><script>document.write('SOMETHING');</script></div> My goal is to extract the content inside the script tag, which in this case is "SOMETHING" ...

Error: The value "'827'" cannot be assigned to "Course_Content.course_outline_id" as it must be a valid instance of "Course_Outline"

While working on my django view, I encountered an error stating: ValueError: Cannot assign '827': 'Course_Content.course_outline_id' must be a 'Course_Outline' instance. I attempted to convert it to an int but it still didn&ap ...

The TS2769 error occurs when trying to change the react calendar due to no matching overload in the

The calendar functionality in my project was implemented using the response calendar library. Suddenly, I encountered an onChange prop error in the default code. This was working fine before. What steps should I take to resolve this issue? Here is my cod ...

A guide on identifying the data type of a value entered into an HTML table using JavaScript

Currently, I am tackling a contenteditable HTML table challenge. My goal is to enforce the insertion of only numeric values while alerting the user if they attempt to input strings or non-numeric characters. Can anyone provide guidance on how to achieve th ...

Unable to show the company logo in the navigation bar

Working on a pizza site and encountering an issue - trying to add the logo of the place to the navbar (which also links to the main page) but it's not displaying. Using Twitter Bootstrap for this project. Here is the code snippet: /*#557c3e green*/ ...

Attempting to transmit JavaScript information to my NodeJS server

Having some trouble sending geolocation data to NodeJS through a POST request. When I check the console log in my NodeJS code, it's just showing an empty object. I've already tested it with postman and had no issues receiving the data. The probl ...

Staggered Drop-Down Menus

I've created a custom CSS drop-down menu that works well, but I've realized that updating this menu across all the HTML pages on my website would be a tedious task. If I ever need to add a new section and tier to the menu, I'd have to update ...

Tips for Preserving the HTML Page State After Making jQuery Changes

Hi there! I am currently working on developing a card game using HTML5, CSS3, and Javascript. This game will communicate with a server built on node.js, facilitated by socket.io for data transmission. One of the key features I am trying to implement is th ...

What are the benefits of using `observer` over `inject` when passing data to a React component in MobX?

After reading MobX documentation, it appears that using observer on all components is recommended. However, I have discovered that by utilizing the inject method, I am able to achieve more precise control over which data triggers a re-render of my componen ...

The ES6 reduce method is not giving the expected result

In Image 1, the output you will see if you log the final array from Snippet 1. My goal is to transform my array to match the format shown in Image 2. I attempted using lodash's _.uniqBy() method [Snippet 2], but the logged output of the reduce varia ...

Error: Type Error when using custom App and getInitialProps in Next.js

I have a simple app built using the Next JS starter kit, and I am attempting to integrate custom functionality as outlined in the documentation: class MyApp extends App { static async getInitialProps({ Component, router, ctx }) { let pageProps = {}; ...

Error: The program encountered a TypeError because it was unable to read the property 'top' of an undefined element when attempting to click the send

I have been searching for solutions, but none seem to match the requirements of my code. My website has various categories. I encountered an issue while attempting to add a new ad post here. form.find('.info-tooltip-container').addClass(&ap ...

Artistic Canvas: Selected Image

I am trying to determine if the user has clicked on an image drawn in a canvas element. Despite clicking on the image, nothing seems to be happening. The alert function is not being triggered and the last condition in the code never evaluates to true. An ...

What could be causing bundle.js to remain in a pending status on my website?

Whenever I try to open a page from my project, the browser keeps showing loading forever and in the network tab, the status of bundle.js is pending. (Interestingly, if I open other routes of the project, everything works fine). If I remove all product var ...

Tips for customizing the CSS file of a React component imported from a UI framework

As I embark on building a large application utilizing React, I find myself navigating the new territory of React philosophy coming from a background of Css+Js+jQuery methods. One key requirement for my project is a reliable UI framework that aligns with Go ...

The Textfield component in Material UI now automatically sets the default date to the current date when using the "date" type

I am using Material UI's textfield with the type set to "date" and I'm experiencing an issue where the date defaults to the current date instead of mm/dd/yyyy. Is there a way to prevent this behavior and display mm/dd/yyyy when the user loads the ...