2013-04-14 11 views
5

Patrzę na dwa przykłady, jeden to interaktywne obiekty na płótnie, a drugi to podpowiedź myszy. Próbowałem połączyć te dwa, aby wygenerować etykiety tekstowe na każdym pojedynczym sześcianie i oto, co mam do tej pory.Jak ustawić etykiety tekstowe w aparacie przez cały czas? Być może za pomocą duszków?

Tekst porusza się jednak z obracającymi się sześcianami, a tekst pojawia się czasem w tył lub w bok.

Jak mogę poprawić tekst w sprite'u, tak jak w przykładowej podpowiedzi myszy (http://stemkoski.github.io/Three.js/Mouse-Tooltip.html)? Próbowałem włączyć duszka, ale ciągle dostrzegałem błędy. Nie jestem pewien, jak to zrobić. Czy możesz wyjaśnić, jak mogę to zrobić?

Dzięki.

Oto mój kod do tej pory:

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

To, co chcesz, nazywa się billboardem. Wierzę, że three.js ma je wbudowane – Dave

+0

@Dave, czy istnieje przykład, który mogę śledzić? –

Odpowiedz

7

Billboarding jest łatwe. Wszystko, co musisz zrobić, w twoim przypadku, dodaj to wewnątrz pętli renderowania:

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

@ WestLangley, prawda, że ​​działa! Fantastyczny! Hmm ... teraz mam osobne pytanie, jak mogę mieć etykietę zgodną pod względem wielkości, bez względu na to, gdzie jest umieszczona? Przypuszczam, że mogę stworzyć pole tekstowe, które będzie spójne z etykietą? –

+0

Możesz użyć kamery ortograficznej, ale naprawdę musisz opublikować nowy numer, jeśli masz dodatkowe pytania. Rozważ także użycie CSS do tekstu. – WestLangley

+0

Dobra dzięki WestLangley. Wypróbuję kilka rzeczy i wkrótce opublikuję nowe pytanie! –

Powiązane problemy