在三个js中使用鼠标悬停更改网格颜色

Posted

技术标签:

【中文标题】在三个js中使用鼠标悬停更改网格颜色【英文标题】:Change color of mesh using mouseover in three js 【发布时间】:2016-11-13 20:21:05 【问题描述】:

我已经编写了一个 WebGL 脚本,该脚本使用 jsonloader 和 three.js 显示多个网格,现在我想添加 MouseOver 和 onClick 事件。第一个是当鼠标悬停在网格上时简单地改变网格的颜色:

function render() 
  requestAnimationFrame(render);    
  mesh.rotation.z += 0.090;    
  raycaster.setFromCamera(mouse, camera);    
  var intersects = raycaster.intersectObjects(scene.children);  

  for (var i = 0; i < intersects.length; i++)     
    intersects[i].object.material.color.set(0xff0000);    
      
  renderer.render(scene, camera);


上面的渲染功能允许我通过将鼠标悬停在任何网格上来将其颜色更改为红色。我已经尝试了几个 if/else 变体来尝试只有当鼠标悬停在网格上时才会产生这种效果,但我无法让它工作——它只是保持红色。谁能建议我如何修改我的脚本?

谢谢。

【问题讨论】:

为什么要在每行之间留一个空格?为什么要使用标签? 这是我养成的坏习惯,抱歉。我有时会从其他文件中复制并粘贴一些代码,然后留出空格来标识我添加的代码。 【参考方案1】:

您必须在鼠标移出时将颜色设置回原始颜色,这不会自动发生...

在http://stemkoski.github.io上查看this example具体更新方法:

Here a fiddle with a demo更新到最新的three.js master:

// create a Ray with origin at the mouse position
//   and direction into the scene (camera direction)
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects( scene.children );

// INTERSECTED = the object in the scene currently closest to the camera 
//      and intersected by the Ray projected from the mouse position    

// if there is one (or more) intersections
if ( intersects.length > 0 )

    // if the closest object intersected is not the currently stored intersection object
    if ( intersects[ 0 ].object != INTERSECTED )
    
        // restore previous intersection object (if it exists) to its original color
        if ( INTERSECTED )
            INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
        // store reference to closest object as current intersection object
        INTERSECTED = intersects[ 0 ].object;
        // store color of closest object (for later restoration)
        INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
        // set a new color for closest object
        INTERSECTED.material.color.setHex( 0xffff00 );
    

else // there are no intersections

    // restore previous intersection object (if it exists) to its original color
    if ( INTERSECTED )
        INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
    // remove previous intersection object reference
    //     by setting current intersection object to "nothing"
    INTERSECTED = null;

【讨论】:

很好的解决方案,它工作得非常完美。只需要注意使用的鼠标坐标的正确调整,并且可能你将不得不忽略你击中的一些对象(例如使用'name'属性)。 @Displee 您是否在 r85 中尝试过此代码?我几乎可以肯定它会起作用,如果不是,那么所需的更改将是最小的。你试过了吗?如果是,您遇到了什么问题? @Displee 我添加了一个小提琴,其中代码更新为 r85。正如我所料,代码与我链接到的页面几乎没有什么不同。【参考方案2】:

由于上面答案中的代码已经过时(我试过了)......你可以看看threex.domevents library。它在我的情况下成功了。

threex.domevents 是一个 three.js 扩展,它在您的 3d 场景中提供 dom 事件。总是努力与平常保持接近 实践中,事件名称与 DOM 中的相同。语义是 同样,这使得这一切都非常容易学习。目前, 可用事件有 click、dblclick、mouseup、mousedown、mouseover 然后鼠标移开。

这是一个使用它的例子:

http://bl.ocks.org/fabiovalse/2e8ae04bfce21af400e6

【讨论】:

以上是关于在三个js中使用鼠标悬停更改网格颜色的主要内容,如果未能解决你的问题,请参考以下文章

d3.js 在鼠标悬停时更改折线图点的颜色和大小

在菜单组件中鼠标悬停时更改按钮的图标和文本颜色

在鼠标悬停时更改背景颜色并在鼠标悬停后将其删除

使用对象时如何在鼠标悬停时更改 SVG 笔触颜色

如何在 Material ui 数据表中悬停或鼠标悬停时更改表格行背景颜色

将鼠标悬停在图像上时如何更改 SVG 的颜色?