Threejs是一个非常棒的图形库,可是对于一些交互逻辑,实现起来就没有那么容易了,这篇我们来讲解下如何实现一些常见的交互操作,比如点击、mouseover等效果。
首先来看看Threejs是如何实现交互的。在3d的世界中,我们选取一个物体不像2d平面立面那么简单,因为我们所对应的是一个3维的世界,而鼠标所在的屏幕是一个2d的世界。这个时候Threejs会为我们提供一个叫做Raycaster的类,为我们提供的是一个射线,然后我们可以根据不同的方向去发射射线,根据射线是否被阻挡,来判断我们是否碰到了物体。
我们来看看如何使用Raycaster类来实现鼠标滑过物体的显示效果,首先我们实例化raycaseer的对象,以及一个记录鼠标位置的坐标mouse,选中的3d模型selectedObject ,选中的3d模型材质selectedMaterial,高亮的材质hightLightMaterial。
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var selectedObject = null;
var selectedMaterial = null;
var hightLightMaterial = new THREE.MeshBasicMaterial({ color: 'green' });
然后我们在主循环中实现raycaster的射线测试工作
function render() {
requestAnimationFrame(render);
//设置射线从摄像机视角开始,沿着坐标射出
raycaster.setFromCamera(mouse, camera);
//获取射线击中的Objects
var intersects = raycaster.intersectObjects(cubes, true);
if (intersects.length > 0) {
var obj = intersects[0].object;
if (selectedObject != obj) {
//设置选中效果
setSelectedStatus(obj);
}
}
else {
//no object intersected 恢复原先的显示
restoreObjectStatus();
}
renderer.render(scene, camera);
};
<span class="redactor-invisible-space"> function setSelectedStatus(obj) {
if (selectedObject)
restoreObjectStatus();
selectedObject = obj;
selectedMaterial = obj.material;
selectedObject.material = hightLightMaterial;
}
function restoreObjectStatus() {
if (selectedObject)
selectedObject.material = selectedMaterial;
selectedObject = null;
selectedMaterial = null;
}
<span class="redactor-invisible-space">
</span></span>
实现了mouseover以后,点击事件就显得比较简单了,我们只需要在注册mousedown事件,然后判断是否有选中object
document.addEventListener('mousedown', onDocumentMouseDown, false);
<span class="redactor-invisible-space">function onDocumentMouseDown(event) {
boxHelper.update(selectedObject);
boxHelper.visible = true;
}</span>
boxhelper是一个显示object外框的辅助类,我们用来显示选中效果,初始化代码如下
var boxHelper = new THREE.BoxHelper(camera, 0xff0000);
boxHelper.visible = false;
scene.add(boxHelper);
最终效果如下:
在线demo:http://tmp.linhongxu.com/learnThreejs/interactive.html
转载自:http://www.linhongxu.com/post/view?id=228