捕获渲染器中特定网格上的click事件

时间:2012-10-09 12:33:39

标签: javascript three.js

我设置了一个包含两个网格(立方体)的画布渲染器。我需要做的是 catch the click event on each cube 为它调用方便的方法。

到目前为止,我可以捕获所有渲染器上的click事件,这意味着当我点击cube1和cube2时,点击属于同一个'因为它绑定到renderer:)

我的问题是,如何在每个多维数据集上绑定click事件?

我的相关代码如下:

            //dom
    var containerPopUp=document.getElementById('popup');
    //renderer
    var rendererPopUp = new THREE.CanvasRenderer();
    rendererPopUp.setSize(420,200);

    containerPopUp.appendChild(rendererPopUp.domElement);
    //Scene
    var scenePopUp = new THREE.Scene();
    //Camera
    var cameraPopUp = new THREE.PerspectiveCamera(50,60/60,1,1000);

    cameraPopUp.position.z = 220;
    cameraPopUp.position.y =  20;
    //
    scenePopUp.add(cameraPopUp);

    //Add texture for the cube
    //Use image as texture
    var img2D = new THREE.MeshBasicMaterial({ //CHANGED to MeshBasicMaterial
    map:THREE.ImageUtils.loadTexture('img/2d.png') 
    });
    img2D.map.needsUpdate = true; //ADDED
    //Add Cube
    var cubeFor2D = new THREE.Mesh(new THREE.CubeGeometry(40,80,40),img2D);
    cubeFor2D.position.x =- 60;
    cubeFor2D.position.y = 20;

    scenePopUp.add(cubeFor2D);
    //
    var img3D = new THREE.MeshBasicMaterial({ //CHANGED to MeshBasicMaterial
    map:THREE.ImageUtils.loadTexture('img/3d.png') 
    });
    img3D.map.needsUpdate = true;
    var cubeFor3D = new THREE.Mesh(new THREE.CubeGeometry(40,80,40),img3D);
    cubeFor3D.position.x = 60;
    cubeFor3D.position.y=20;

    scenePopUp.add(cubeFor3D);
    //
    rendererPopUp.render(scenePopUp,cameraPopUp);
    //
    animate();

    rendererPopUp.domElement.addEventListener('click',testCall,false);//Here the click event is bound on the whole renderer, means what ever object in the renderer is clicked, the testCall method is called.

如您所见,cubeFor2D和cubeFor3D包含在渲染器中。我需要在每个网格上绑定click事件。我用threex.domevent.js

尝试了这个
var meshes  = {};
        meshes['mesh1'] = cubeFor2D;
        meshes['mesh1'].on('mouseover', function(event){

              //response to click...
              console.log('you have clicked on cube 2D');

        });

但它不起作用,在控制台中,我收到了这个错误:

TypeError: meshes.mesh1.on is not a function

当然,我包含了API源代码文件:

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

2 个答案:

答案 0 :(得分:19)

您可以生成这样的回调。首先为每个对象定义回调函数:

mesh.callback = function() { console.log( this.name ); }

然后按照标准拣货模式:

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();

function onDocumentMouseDown( event ) {

    event.preventDefault();

    mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;

    raycaster.setFromCamera( mouse, camera );

    var intersects = raycaster.intersectObjects( objects ); 

    if ( intersects.length > 0 ) {

        intersects[0].object.callback();

    }

}

编辑:更新为three.js r.70

答案 1 :(得分:0)

  1. 创建点击处理程序

    window.addEventListener('click', onDocumentMouseDown, false);
    
  2. 定义函数onDocumentMouseDown,请注意raycaster上面答案中的区别是单击的对象的索引位置!

    var raycaster = new THREE.Raycaster();
    var mouse = new THREE.Vector2();
    function onDocumentMouseDown( event ) {
    event.preventDefault();
    mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
    raycaster.setFromCamera( mouse, camera );
    console.log(scene.children);
    var intersects = raycaster.intersectObjects( scene.children );
    console.log(intersects[1]);
    if ( intersects.length > 0 ) {
        intersects[1].object.callback();
    }}
    
  3. 定义网格对象

    var mesh_menu_title = new THREE.Mesh(geometry_menu, materials_menu);
    mesh_menu_title.name = 'select_lang';
    mesh_menu_title.callback = function() { select_language();}
    scene.add(mesh_menu_title);
    
  4. 定义回调函数

    function select_language(){
    var selectedObject = scene.getObjectByName("select_lang"); 
    scene.remove( selectedObject );
    var selectedObject = scene.getObjectByName("start");
    scene.remove( selectedObject );
    var selectedObject = scene.getObjectByName("menu");
    scene.remove( selectedObject );
    }
    

因此,以上这段代码将处理在画布中单击的特定对象,然后回调一个函数“ mesh.callback”,它将从画布中删除一些场景子项。

如果使用相交[0] .object.callback();则不起作用。因为在索引0处存储的对象是顶点。