I've created a simple WebGL 3D Panorama application using a SphereGeometry
, PerspectiveCamera
and a CanvasTexture
. Now, I'm looking to bring the scene to life by adding "HotSpots" over certain parts of the SphereGeometry
. The problem I'm having is understanding how to update the various DOMElements
so that their position is reflective of the updated Camera
position.
Basically, as the Camera
rotates the various DOMElements
would move in and out of view relative to the direction the camera is spinning. I tried positioning a <div>
absolute
to the <canvas>
and translating
the X
and Y
position using the returned PerspectiveCamera
camera.rotation
but it didn't really work; here's my JS & CSS implentation:
CSS
#TestHotSpot {
/* not sure if using margins is the best method to position hotspot */
margin-top: 50px;
margin-left: 50px;
width: 50px;
height: 50px;
background: red;
position: absolute;
}
JavaScript
/**
CONFIG is my stored object variable; it contains the PerspectiveCamera instance
code is being called inside of my RequestAnimationFrame
**/
config.camera.updateProjectionMatrix();
config.controls.update(delta);
document.getElementById("TestHotSpot").style.transform = "translate("+ config.camera.rotation.x +"px, "+ config.camera.rotation.y +"px)";
Here is also a live example of the desired effect.
What would be the best solution to fix this problem? What I noticed when I ran this that the DOMElements
would only slightly move; I also noticed that they wouldn't really take in account where along the SphereGeometry
they were placed (for example, being positioned "behind" the Camera
; really complex!
I'm happy to use any plugins for the THREE.js
engine as well as follow any tutorials. Thank you so much for replying in advance!
And you will be done !!
Okay, chiming in on my own question! I had a few problems but I've figured out how to get CSS3d mixing in with THREE.js WebGL scenes.
So the first thing I had to do was update my THREE.js Library; I was running 71 from an earlier download but I needed to update it to the library Mr.Doob was using in this example. I also updated my CSS3d library to the file included in that same example.
I then used this method (the same specified in the link) to create a demo scene.
var camera, scene, renderer;
var scene2, renderer2;
var controls;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 200, 200, 200 );
controls = new THREE.TrackballControls( camera );
scene = new THREE.Scene();
scene2 = new THREE.Scene();
var material = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, wireframeLinewidth: 1, side: THREE.DoubleSide } );
//
for ( var i = 0; i < 10; i ++ ) {
var element = document.createElement( 'div' );
element.style.width = '100px';
element.style.height = '100px';
element.style.opacity = 0.5;
element.style.background = new THREE.Color( Math.random() * 0xffffff ).getStyle();
var object = new THREE.CSS3DObject( element );
object.position.x = Math.random() * 200 - 100;
object.position.y = Math.random() * 200 - 100;
object.position.z = Math.random() * 200 - 100;
object.rotation.x = Math.random();
object.rotation.y = Math.random();
object.rotation.z = Math.random();
object.scale.x = Math.random() + 0.5;
object.scale.y = Math.random() + 0.5;
scene2.add( object );
var geometry = new THREE.PlaneGeometry( 100, 100 );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.copy( object.position );
mesh.rotation.copy( object.rotation );
mesh.scale.copy( object.scale );
scene.add( mesh );
}
//
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer2 = new THREE.CSS3DRenderer();
renderer2.setSize( window.innerWidth, window.innerHeight );
renderer2.domElement.style.position = 'absolute';
renderer2.domElement.style.top = 0;
document.body.appendChild( renderer2.domElement );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
renderer2.render( scene2, camera );
}
After I had that working, I re-purposed the CSS3d scene
, CSS3d object
and the CSS3d renderer
to be included in my scene.
Good luck to anyone else and hopefully this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With