Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overlay HTML text/buttons on three.js?

Ok, very new to three.js here but I am trying to achieve what Google has with https://beinternetawesome.withgoogle.com/interland

See - they have their FULL SCREEN Three.js scene and their text, buttons (which are clearly HTML divs, not generated via JS) overlaid perfectly on top.

I have looked at https://discourse.threejs.org/t/trying-to-overlay-a-button-and-text-on-top-of-a-three-js-scene/390/2

and similar Questions but can't understand the proper way to do this. I don't want to generate my UI elements in Three.js - I just want to use HTML.

What I have so far is I generate my Three.js canvas and add it to my document so that it gets and STAYS 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 with my existing HTML:

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

I get the UI div stuck on top, no matter how I play with the CSS or the z index of the UI div:

enter image description here

How can I achieve the Google effect with HTML overlaid over my three.js scene? What am I doing wrong?

I need my canvas to fill the whole window just as Google's does and can't achieve that it seems making the canvas HTML element beforehand and trying to attach everything in JS.

like image 360
blue Avatar asked Nov 15 '17 01:11

blue


2 Answers

Creativity is up to you, as there are many ways to achieve the desired result.

You can start from looking at the source code of examples from the official web site of Three.js. There you can see how the info section of an example sets on a web page.

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>
like image 113
prisoner849 Avatar answered Sep 19 '22 10:09

prisoner849


z-index only works with position property except for the case position: static and position: initial.

This button class worked fine with my threejs scene. You can edit left, top accordingly.

button {
    position: absolute;
    display: block;
    z-index: 99;
    left: 50%;
    top: 50%;
    }
like image 29
Utkarsh Zaveri Avatar answered Sep 20 '22 10:09

Utkarsh Zaveri