龙空技术网

three.js之模型区域选中方法

爱吃稻的稻草人 638

前言:

当前大家对“js选中效果”大体比较注重,兄弟们都需要知道一些“js选中效果”的相关文章。那么小编在网络上收集了一些有关“js选中效果””的相关内容,希望咱们能喜欢,朋友们快快来了解一下吧!

今天从ui那边拿到一个城镇模型,样子长这样的

3d模型

要实现的效果是选择这个模型中的某个房子,实现交互。效果如下

交互效果

导入模型和可能遇到的问题模型太大了在视图中调试半天也不出现。

可以对模型的大小进行了缩放,并且通过计算xyz的最远和最近的2点确定中心点,将模型放置在视图的中心位置。核心代码如下:

objLoader.load('./obj/house.obj', function (obj) {		console.log(obj)		obj.traverse(function (child) {			if (child instanceof THREE.Mesh) {				child.material = new THREE.MeshLambertMaterial({					color: 0x2397F6,					side: THREE.DoubleSide				});			}		});		obj.scale.set(0.05, 0.05, 0.05)		var box = new THREE.Box3();		box.expandByObject(obj);		var x = (box.max.x + box.min.x) / 2;		var y = (box.max.y + box.min.y) / 2;		var z = (box.max.z + box.min.z) / 2;		obj.position.set(0 - x, 0 - y, 0 - z);		obj.castShadow = true;		obj.receiveShadow = true;		let wrapper = new THREE.Object3D();		//模型在场景中实际位置		var pt = {			x: 0,			y: 0,			z: 0		};		wrapper.position.set(pt.x, pt.y, pt.z);		wrapper.add(obj);		scene.add(wrapper);		render();	});
点击事件

three.js通过射线检测我们所点击的对象。

这里我们需要将鼠标的x,y点转化为空间坐标。这里简单地讲下原理(不想看的也可以跳过,直接拷贝公式)。

原理红色区域代表视图界面,空间坐标区间设置为[-1,1]左上角黑点是鼠标的原点(0,0),我们空间坐标的原点在视图中心(0,0)对应(window.innerWidth/2,window.innerHeight/2),现在鼠标点击的点(x,y)我们要转化成空间坐标(a,b),对应的公式:

x = event.clientX  // 鼠标点击的位置x1=x-window.innerWidth/2; // (减去空间坐标原点)a=x1/(window.innerWidth/2)  // (空间坐标在[-1,1]之间,window.innerWidth/2  代表长度1)// 化简后得到a=(event.clientX / window.innerWidth) * 2 - 1

分析图

点击事件代码

const onMouseMove = (event) => {		// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)		this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1		this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1		tooltip.style.left = event.clientX + 2 + 'px'		tooltip.style.top = event.clientY - 200 + 'px'		animate()	}	window.addEventListener('mousedown', onMouseMove, false)	var lastPick = null	function animate() {		// 通过摄像机和鼠标位置更新射线		raycaster.setFromCamera(mouse, camera)		// 算出射线 与当场景相交的对象有那些		const intersects = raycaster.intersectObjects(			scene.children,			true		)		// 恢复上一个模型状态		if (lastPick) {			this.tooltip.style.visibility = 'hidden'			this.lastPick.object.material.color.set('#2397F6')		}		lastPick = intersects.find(			(item) => {				return item			}		)		if (lastPick) {      // 模型状态修改			console.log(this.lastPick.object.name)			this.lastPick.object.material.color.set('red')      // 这里的模型名称是ui做3d时候命名的,可以自定义修改			this.tooltip.innerHTML = '模型名称:' + this.lastPick.object.name			this.tooltip.style.visibility = 'visible'		}		render()	}
结语

以上就是所有的核心代码。对于模型要求整体性要高一点,不能太零散,否则会出行点击高楼时候,出现了避雷针没有被选中现象。

标签: #js选中效果