admin管理员组

文章数量:1401183

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 plex!

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!

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 plex!

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!

Share Improve this question edited Aug 4, 2015 at 14:01 WestLangley 105k11 gold badges287 silver badges283 bronze badges asked Aug 4, 2015 at 7:11 lindsaylindsay 9722 gold badges11 silver badges23 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3
  1. Try to set a planemesh/mesh to the desired point.
  2. Copy the position of the css elements (domElements created with three.js cssObject [if you already know]) along with planemesh/mesh 's position.

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!

本文标签: javascriptTHREEjs SphereGeometry Panorama hotspots using DOMElementsStack Overflow