What is the best way to superimpose text and buttons over a three.js scene

Hey there, I'm diving into the world of three.js and I'm on a mission to recreate the awesome interactive 3D experience that Google has with their game at

Check it out - they have this cool Three.js scene taking up the entire screen with text and buttons seamlessly placed on top (which are clearly HTML divs, not generated via JS)

I've checked out some resources like

and similar questions but I'm struggling to figure out the right approach. I really don't want to create my UI elements in Three.js - I simply want to use regular HTML.

So far, I've created my Three.js canvas and added it to my document so it fills the full width/height of my window:

var controls, camera, renderer, scene, container, w, h;
renderer    = new THREE.WebGLRenderer()
// container = document.getElementById('canvas');
container = window;
w = container.innerWidth;
h = container.innerHeight;
renderer.setSize(w, h)
renderer.setPixelRatio( window.devicePixelRatio );
document.body.appendChild(renderer.domElement);

And then, using my existing HTML:

<body>
    <div id="ui">
    <p id="message">Test to change</p>
</div>

I find that the UI div stays on top no matter how I adjust the CSS or z-index:

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

How can I achieve the same effect as Google with HTML overlaid on my three.js scene? What am I missing?

I really want my canvas to fill the whole window just like Google's does but I'm struggling to make it happen by creating the canvas element beforehand and trying to attach everything through JS.

Answer №1

There are countless paths to unlock your creativity and achieve the desired outcome.

One starting point is exploring the source code of various examples on Three.js' official website. By analyzing how the info section is implemented in these examples, you can gain valuable insights for your own projects.

var buttons = document.getElementsByTagName("button");
for (let i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener("click", onButtonClick, false);
};

function onButtonClick(event) {
  alert(event.target.id);
}

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

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

camera.position.z = 5;

var animate = function() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
};

animate();
body {
  overflow: hidden;
  margin: 0;
}

.ui {
  position: absolute;
}

button{
  margin: 20px;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

<div style="width:100%;height:50px;text-align: center; color:white;" class="ui">Info header</div>
<button style="top:0" id="fire" class="ui">Fire</button>
<button style="bottom:0" id="spell" class="ui">Spell</button>
<button style="right:0" id="health" class="ui">Health</button>
<button style="right:0; bottom:0;" id="shield" class="ui">Shield</button>

Answer №2

The z-index property is effective only when used in conjunction with the position property, except for scenarios where position: static or position: initial are applied.

I found that this button class worked perfectly within my threejs scene. Feel free to adjust the values of left and top as needed.

.button {
    position: absolute;
    display: block;
    z-index: 99;
    left: 50%;
    top: 50%;
}

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

Is it possible to compare escaped data with the unescaped value of a select box in JavaScript?

On my webpage, I have a functionality that involves fetching select box options through an AJAX request. I then create the select box based on this data, and later use the selected option to retrieve additional information from the response received via AJ ...

Allow all images on the webpage to be easily dragged and dropped into a designated upload section

I am in the process of developing a browser extension that allows users to save images from web pages into their favorites, similar to Pinterest. The functionality involves clicking on the extension icon which adds a special field to the HTML where users c ...

Ways to extract information from an HTML response following a GET request

Attempting to retrieve data from a request on a NASA webpage has proven challenging as the information is not coming through easily for me. Initially, I inputted the longitude and latitude on this page, , only to receive an HTML response containing all the ...

Ensure that test cases in Angular2 include a line that covers conditions for returning values

I'm having trouble implementing test coverage for an online platform, as I'm not sure how to approach it. Within my service method, I have the following code: public getResults() { return this.http(url,body).map(this.mapResponse); } private ...

What steps can I take to fix the problem of Expo Go crashing on my Android device?

For the past 3 days, the Expo Go Android app version 2.28.4 has been crashing every time I try to start it. This issue is preventing me from testing my Expo apps on physical devices, as they work fine on simulators. Even the app that I published on Expo ...

Experience the power of dynamic site regeneration with GatsbyJS

Currently, I am working on a website built in GatsbyJS that deals with large datasets of dynamic content fetched using React fetch upon page load. The challenge here is to display semi-live data that updates every 5 minutes. I am curious about how I can m ...

In Python with Selenium, the ability to expand and collapse functionality will only be available if the button

I have a website where I want to be able to click and open a collapse/expand window. I only want to open it if it's currently closed; otherwise, I want to proceed with the next operation. Can anyone provide me with the response or key that I need to i ...

How can I maintain the consistent speed of the Javascript timer even when the .deck is clicked?

Currently, I'm working on creating a memory card game. In this game, the deck of cards is represented by the class .deck. Strangely enough, every time I click on a card, the timer starts to speed up instead of keeping a consistent pace. How can I tack ...

The clash between React Inline styles and Client CSS can lead to conflicts in styling

Our application needs to be loaded into the client's page, which is built using React. We are implementing React Inline Styles by defining styles as objects. However, we have encountered an issue where any CSS specified by the client using tag attribu ...

The value of the bound variable in ng-options does not get updated after the array is

I have a situation where I am populating a list using an array and the ng-options directive in AngularJS. The selected item is bound to a variable called myObject.selectedItem. However, I noticed that even after clearing the array, the value of myObject.se ...

Is it possible to use setState after a setTimeout to unmount a component?

Can anyone help me find the issue with my code? I am attempting to clear an error message after a specific duration, but it's not working as expected. I'm puzzled about what might be causing this problem. export default class MyError extends Com ...

Having trouble with JQuery in JADE?

I recently attempted to create a slideshow for my website, but it appears that my JQuery code is not functioning as expected. Here's the code snippet I used: div#slideshow img(src="/images/img1.png") img(src="/images/ ...

Running multiple web applications with different base directories on a single Express server

I am currently working on serving a website that requires different static directories for various routes. When a GET request is sent to the /tools* route, I want to utilize the /dist/toolsApp/ directory as the base directory for my frontend code. If ...

Using AJAX to dynamically inject a JavaScript function into the webpage

When I load a portion of a page using AJAX calls, sometimes the loaded content may contain script functions attached to controls with different events. The issue arises when these events are triggered, resulting in an error message saying "object not found ...

Using an Array as a prop in a React component: A step-by-step guide

Currently, I am in the process of learning React by building a website to gain more familiarity with it. As part of my project, I have been experimenting with the "use-dencrypt-effect" npm package. However, I encountered an issue where setting its values v ...

An error occurred at line 120 in the index.js file of the http-proxy library: "socket hang up"

I encountered an issue while running expressJS in one of the containers within docker-compose. When I repeatedly refresh the landing page by pressing CMD+R (approximately every 3-4 seconds), it displays an error message "Error: socket hang up" causing the ...

Is there a way to switch tabs through programming?

Is there a way to switch between tabs using jQuery or JavaScript when using the tabbed content from ? I have tried using $("tab1").click(); I have created a fiddle for this specific issue which can be found at: https://jsfiddle.net/6e3y9663/1/ ...

Applying CSS styling to PHP documents

I am a beginner, so please go easy on me. I am looking to style variables like $product_name, $author, and $details. I was thinking of styling the echos, but in this scenario, the only echo is: <?php // Establish connection with the MySQL database ...

What status code should be used to redirect a request from one valid endpoint to another valid endpoint?

In my system, there are two main components: projects and proposals. Each proposal can exist in one of three states - pending, approved, or rejected. A project is always associated with a previously approved proposal. The API endpoint for proposals (/pro ...

JQuery Form Validation - Detecting Input Changes

Currently, I have a form set up with jQuery validation that works well, but I want to enhance its functionality. The form uses a plugin for validation, but it only checks for errors upon submission. I'm interested in finding a way to validate the fiel ...