在3js中为多维数据集添加click事件侦听器

时间:2014-04-12 09:56:02

标签: three.js

在我的代码中我有两个立方体,我想向它们添加click事件监听器。例如,警告用户点击了哪个多维数据集。当我将click事件监听器添加到文档时它完美地工作,但是当我向立方体添加相同的单击事件监听器时它没有显示任何内容。这是我的代码部分..

<script type = "text/javascript" src = "three.min.js"></script>
<script type="text/javascript">
var camera = new THREE.PerspectiveCamera(70,window.innerWidth/window.innerHeight,0.1,1000);
var scene = new THREE.Scene();
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);

document.body.appendChild(renderer.domElement);
camera.position.z=30;

var geometry = new THREE.CubeGeometry(10,10,10);
var material = new THREE.MeshBasicMaterial({color:0x778899});
var cube = new THREE.Mesh(geometry,material);
cube.addEventListener("mousedown", onDocumentMouseDown, false);
cube.position.x = -10;
scene.add(cube);

var cube1 = new THREE.Mesh(geometry,material);
cube.addEventListener("mousedown", onDocumentMouseDown, false);
cube1.position.x=10;
scene.add(cube1);

var render = function(){
    var timer = Date.now()*-0.0002;
    requestAnimationFrame(render);
    camera.position.x = 30* Math.cos(timer);
    camera.position.z = 30* Math.sin(timer);

    camera.lookAt(scene.position);
    renderer.render(scene,camera);
};

render();

function onDocumentMouseDown(event){
    alert('hi');
}
</script>

3 个答案:

答案 0 :(得分:4)

addEventListener只能用于DOM元素。见EventTarget.addEventListener()

如果你想在Three.js场景中选择对象,你应该查看Three.js Raycaster

Raycaster基本上将来自摄像机的光线发送到场景中,并返回与光线相交的对象阵列。要使用Raycaster,您需要将addEventListener附加到窗口对象或Three.js画布。

例如:window.addEventListener( 'mousemove', onMouseMove, false );

在Three.js示例页面上有很多使用Raycaster的例子。

答案 1 :(得分:0)

您还可以使用Threex.js的domEvents将侦听器添加到对象网格。

var domEvents = new THREEx.DomEvents(camera, renderer.domElement);
domEvents.addEventListener(cube, 'mousedown', onDocumentMouseDown, false);
domEvents.addEventListener(cube1, 'mousedown', onDocumentMouseDown, false);

function onDocumentMouseDown(event){
    if (event.target == cube)
        //do stuff
}

答案 2 :(得分:0)

默认情况下,不支持为Three.js对象添加Click侦听器。

您应该结合使用Raycaster和鼠标事件:

export const addObjectClickListener = (
          camera,
          scene,
          raycaster,
          objectToWatch,
          onMouseClick,
        ) => {
          const objectToWatchId = objectToWatch.uuid;
          let mouse = new THREE.Vector2();

          document.addEventListener(
            "click",
            (event) => {
              mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
              mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

              raycaster.setFromCamera(mouse, camera);

              const intersects = raycaster.intersectObjects(scene.children);

              const isIntersected = intersects.find(
                (intersectedEl) => intersectedEl.object.uuid === objectToWatchId
              );

              if (isIntersected) {
                onMouseClick();
              }
            },
            false
          );
        };

这需要几个参数:

  • 相机-三个相机(例如,透视)
  • 场景-三场景
  • raycaster-三.Raycaster
  • objectToWatch-Three.Object(用于监视单击事件的目标网格)
  • onMouseClick-回调

您可以为悬停和其他事件做类似的事情。请注意性能,因为每次调用此函数时都会为全局鼠标事件注册新的侦听器。因此,如果您需要添加许多可点击的对象,则可能需要以其他方式进行。