微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

避免将 keydown 事件从 dat.GUI 传播到 Three.js 场景

如何解决避免将 keydown 事件从 dat.GUI 传播到 Three.js 场景

我有这个带有 2 个事件侦听器的代码(见下文):

renderer.domElement.addEventListener("pointerdown",changeColor,false);
document.addEventListener("keydown",false);

它们都触发了立方体的颜色变化。但是,当我在 GUI 中编辑输入参数时,keydown 事件也会导致颜色更改,我想避免这种情况。

我猜这是因为我将 document.addEventListener 用于 keydown 事件。但是,如果我改用 renderer.domElement.addEventListener,它将不起作用。

如何避免在编辑 GUI 参数时传播 keydown 事件?

代码

var renderer,controls,scene,camera;
var cube;

init();

function init() {

    // Scene
    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xb0b0b0);

    // Camera
    camera = new THREE.PerspectiveCamera(30,window.innerWidth / window.innerHeight,1,1000);
    camera.position.set(300,300,300);
    camera.up.set(0,1);

    // Light
    var ambientLight = new THREE.AmbientLight(0xcccccc,0.2);
    scene.add(ambientLight);

    // Helpers
    var helpers = new THREE.Group();
    var grid = new THREE.GridHelper(200,10);
    grid.rotation.x = Math.PI / 2;
    var axis = THREE.AxisHelper(100);
    helpers.add(grid);
    helpers.add(axis);
    scene.add(helpers);

    // Renderer
    renderer = new THREE.Webglrenderer({ antialias: true });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth,window.innerHeight);
    document.body.appendChild(renderer.domElement);

    // Controls
    controls = new THREE.OrbitControls(camera,renderer.domElement);

    // Event listeners
    controls.addEventListener("change",render,false);

    // Draw the cube
    var cubeGeometry = new THREE.BoxGeometry( 50,50,50 );
        var cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x000088 } );
        cube = new THREE.Mesh( cubeGeometry,cubeMaterial );
    scene.add(cube);
    
    // GUI
    params = {
        size: 50,};
    var gui = new dat.GUI();
    gui.add(params,"size",0.0,100,1);
    
    // Listeners
    renderer.domElement.addEventListener("pointerdown",false);
    document.addEventListener("keydown",false);

    // Render
    render();
}

function changeColor(event) {
    cube.material.color.set(Math.random() * 0xffffff);
    cube.material.needsUpdate = true;
    render();
}

function render() {
    renderer.render(scene,camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<html>
    <head>
        <script src="https://unpkg.com/three@0.126.0/build/three.min.js"></script>
        <script src="https://unpkg.com/three@0.126.0/examples/js/controls/OrbitControls.js"></script>
        <script src="https://stemkoski.github.io/Three.js/js/DAT.GUI.min.js"></script>
    </head>
    <body>
    </body>
</html>

解决方法

不确定这是最好的方法,但是您可以通过检查其目标来忽略来自事件处理程序的 keydown 事件。如果目标是 input,则什么都不做:

function changeColor(event) {
    // Ignore key event when editing dat.GUI input values
    if (event.target.localName == "input") {
        return;
    }
    // [...]
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。