在Three.js中更改Sprite o Texture Size

时间:2017-09-11 07:50:53

标签: javascript html canvas three.js

我正在学习使用“Three.js”库。我使用纹理和精灵与画布创建标签,显示信息取决于我用鼠标选择的对象。

问题在于我没有显示所有内容 在浏览器屏幕上。

您可以在此处查看问题:screenshot

代码在这里:

<html lang="en">
    <head>
        <title>Prueba</title>
        <!-- Eliminación de la mal interpretación de signos. -->
        <meta charset="utf-8">
        <!-- Adaptación a la pantalla de los dispositivos móviles.-->
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <!-- Librería principal de "Three.js". -->
        <script src="js/Three.js"></script>
        <!-- Librería para la creación de un elemento detector. -->
        <script src="js/Detector.js"></script>
        <!-- Lbrería para el control de la cámara. -->
        <script src="js/OrbitControls.js"></script>
        <!-- Librería para el "render" ocupe toda la ventana del navegador. -->
        <script src="js/THREEx.FullScreen.js"></script>
        <!-- Librería para rediemnsionalizar los cambios de tamaño de la ventana del navegador. -->
        <script src="js/THREEx.WindowResize.js"></script>
        <!-- jQuery para proporcionar información de los objetos que hay en la escena cuando el ratón está sobre ellos. -->
        <script src="js/jquery-1.9.1.js"></script>
    </head>
    <body>
        <div id="ThreeJS" style="position: absolute; left:0px; top:0px">
        </div>
        <script>
            // Declaración global delas variables estándar.
            var container, scene, camera, renderer, controls, stats;
            // Declaración global de las variables que se customizarán.
            var projector, mouse = { x: 0, y: 0 }, INTERSECTED;
            var sprite1;
            var canvas1, context1, texture1;
            // Llamada inicial de las funciones "init()" y "animate()".
            init();
            animate();
            // Funciones:       
            function init() {
                // Creación de la escena.
                scene = new THREE.Scene();
                // Creación de la cámara.
                var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
                var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
                camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
                scene.add(camera);
                // Posicionamiento de la cámara.
                camera.position.set(0,150,400);
                camera.lookAt(scene.position);  
                // Creación del renderer (detección del navegador usado).
                if( Detector.webgl ) {
                     renderer = new THREE.WebGLRenderer( {antialias:true} );
                }else{
                     renderer = new THREE.CanvasRenderer(); 
                }
                renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
                container = document.getElementById( 'ThreeJS' );
                container.appendChild( renderer.domElement );
                // Eventos de ajuste del renderer a la ventana del navegador.
                THREEx.WindowResize(renderer, camera);
                THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) });
                // Control de la cámara con el ratón.
                controls = new THREE.OrbitControls( camera, renderer.domElement );
                // Definir las esferas (vértices o nodos).
                var sphere = [];
                var nummero_nodos = 48;
                for (i=1;i<=nummero_nodos;i++) {
                    // SphereGeometry(radio esfera, ancho segemento, altura segmento)
                    var sphereGeometry = new THREE.SphereGeometry(8, 20, 20);
                    // Decidimos como se verá el plano.
                    var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x7777ff}); // color azul 
                    // Creamos un objeto tipo esfera.
                    sphere[i] = new THREE.Mesh(sphereGeometry, sphereMaterial);
                    // Posicionamos la esfera en la escena.
                    if(i%2!=0) {
                        // Si la esfera es impar.
                        sphere[i].position.x = -50;
                        sphere[i].position.y = 200-50*i;
                        sphere[i].position.z = 0;
                    }else{
                        // Si la esfera tiene i par.
                        sphere[i].position.x = 50;
                        sphere[i].position.y = 150-50*i;
                        sphere[i].position.z = 0;
                    }
                    // Añadir una etiqueta a las esferas.
                    sphere[i].name="ESFERA "+i.toString()+", texto de relleno para mostrar el error o el fallo.";
                    // Añadimos la esfera a la escena.
                    scene.add(sphere[i]);
                }
                // Conocer la posición X de las esferas.    
                /* for(i=1;i<=nummero_nodos;i++) {
                    console.log(sphere[i].position.x);
                } */
                // Definir los tubos (relaciones).
                var tube =[]
                var j=1;
                for(i=1;i<=nummero_nodos;i++) {
                    // Los vértices impares generan relaciones.
                    if(i%2==1) {
                        // Relación nodo impar-impar.
                        if(sphere[i-1]!=undefined && sphere[i-1]!="") {
                            // Definir la línea (usamos un tubo).
                            // Creamos el cammino que va a seguir el tubo (es decir la línea).
                            // Indicamos los vértices que formarán la línea.
                            var start = new THREE.Vector3(sphere[i].position.x,sphere[i].position.y, sphere[i].position.z);
                            var end = new THREE.Vector3(sphere[i-1].position.x,sphere[i-1].position.y, sphere[i-1].position.z);
                            // Creamos la línea.
                            var line = new THREE.LineCurve( start, end )
                            // Indicamos el número de puntos que compondrán el tubo.
                            var numPoints = 100;
                            // Decidimos como se verá el tubo.
                            var tubeGeometry = new THREE.TubeGeometry( line, numPoints, 2, 8, false );
                            var tubeMaterial = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
                            tube[j] = new THREE.Mesh( tubeGeometry, tubeMaterial );
                            tube[j].name="TUBO "+j.toString();
                            scene.add( tube[j] );
                            j+=1;
                        }
                        // Relación nodos impar-impar.
                        if(sphere[i+2]!=undefined && sphere[i+2]!="") {
                            // Definir la línea (usamos un tubo).
                            // Creamos el cammino que va a seguir el tubo (es decir la línea).
                            // Indicamos los vértices que formarán la línea.
                            var start = new THREE.Vector3(sphere[i].position.x, sphere[i].position.y, sphere[i].position.z);
                            var end = new THREE.Vector3(sphere[i+2].position.x, sphere[i+2].position.y, sphere[i+2].position.z);
                            // Creamos la línea.
                            var line = new THREE.LineCurve( start, end )
                            // Indicamos el número de puntos que compondrán el tubo.
                            var numPoints = 100;
                            // Decidimos como se verá el tubo.
                            var tubeGeometry = new THREE.TubeGeometry( line, numPoints, 2, 8, false );
                            var tubeMaterial = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
                            tube[j] = new THREE.Mesh( tubeGeometry, tubeMaterial );
                            tube[j].name="TUBO "+j.toString();
                            scene.add( tube[j] );
                            j+=1;
                        }
                    }
                };  
                // Inicializar un objeto para realizar cálculos de la relación "pantalla / mundo".
                projector = new THREE.Projector();
                // Cuando el ratón se mueve llamamos a la función onDocumentMouseMove().
                document.addEventListener( 'mousemove', onDocumentMouseMove, false );
                /////// Dibujar el texto en un elemento canvas: /////////
                // Creamos el elemento tipo canvas.
                canvas1 = document.createElement('canvas');
                context1 = canvas1.getContext('2d');
                context1.font = "Bold 20px Arial";
                context1.fillStyle = "rgba(0,0,0,0.95)";
                context1.fillText('Hello, world!', 0, 20);
                // El contenido del elemento canvas será utilizado por un elemento del tipo textura.
                texture1 = new THREE.Texture(canvas1);
                texture1.needsUpdate = true;
                // Creamos un elemento tipo sprite donde pondremos nuestro elemento tipo textura que contiene el texto.
                var spriteMaterial = new THREE.SpriteMaterial( { map: texture1, useScreenCoordinates: true, alignment: THREE.SpriteAlignment.topLeft } );
                sprite1 = new THREE.Sprite( spriteMaterial );
                sprite1.scale.set(200,100,1.0);
                sprite1.position.set( 50, 50, 0 );
                // Añadir el sprite a la escena.
                scene.add( sprite1 );   
            }
            function onDocumentMouseMove( event ) {
                // Corregimos la posición del sprite al mover el ratón.
                sprite1.position.set( event.clientX, event.clientY - 20, 0 );
                // Modificamos los valores de la variable mouse.
                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = -( event.clientY / window.innerHeight ) * 2 + 1;
            }
            function animate() {
                requestAnimationFrame( animate );
                // Rellamada de las funciones.
                render();       
                update();
            }
            function update() {
                // Creación de una línea (ray) con origen en la posición del ratón y con dirección hacia la escena (dirección de la cámara).
                var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
                projector.unprojectVector( vector, camera );
                var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
                // Creamos una matriz que contenga todos los objetos en la escena con la que la línea se cruza en su trayectoria.
                var intersects = ray.intersectObjects( scene.children );
                // INTERSECTED : es el objeto en la escena actualmente más cercano a la cámara e intersectado por el rayo (línea) proyectado desde la posición del ratón.               
                // Si hay una (o más) intersecciones.
                if(intersects.length > 0) {
                    // Si el objeto más cercano intersectado no es el objeto de intersección actualmente almacenado.
                    if(intersects[ 0 ].object != INTERSECTED) {
                        // Restaurar el objeto de intersección anterior (si existe) a su color original.
                        if(INTERSECTED) { 
                            INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
                        }
                        // Almacena la referencia al objeto más cercano como objeto de intersección actual.
                        INTERSECTED = intersects[ 0 ].object;
                        // Almacena el color del objeto más cercano (para una restauración posterior).
                        INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
                        // Establece un nuevo color para el objeto más cercano.
                        INTERSECTED.material.color.setHex( 0xffff00 );
                        // Actualiza el texto, si tiene un campo "name" el objeto.
                        if(intersects[ 0 ].object.name) {
                            context1.clearRect(0,0,640,480);
                            var message = intersects[ 0 ].object.name;
                            var metrics = context1.measureText(message);
                            var width = metrics.width;
                            context1.fillStyle = "rgba(0,0,0,0.95)"; // color del borde (negro)
                            context1.fillRect( 0,0, width+8,20+8);
                            context1.fillStyle = "rgba(255,255,255,0.95)"; // color del fondo (blanco)
                            context1.fillRect( 2,2, width+4,20+4 );
                            context1.fillStyle = "rgba(0,0,0,1)"; // color del texto (negro)
                            context1.fillText( message, 4,20 );
                            texture1.needsUpdate = true;
                        }else{
                            // No existe texto ni itiqueta.
                            context1.clearRect(0,0,300,300);
                            texture1.needsUpdate = true;
                        }
                    }
                    // Si no hay intersección.
                }else{
                    // Restaura el objeto de intersección anterior (si existe) a su color original.
                    if(INTERSECTED) { 
                        INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
                    }
                    // Elimina la referencia de objeto de intersección anterior estableciendo el objeto de intersección actual en "nada".
                    INTERSECTED = null;
                    context1.clearRect(0,0,300,300);
                    texture1.needsUpdate = true;
                }
                // Modificación de la cámara al mover el ratón.
                controls.update();
            }
            // Renderización de la escena.
            function render() {
                renderer.render( scene, camera );
            }
        </script>
    </body>
</html>

我尝试通过使用“fillRect()”修改画布的大小来解决问题,但它没有显示所有矩形。

我还修改了精灵的比例,但这只会扭曲字母。

最后,我试图将信息放在不同的行中,但最终只会在垂直方向发生相同的事情。

有人知道如何解决这个问题吗?有什么想法吗?

提前致谢!

0 个答案:

没有答案