2011-11-02 20 views
8

tengo muchos elementos en el lienzo con Three.js,cómo conseguir elemento hecho clic en Three.js

que puede haber anulación con los demás.

por lo que ahora, cuando se haga clic en un punto,

¿Cómo puedo obtener ese mismo elemento? actualización

: chicos, esta demo ayuda mucho: http://mrdoob.github.com/three.js/examples/canvas_interactive_cubes.html

+0

http: // stackoverflow.com/questions/8292486/three-js-how-to-detect-what-shape-was-selected-after-drag – BorisD

Respuesta

21

utilizar el siguiente código. Esto le permitirá agregar un evento de clic y hacer lo que necesite cuando eso suceda. Puede ver el origen de la página para ver qué están haciendo y de qué obtuve este código.

document.addEventListener('mousedown', onDocumentMouseDown, false); 

var projector = new THREE.Projector(); 

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 ray = new THREE.Ray(camera.position, 
          vector.subSelf(camera.position).normalize()); 

    var intersects = ray.intersectObjects(objects); 

    if (intersects.length > 0) { 

     intersects[ 0 ].object.materials[ 0 ].color.setHex(Math.random() * 0xffffff); 

     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); 
    } 
    */ 
} 
+4

¿Dónde se declara e inicializa la variable 'projector'? –

+0

He agregado 'var projector = new THREE.Projector();' a la respuesta, no hice una prueba ni nada, pero estoy usando prácticamente la misma lógica en mi propio código que está tomado de las muestras ThreeJS . – Philipp

+0

'vector.subSelf' ya no existe. ahora debería ser 'vector.sub'. Además, 'unprojectVector' ahora es' unproject'. – antoineMoPa

5

El ejemplo al que se vincula tiene una API simple para esto.

Pon esto en tu HTML. Tendrás que llamar al download the script y asegurarte de que se carga.

<script src='threex.domevent.js'></script> 

Luego, en su objeto de malla, llamar al siguiente:

mesh.on('click', function() 
{ 
    // response to click... 
    mesh.scale.x *= 2; 
}); 

O un ejemplo más interesante que anima la rotación y el color de un objeto sin problemas:

mesh.on('click', function(event) 
{ 
    var object3d = event.target, 
     rotation, color; 
    if (object3d.rotation.x < Math.PI/4) { 
     rotation = {x: Math.PI/2}; 
     color = {r: 1, g: 0.5, b: 0}; 
    } else { 
     rotation = {x: 0}; 
     color = {r: 0.5, g: 0.75, b: 0.25}; 
    } 
    new TWEEN.Tween(object3d.rotation) 
     .to(rotation, 800) 
     .easing(TWEEN.Easing.Bounce.EaseOut) 
     .start(); 
    new TWEEN.Tween(object3d.material.color) 
     .to(color, 300) 
     .easing(TWEEN.Easing.Quartic.EaseIn) 
     .start(); 
}) 
+2

dice Uncaught TypeError: Object [object Object] no tiene el método 'on' mazeJs.js: 198 – Rickie

+0

@Rickie, ¿cuál es el tipo de su ' ¿instancia de malla? –

+0

Este script es verdaderamente fresco y me gustaría utilizarlo pero también estoy recibiendo un error: no detectada TypeError: mesh.on no es una función .. var img = new THREE.MeshBasicMaterial ({ \t \t \t \t \t mapa: THREE.ImageUtils.loadTexture ('images/greg.jpg') \t \t \t \t \t}); var mesh = new THREE.Mesh (new THREE.PlaneGeometry (50, 50), img); --- Me pregunto qué podría estar causando el error – Starfs

1

respuesta de Drew el uso de THREEx.domevents está desactualizado. La nueva API requiere inicializar un objeto domEvents y luego vincular las mallas con los detectores de eventos correspondientes.

Desde el Github repo:

var domEvents = new THREEx.DomEvents(camera, renderer.domElement) 
// ... 
domEvents.addEventListener(mesh, 'click', function(event){ 
    console.log('you clicked on the mesh') 
}, false) 

Además, está disponible en la glorieta!

bower install threex.domevents 

Editar: Aunque no documentado, no hay soporte para 'touchstart', 'touchend', y algunos otros eventos móviles. Asegúrese de consultar estos si es compatible con el móvil, ya que los "clics" del mouse no siempre se informan como tales en algunos dispositivos.

2

tal vez esta herramienta puede ayudar a usted, un gerente de la interacción completa, ayudan three.js fácil de evento interacción de unión

más detial ver three.interaction

import { Scene, PerspectiveCamera, WebGLRenderer, Mesh, BoxGeometry, MeshBasicMaterial } from 'three'; 
 
import { Interaction } from 'three.interaction'; 
 

 
const renderer = new WebGLRenderer({ canvas: canvasElement }); 
 
const scene = new Scene(); 
 
const camera = new PerspectiveCamera(60, width/height, 0.1, 100); 
 

 
// new a interaction, then you can add interaction-event with your free style 
 
const interaction = new Interaction(renderer, scene, camera); 
 

 
const cube = new Mesh(
 
    new BoxGeometry(1, 1, 1), 
 
    new MeshBasicMaterial({ color: 0xffffff }), 
 
); 
 
scene.add(cube); 
 
cube.cursor = 'pointer'; 
 
cube.on('click', function(ev) {}); 
 
cube.on('touchstart', function(ev) {}); 
 
cube.on('touchcancel', function(ev) {}); 
 
cube.on('touchmove', function(ev) {}); 
 
cube.on('touchend', function(ev) {}); 
 
cube.on('mousedown', function(ev) {}); 
 
cube.on('mouseout', function(ev) {}); 
 
cube.on('mouseover', function(ev) {}); 
 
cube.on('mousemove', function(ev) {}); 
 
cube.on('mouseup', function(ev) {}); 
 
// and so on ... 
 

 
/** 
 
* you can also listen at parent or any display-tree node, 
 
* source event will bubble up along with display-tree. 
 
*/ 
 
scene.on('touchstart', ev => { 
 
    console.log(ev); 
 
}) 
 
scene.on('touchmove', ev => { 
 
    console.log(ev); 
 
})

Cuestiones relacionadas