【问题标题】:adding click event listener for a cube in 3js在 3js 中为多维数据集添加点击事件监听器
【发布时间】:2020-06-15 18:01:49
【问题描述】:

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

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

【问题讨论】:

标签: three.js


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

    您还可以使用 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
    }
    

    【讨论】:

      【解决方案3】:

      默认不支持为 Three.js 对象添加点击监听。

      您应该将 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
                );
              };
      

      这需要几个参数:

      • camera - Three.Camera (e.g. Perspective)
      • 场景-三.场景
      • raycaster - 三.Raycaster
      • objectToWatch - Three.Object(目标网格来监视点击事件)
      • onMouseClick - 回调

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

      【讨论】:

      • 如何将此 addObjectClickListener 添加到应用程序?
      猜你喜欢
      • 1970-01-01
      • 2021-04-13
      • 2022-12-24
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      • 2018-02-11
      • 1970-01-01
      • 2020-06-13
      相关资源
      最近更新 更多