Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I add a tag/label to appear on top of several objects so that the tag always faces the camera when the user clicks the object?
    primarykey
    data
    text
    <p>Essentially, what I am saying is I want to create a tag or label that appears on top of/on the surface of an object so that the tag always faces the camera when the user clicks the object even when the object is rotated. </p> <p>How do I go about doing so? </p> <p>I was told to use Orthogonal camera (but I'm not sure how?) and CSS for the label (see previous post: <a href="https://stackoverflow.com/questions/16001208/how-can-i-make-my-text-labels-face-the-camera-at-all-times-perhaps-using-sprite">How can I make my text labels face the camera at all times? Perhaps using sprites?</a>) </p> <p>The label in CSS and html is below. However, I want to do this for several objects as well, so I guess I can make a list of all the tags I want for each cube in this case.</p> <p>CSS: </p> <pre><code>label { vertical-align: middle; display: table-cell; background-color : #99FFCC; border: 1px solid #008000; width: 150px; } </code></pre> <p>HTML: </p> <pre><code>&lt;div id="Cube1"&gt; &lt;label&gt;Cube 1&lt;/label&gt; &lt;/div&gt; </code></pre> <p></p> <p>Previous Code: </p> <pre><code>&lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;title&gt;three.js canvas - interactive - cubes&lt;/title&gt; &lt;meta charset="utf-8"&gt; &lt;meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"&gt; &lt;style&gt; body { font-family: Monospace; background-color: #f0f0f0; margin: 0px; overflow: hidden; } &lt;/style&gt; &lt;/head&gt; &lt;body&gt; &lt;script src="js/three.min.js"&gt;&lt;/script&gt; &lt;script src="js/stats.min.js"&gt;&lt;/script&gt; &lt;script&gt; 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 = '&lt;a href="http://threejs.org" target="_blank"&gt;three.js&lt;/a&gt; - 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 &lt; 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 &gt; 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 ); } &lt;/script&gt; &lt;/body&gt; </code></pre> <p>Please let me know if I'm being unclear. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload