gpt4 book ai didi

Javascript 鼠标事件不适用于 Three.JS 场景元素

转载 作者:太空宇宙 更新时间:2023-11-04 15:26:21 25 4
gpt4 key购买 nike

好吧,我只是很困惑(而且可能太累了,不利于我现在从事这项工作......)。当鼠标悬停在场景中特定类型的实体上时,我试图让我的 Three.js 应用程序针对不同的鼠标事件执行不同的函数。 “mousemove”类型的事件运行良好,并且

console.log( 'INTERSECTED.isGraphElement: ', INTERSECTED.isGraphElement, 'MouseEvent: ', mouse.type );

语句注册了我正在监听的所有鼠标事件,其中包括“mousemove”、“click”、“dblclick”、“wheel”和“oncontextmenu”。它还检测 INTERSECTED.isGraphElement对象如预期。

尽管如此,当 transformGraphElement()运行时,只有“mousemove”事件在 transformGraphElement 内注册。功能。即使是注释掉的测试代码行也应该输出“Got the dblclick!”不运行。看来这里没有检测到我正在监听的其他鼠标事件。

我在 transformGraphElement 中尝试过的事情功能:

  • 将 dblclick 事件替换为我正在监听的其他类型之一。没有骰子。
  • 注释掉处理 mousemove 事件的行。没有骰子。
  • 测试一下我的 obj.referent.transformOnDblClick() 是否有错误功能。我只知道它根本没有被调用(当我将它与“mousemove”事件关联时,它运行得很好)。
  • 为我的“if”语句尝试不同的有效语法。没有骰子。
  • 尝试对 mouseEventHandler() 进行一些重构功能。没有骰子。

这是我的相关代码:

    function render() {        mouseEventHandler( transformGraphElement, unTransformGraphElement );        requestAnimationFrame( render );        renderer.render(scene, entities.cameras.perspCamera );    }    function mouseEventHandler( fn, revFn ){        // update the picking ray with the camera and mouse position        ray.setFromCamera( mouse, entities.cameras.perspCamera );        // calculate objects intersecting the picking ray        var intersects = ray.intersectObjects( scene.children );        if ( intersects && intersects[0] && intersects[0].object ){            if ( intersects[ 0 ].object != INTERSECTED ){   // if there's an intersected object                if ( INTERSECTED ) {                        // and if a previous INTERSECTED object exists:                    revFn( INTERSECTED, mouse );                    // restore the previous intersected object to its non-intersected state.                                }                                       INTERSECTED = intersects[ 0 ].object;       // set the currently intersected object to INTERSECTED                fn( INTERSECTED, mouse );                           // transform the currentlY INTERSECTED object.                }                   console.log( 'INTERSECTED.isGraphElement: ', INTERSECTED.isGraphElement, 'MouseEvent: ', mouse.type );            }    }    function transformGraphElement( obj, mouse ){        // Check if INTERSECTED is a Graph Element, and if so, invoke it's transform function.          if ( mouse.type === "mousemove" && obj.isGraphElement ) { obj.referent.transformOnMouseOver(); }        //if ( mouse.type === 'dblclick' ) { console.log('Got the dblclick Inside!') }          if ( mouse.type === 'dblclick' && obj.isGraphElement ) { obj.referent.transformOnDblClick(); ) }    }    function unTransformGraphElement( obj, mouse ){        // Check if INTERSECTED is a Graph Element, and if so, revert it to it's pre-mouseEvent state.        if ( mouse.type === "mousemove" && obj.isGraphElement ) { obj.referent.transformOnMouseOut(); }        if ( mouse.type === 'dblclick' ) { console.log('Got the dblclick Out!') }    }

我想知道我遇到的是否是某种默认行为或覆盖,但 event.preventDefault() 行不应该处理这个问题吗? (下面的代码在上面的代码之前运行):

    var ray = new THREE.Raycaster();    var mouse = new THREE.Vector2();    var INTERSECTED;  // Object closest to the camera    function onMouse( event ) {        event.preventDefault();        // calculate mouse position in normalized device coordinates        // (-1 to +1) for both components        mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;        mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;        mouse.type = ( event.type );    }    function listenFor(){        document.addEventListener( 'click', onMouse, false );        document.addEventListener( 'mousemove', onMouse, false );        document.addEventListener( 'mousedown', onMouse, false );        document.addEventListener( 'dblclick', onMouse, false )        document.addEventListener( 'wheel', onMouse, false );        document.addEventListener( 'contextmenu', onMouse, false );    }    listenFor();

Console.log( mouse.type )从里面onMouse()函数完美地注册了我正在监听的所有鼠标事件。

我已经为此苦苦挣扎了三个小时。我希望这是因为我心情不好而错过的一些愚蠢而简单的事情。欢迎所有帮助,如果有任何缺失的代码对于提供有用的答案很重要,请告诉我...我不这么认为,但心情不好...

感谢您的帮助!

最佳答案

第二天早上我起床并解决了问题。问题出在代码中的逻辑上:

            if ( intersects[ 0 ].object != INTERSECTED ){   // if there's an intersected object                if ( INTERSECTED ) {                        // and if a previous INTERSECTED object exists:                    revFn( INTERSECTED, mouse );                    // restore the previous intersected object to its non-intersected state.                                }                                       INTERSECTED = intersects[ 0 ].object;       // set the currently intersected object to INTERSECTED                fn( INTERSECTED, mouse );                           // transform the currentlY INTERSECTED object.                }                   console.log( 'INTERSECTED.isGraphElement: ', INTERSECTED.isGraphElement, 'MouseEvent: ', mouse.type );            }

Non-mousemove events could not be passed. My solution was to wrap this section with another conditional if (mouse.type === 'mousemove') and then have additional conditionals for other event types. Here's the whole, with a bit of refactoring to make the whole easier to reason about:

var ray = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var INTERSECTED; // Object closest to the camera

function onMouse( event ) {

event.preventDefault();

// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components

mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

mouseEventHandler( event /*, transformGraphElement, unTransformGraphElement */ );

}

function listenFor(){
document.addEventListener( 'click', onMouse, false );
document.addEventListener( 'mousemove', onMouse, false );
document.addEventListener( 'mousedown', onMouse, false );
document.addEventListener( 'dblclick', onMouse, false )
document.addEventListener( 'wheel', onMouse, false );
document.addEventListener( 'contextmenu', onMouse, false );
}

listenFor();

/* ... */

function render() {

requestAnimationFrame( render );
renderer.render(scene, entities.cameras.perspCamera );
}

function mouseEventHandler( event /* , fn, revFn */ ){

// update the picking ray with the camera and mouse position
ray.setFromCamera( mouse, entities.cameras.perspCamera );

// calculate objects intersecting the picking ray
var intersects = ray.intersectObjects( scene.children );

// if there's at least one intersected object...
if ( intersects && intersects[0] && intersects[0].object ){

// Check if the event is a mouse move, INTERSECTED exists and we're sitting on the same INTERSECTED object as the last time this function ran...
if ( event.type === 'mousemove' ){
// Check if the current top-level intersected object is the previous INTERSECTED
if ( intersects[ 0 ].object != INTERSECTED ){
// ... if there is a previous INTERSECTED
if ( INTERSECTED ) {
// restore the previous INTERSECTED to it's previous state.
unTransformGraphElementOnMouseOut( INTERSECTED, event );
}
// set the currently intersected object to INTERSECTED
INTERSECTED = intersects[ 0 ].object;
// and transform it accordingly.
transformGraphElementOnMouseOver( INTERSECTED, event );
}
}

// Check if the mouse event is a doubble click
if ( event.type === 'dblclick' ){
// If the currently intersected object is INTERSECTED
if ( intersects[ 0 ].object === INTERSECTED ){
// select it.
transformGraphElementOnSelect( INTERSECTED, event );
}
// If the currently intersected object is not INTERSECTED
if ( intersects[ 0 ].object !== INTERSECTED ){
// If there is a previous INTERSECTED
if ( INTERSECTED )
// restore it to its unselected state.
unTransformGraphElementOnUnselect( INTERSECTED, event );
}
}

INTERSECTED && console.log( 'INTERSECTED.isGraphElement: ', INTERSECTED.isGraphElement, 'MouseEvent: ', event.type );
}
}

function transformGraphElementOnMouseOver( obj, event ){
if ( obj.isGraphElement ) { obj.referent.transformOnMouseOver(); }
}

function unTransformGraphElementOnMouseOut( obj, event ){
if ( obj.isGraphElement ) { obj.referent.transformOnMouseOut(); }
}

function transformGraphElementOnSelect( obj, event ){
if ( obj.isGraphElement ) { obj.referent.transformOnDblClick(); }
}

function unTransformGraphElementOnUnselect( obj, event ){
if ( obj.isGraphElement ) { obj.referent.unTransformOnDblClick(); }
}

mouseEventHandler()的逻辑仍然存在一些问题,但核心的挫败感已经得到解决。一些值得一提的额外重构:

  • 无需添加 event.typemouse .
  • 我移动了mouseEventHandler()调用 render()onMouse() 。这可确保鼠标事件仅注册一次。
  • 我摆脱了 mouseEventHandler() 中的 'fn'/'revFn' 回调因为他们只是让事情变得比他们需要的更加困惑。
  • Event不需要是转换函数的参数,很快就会发布。

希望这对某人有帮助。

关于Javascript 鼠标事件不适用于 Three.JS 场景元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47950150/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com