I'm looking at two examples, one is canvas interactive objects and the other is mouse tooltip. I tried combining the two to generate text labels on each individual cube and here's what I have so far.
However, the text moves with the rotating cubes and the text appears backwards or sideways at times.
How can I make the text fixed in a sprite like in the mouse tooltip (http://stemkoski.github.io/Three.js/Mouse-Tooltip.html) example? I tried to incorporate the sprite but I kept getting errors. I'm not sure how to do it. Could you explain how I can go by it?
Thanks.
Here's my code so far:
<!DOCTYPE html>
<html lang="en">
    <head>
            <title>three.js canvas - interactive - cubes</title>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
            <style>
                    body {
                            font-family: Monospace;
                            background-color: #f0f0f0;
                            margin: 0px;
                            overflow: hidden;
                    }
            </style>
    </head>
    <body>
            <script src="js/three.min.js"></script>
            <script src="js/stats.min.js"></script>
            <script>
                    var container, stats;
                    var camera, scene, projector, renderer;
                    var projector, mouse = { x: 0, y: 0 }, INTERSECTED;
                    var particleMaterial;
                    var currentLabel = null;
                    var objects = [];
                    init();
                    animate();
                    function init() {
                            container = document.createElement( 'div' );
                            document.body.appendChild( container );
                            var info = document.createElement( 'div' );
                            info.style.position = 'absolute';
                            info.style.top = '10px';
                            info.style.width = '100%';
                            info.style.textAlign = 'center';
                            info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js</a> - clickable objects';
                            container.appendChild( info );
                            camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
                            camera.position.set( 0, 300, 500 );
                            scene = new THREE.Scene();
                            var geometry = new THREE.CubeGeometry( 100, 100, 100 );
                            for ( var i = 0; i < 10; i ++ ) {
                                    var object = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) );
                                    object.position.x = Math.random() * 800 - 400;
                                    object.position.y = Math.random() * 800 - 400;
                                    object.position.z = Math.random() * 800 - 400;
                                    object.scale.x = Math.random() * 2 + 1;
                                    object.scale.y = Math.random() * 2 + 1;
                                    object.scale.z = Math.random() * 2 + 1;
                                    object.rotation.x = Math.random() * 2 * Math.PI;
                                    object.rotation.y = Math.random() * 2 * Math.PI;
                                    object.rotation.z = Math.random() * 2 * Math.PI;
                                    object.label = "Object " + i;
                                    scene.add( object );
                                    objects.push( object );
                            }
                            var PI2 = Math.PI * 2;
                            particleMaterial = new THREE.ParticleCanvasMaterial( {
                                    color: 0x000000,
                                    program: function ( context ) {
                                            context.beginPath();
                                            context.arc( 0, 0, 1, 0, PI2, true );
                                            context.closePath();
                                            context.fill();
                                    }
                            } );
                            projector = new THREE.Projector();
                            renderer = new THREE.CanvasRenderer();
                            renderer.setSize( window.innerWidth, window.innerHeight );
                            container.appendChild( renderer.domElement );
                            stats = new Stats();
                            stats.domElement.style.position = 'absolute';
                            stats.domElement.style.top = '0px';
                            container.appendChild( stats.domElement );
                            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
                            //
                            window.addEventListener( 'resize', onWindowResize, false );
                    }
                    function onWindowResize() {
                            camera.aspect = window.innerWidth / window.innerHeight;
                            camera.updateProjectionMatrix();
                            renderer.setSize( window.innerWidth, window.innerHeight );
                    }
                    function onDocumentMouseDown( event ) {
                            event.preventDefault();
                            var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
                            projector.unprojectVector( vector, camera );
                            var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
                            var intersects = raycaster.intersectObjects( objects );
                            if ( intersects.length > 0 ) {
                            if ( intersects[ 0 ].object != INTERSECTED ) 
                                            {
                                             // restore previous intersection object (if it exists) to its original color
                                            if ( INTERSECTED ) {
                                            INTERSECTED.material.color.setHex( INTERSECTED.currentHex ); } 
                                            // store reference to closest object as current intersection object
                                            INTERSECTED = intersects[ 0 ].object;
                                            // store color of closest object (for later restoration)
                                            INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
                                            // set a new color for closest object
                                            INTERSECTED.material.color.setHex( 0xffff00 );
                                            var canvas1 = document.createElement('canvas');
                                            var context1 = canvas1.getContext('2d');
                                            context1.font = "Bold 40px Arial";
                                            context1.fillStyle = "rgba(255,0,0,0.95)";
                                            context1.fillText(INTERSECTED.label, 0, 50);
                                            // canvas contents will be used for a texture
                                            var texture1 = new THREE.Texture(canvas1) 
                                            texture1.needsUpdate = true;
                                            var material1 = new THREE.MeshBasicMaterial( {map: texture1, side:THREE.DoubleSide } );
                                            material1.transparent = true;
                                            var mesh1 = new THREE.Mesh(
                                            new THREE.PlaneGeometry(canvas1.width, canvas1.height),
                                            material1
                                    );
                                            mesh1.position = intersects[0].point;
                                            if (currentLabel)
                                                    scene.remove(currentLabel);
                                            scene.add( mesh1 );                             
                                            currentLabel = mesh1;
                            } 
                            else // there are no intersections
                                            {
                                    // restore previous intersection object (if it exists) to its original color
                                    if ( INTERSECTED ) {
                                            console.log("hello");
                                            INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
                                            }
                                            // remove previous intersection object reference
                                            //     by setting current intersection object to "nothing"
                                            INTERSECTED = null;
                                            mesh1 = null; 
                                            mesh1.position = intersects[0].point; 
                                            scene.add( mesh1 );
                                            }
                                    //var particle = new THREE.Particle( particleMaterial );
                                    //particle.position = intersects[ 0 ].point;
                                    //particle.scale.x = particle.scale.y = 8;
                                    //scene.add( particle );
                            }
                            /*
                            // Parse all the faces
                            for ( var i in intersects ) {
                                    intersects[ i ].face.material[ 0 ].color.setHex( Math.random() * 0xffffff | 0x80000000 );
                            }
                            */
                    }
                    //
                    function animate() {
                            requestAnimationFrame( animate );
                            render();
                            stats.update();
                    }
                    var radius = 600;
                    var theta = 0;
                    function render() {
                            theta += 0.1;
                            camera.position.x = radius * Math.sin( THREE.Math.degToRad( theta ) );
                            camera.position.y = radius * Math.sin( THREE.Math.degToRad( theta ) );
                            camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) );
                            camera.lookAt( scene.position );
                            renderer.render( scene, camera );
                    }
            </script>
    </body>
Billboarding is easy. All you have to do, in your case, is add this inside your render loop:
if ( currentLabel ) currentLabel.lookAt( camera.position );
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