Three.js中鼠标移出物体后如何移除场景中的Mesh?
Three.js 鼠标悬停显示Mesh,移出后无法移除的问题解决
问题描述
加载GLTF模型后,已实现鼠标悬停时改变物体材质颜色、移出后恢复颜色的逻辑,但无法实现移出时移除悬停时创建的Mesh——Mesh始终留在场景中。尝试添加scene.remove(radioOutline.mesh)时,因radioOutline是if语句内的局部变量,外部无法访问;若将radioOutline相关代码移到if外,会因intersects[0]未定义抛出错误。
解决方案
核心是将radioOutline变量提升到onHover函数外部,让其作用域覆盖整个悬停逻辑,这样在鼠标移出时能访问并移除该Mesh。
修改后的代码
var radioMaterial = new THREE.MeshBasicMaterial({color: 0x0fffAA, side: THREE.BackSide}); class outlineMesh { constructor(geometry) { this.mesh = new THREE.Mesh(geometry, radioMaterial); } } // 声明全局(函数外)变量存储outline实例,初始为null let radioOutline = null; // Mouse hover event -> raycaster function onHover(event) { event.preventDefault(); raycaster.setFromCamera( mouse, camera ); var intersects = raycaster.intersectObject( radioModel ); if ( intersects.length > 0 ) { // 仅当outline不存在时才创建,避免重复添加 if (!radioOutline) { radioOutline = new outlineMesh(intersects[0].object.geometry); radioOutline.mesh.position.set(1.4,-0.5,1.2); radioOutline.mesh.rotation.y = -0.3; radioOutline.mesh.scale.multiplyScalar(1.6); scene.add(radioOutline.mesh); } if ( intersects[0].object != INTERSECTED ) { if ( INTERSECTED ) { INTERSECTED.material.color.setHex(INTERSECTED.currentHex); } INTERSECTED = intersects[0].object; INTERSECTED.currentHex = INTERSECTED.material.color.getHex(); INTERSECTED.material.color.setHex(radioHoverColor); cursor.style.cursor = "pointer"; } } else { if ( INTERSECTED ) { INTERSECTED.material.color.setHex(INTERSECTED.currentHex); } // 移除outline并重置变量 if (radioOutline) { scene.remove(radioOutline.mesh); radioOutline = null; } INTERSECTED = null; cursor.style.cursor = "default"; } }
关键修改点
- 变量作用域调整:将
radioOutline从if内部的局部变量改为函数外的全局变量,确保鼠标移出时能访问到该实例。 - 避免重复创建:悬停时先判断
radioOutline是否存在,不存在才创建添加,防止同一Mesh被重复添加到场景。 - 移出时清理:在else分支中,检查
radioOutline存在则从场景移除,并将变量重置为null,确保下次悬停能重新创建。
内容的提问来源于stack exchange,提问作者ZIMRO
相关产品推荐
相关产品推荐

