在三个 js 中使用鼠标悬停更改网格的颜色
Change color of mesh using mouseover in three js
我已经使用 jsonloader 和 three.js 编写了一个显示多个网格的 WebGL 脚本,现在我想添加 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 变体来尝试让这种效果只在鼠标悬停在网格上时起作用,但我无法让它起作用——它只是保持红色。谁能建议我如何修改我的脚本?
谢谢。
您必须在鼠标移开时将颜色设置回原始颜色,这不会自动发生...
检查this example on http://stemkoski.github.io 具体更新方法:
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;
}
由于上面答案中的代码已经过时(我试过了)...你可以看看threex.domevents library。它在我的案例中起到了作用。
threex.domevents is a three.js extension which provide dom events inside your 3d scene. Always in a effort to stay close to usual
pratices, the events name are the same as in DOM. The semantic is the
same too, which makes it all very easy to learn. Currently, the
available events are click, dblclick, mouseup, mousedown, mouseover
and mouse out.
这是一个使用它的例子:
我已经使用 jsonloader 和 three.js 编写了一个显示多个网格的 WebGL 脚本,现在我想添加 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 变体来尝试让这种效果只在鼠标悬停在网格上时起作用,但我无法让它起作用——它只是保持红色。谁能建议我如何修改我的脚本?
谢谢。
您必须在鼠标移开时将颜色设置回原始颜色,这不会自动发生...
检查this example on http://stemkoski.github.io 具体更新方法:
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;
}
由于上面答案中的代码已经过时(我试过了)...你可以看看threex.domevents library。它在我的案例中起到了作用。
threex.domevents is a three.js extension which provide dom events inside your 3d scene. Always in a effort to stay close to usual pratices, the events name are the same as in DOM. The semantic is the same too, which makes it all very easy to learn. Currently, the available events are click, dblclick, mouseup, mousedown, mouseover and mouse out.
这是一个使用它的例子: