2013-04-14 2 views
5

Ich betrachte zwei Beispiele, eins ist interaktive Objekte auf Leinwand und das andere ist Maus-Tooltip. Ich habe versucht, die beiden zu kombinieren, um Textbeschriftungen für jeden einzelnen Würfel zu generieren, und hier ist das, was ich bisher gemacht habe.Wie kann ich meine Textbeschriftungen jederzeit der Kamera aussetzen? Vielleicht mit Sprites?

Der Text bewegt sich jedoch mit den rotierenden Würfeln und der Text erscheint manchmal rückwärts oder seitwärts.

Wie kann ich den Text in einem Sprite wie in der Maus Tooltip (http://stemkoski.github.io/Three.js/Mouse-Tooltip.html) Beispiel behoben werden? Ich habe versucht, das Sprite zu integrieren, aber ich habe immer Fehler bekommen. Ich bin mir nicht sicher, wie es geht. Kannst du mir erklären, wie ich daran vorbeigehen kann?

Danke.

Hier ist mein Code so weit:

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

+1

Was Sie wollen, heißt eine Plakatwand. Ich glaube, dass three.js sie eingebaut hat – Dave

+0

@Dave, gibt es ein Beispiel, dem ich folgen kann? –

Antwort

7

Billboarding einfach ist. Alles, was Sie in Ihrem Fall tun müssen, ist dies in Ihrem Render-Loop hinzuzufügen:

if (currentLabel) currentLabel.lookAt(camera.position); 
+0

@ WestLangley, Wahr, das funktioniert! Fantastisch! Hmm ... jetzt habe ich eine separate Frage, wie kann ich ein Label konsistent in der Größe haben, egal wo es positioniert ist? Ich nehme an, ich kann eine Textbox erstellen, die das Etikett konsistent hält? –

+0

Sie könnten zum Beispiel eine orthographische Kamera verwenden, aber Sie müssen wirklich ein neues Problem veröffentlichen, wenn Sie weitere Fragen haben. Ziehen Sie auch die Verwendung von CSS für Text in Betracht. – WestLangley

+0

Okay, danke WestLangley. Ich werde ein paar Dinge versuchen und bald eine neue Frage stellen! –

Verwandte Themen