分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

基于WebGL(ThingJS)的平面图导航,室内导航,3D聚焦 (二)

发布时间:2023-09-06 02:30责任编辑:赖小花关键词:WebWebGL

前言

基于WebGL架构的3D可视化平台—平面图导航(一)中已经完成了iframe面板与我们的3D场景的简单交互,下面我们继续完善并给iframe页加上鼠标悬停事件让iframe页的img标签和我们场景中的obj一起动起来。

实现

第一步,还是使用之前的场景接着上次的继续,先编写iframe页。给每一个img标签都加上onmouseover、onmouseout 事件。

<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<meta name="viewport" content="width=device-width, initial-scale=1.0"> ???<meta http-equiv="X-UA-Compatible" content="ie=edge"> ???<title>Document</title> ???<style> ?????.total_image { ???????margin : 20px; ???????} ???????.total_image img{ ???????????cursor: pointer; ???????????transition: all 0.6s; ???????????width: 50px; ???????} ???????.total_image img:hover{ ???????????transform: scale(1.5); ???????????position:relative; ???????????z-index:100; ???????} ???</style></head><body><div class="total_image" style="width: 500px;height: 280px;background-size: 100% auto"> ???<img class="model_imag" src="发电室1.jpg" style="float: left;display: block;width: 85px;height: 84px" onclick="onClick(‘PowerGenerationGroup_01‘,‘viewPoint_1‘)" onmouseover="onMouseOver(‘PowerGenerationGroup_01‘,‘viewPoint_1‘)" onmouseout="onMouseOut(‘PowerGenerationGroup_01‘)"> ?????????????????<img class="model_imag" src="发电室2.jpg" style="float: left;display: block;width: 78px;height: 84px" onclick="onClick(‘PowerGenerationGroup_02‘,‘viewPoint_2‘)" onmouseover="onMouseOver(‘PowerGenerationGroup_02‘,‘viewPoint_2‘)" onmouseout="onMouseOut(‘PowerGenerationGroup_02‘)"> ?????????????????<img class="model_imag" src="发电室3.jpg" style="float: left;display: block;width:170px;height: 84px" onclick="onClick(‘PowerGenerationGroup_03‘,‘viewPoint_3‘)" onmouseover="onMouseOver(‘PowerGenerationGroup_03‘,‘viewPoint_3‘)" onmouseout="onMouseOut(‘PowerGenerationGroup_03‘)"> ?????????????????<img class="model_imag" src="发电室4.jpg" style="float: left;display: block;width:167px;height: 84px" onclick="onClick(‘PowerGenerationGroup_04‘,‘viewPoint_4‘)" onmouseover="onMouseOver(‘PowerGenerationGroup_04‘,‘viewPoint_4‘)" onmouseout="onMouseOut(‘PowerGenerationGroup_04‘)"> ?????????????????<div style="display: block;float: left;width: 100px;height: 145px;background-color:white"> ???????<img class="model_imag" src="办公室1.jpg" style="float: left;display: block;width:100px;height: 60px" onclick="onClick(‘Office‘,‘viewPoint_5‘)" onmouseover="onMouseOver(‘Office‘,‘viewPoint_5‘)" onmouseout="onMouseOut(‘Office‘)"> ???????<img class="model_imag" src="返回.png" style="float: left;display: block;width:100px;height: 80px" onclick="initViewPoint()"> ???</div> ???<img class="model_imag" src="发电室5.jpg" style="float: right;display: block;width:123px" onclick="onClick(‘PowerGenerationGroup_05‘,‘viewPoint_8‘)" onmouseover="onMouseOver(‘PowerGenerationGroup_05‘,‘viewPoint_8‘)" onmouseout="onMouseOut(‘PowerGenerationGroup_05‘)"> ??????????????????<img class="model_imag" src="会议室1.jpg" style="float: left;display: block;width: 138px;height: 145px" ??onclick="onClick(‘BoardRoom_01‘,‘viewPoint_6‘)" onmouseover="onMouseOver(‘BoardRoom_01‘,‘viewPoint_6‘)" onmouseout="onMouseOut(‘BoardRoom_01‘)"> ?????????????????<img class="model_imag" src="会议室2.jpg" style="float: left;display: block;width: 138px;height: 145px" ??onclick="onClick(‘BoardRoom_02‘,‘viewPoint_7‘)" onmouseover="onMouseOver(‘BoardRoom_02‘,‘viewPoint_7‘)" onmouseout="onMouseOut(‘BoardRoom_02‘)"> </div><script> ???function onClick(viewPoint,target){ ???????window.parent.onClick(viewPoint,target); ???}function onMouseOver(targetObj,viewPoint){ ???window.parent.onMouseOver(targetObj,viewPoint); ???} ?function onMouseOut(targetObj){ ???????window.parent.onMouseOut(targetObj); ???}function initViewPoint(){ ???????window.parent.initViewPoint(); ???}</script></body></html>

  

第二步,房间里的物体不要要让他“飞起来”,还要给他加一个“底座”。这里叫他SurveillanceCamera类,在自己编写类的时候一定要注意,想要当前类生效一定要继承THING.Thing,并且THING.factory.registerClass(‘ClassName’, ClassName);

class SurveillanceCamera extends THING.Thing { ???constructor(app) { ???????super(app); ???????this.app = app; ???????this.isFrustum = true; ???????this.opacity = 1; ???????this.color = 0xff00ff; ???????this.vertices = []; ???????this.near = 0.1; ???????this.camera = null; ???????this.node = new THREE.Object3D(); ???????this._frustum = new THREE.Frustum(); ???????this._projScreenMatrix = new THREE.Matrix4(); ???} ???setup(param) { ???????super.setup(param); ???????this.fov = param[‘fov‘]; ???????this.aspect = param[‘aspect‘]; ???????this.far = param[‘far‘]; ???????this.alpha = param[‘alpha‘]; ???????this.lineAlpha = param[‘lineAlpha‘]; ???????this.setupComplete(param); ???} ???setupComplete(param) { ???????super.setupComplete(param); ???????this.build(); ???} ???build() { ???????if (this.node.children.length > 0) { ???????????this.node.children = []; ???????} ???????if (this.camera != null) { ???????????this.camera = null; ???????} ???????var h = this.far * Math.tan(this.fov * 0.5 * 0.017453293); ???????var w = this.aspect * h; ???????var geometry = new THREE.Geometry(); ???????this.vertices = [new THREE.Vector3(0, 0, 0), new THREE.Vector3(w, -h, -this.far), new THREE.Vector3(w, h, -this.far), new THREE.Vector3(-w, h, -this.far), new THREE.Vector3(-w, -h, -this.far)]; ???????var faces = [new THREE.Face3(0, 1, 2), new THREE.Face3(0, 2, 3), new THREE.Face3(0, 3, 4), new THREE.Face3(0, 4, 1), new THREE.Face3(3, 4, 1), new THREE.Face3(3, 1, 2)]; ???????geometry.vertices = this.vertices; ???????var line_mat = new THREE.LineBasicMaterial({ ???????????color: "#b4f5f8", ???????????opacity: this.lineAlpha || 0.5, ???????}) ???????var texture = THREE.ImageUtils.loadTexture("images/light2.png"); ???????texture.wrapS = THREE.RepeatWrapping; ???????texture.wrapT = THREE.RepeatWrapping; ???????var frustum_mat = new THREE.MeshBasicMaterial({ ???????????color: "#0aa5ff", ???????????opacity: this.alpha || 0.5, ???????????transparent: true, ???????????side: THREE.DoubleSide, ???????}); ???????var line_mesh = new THREE.Line(geometry, line_mat); ???????var frustum_mesh = new THREE.Mesh(geometry, frustum_mat); ???????geometry.faces = faces; ???????this.node.add(frustum_mesh, line_mesh); ???????this.camera = new THREE.PerspectiveCamera(this.fov, this.aspect, this.near, this.far); ???????this.camera.position.set(this.position[0], this.position[1], this.position[2]); ???????this.camera.rotation.copy(this.node.rotation); ???????this.camera.updateMatrixWorld(true); ???????this._updateFrustum(); ???} ???setPosition() { ???????this.camera.position.set(this.position[0], this.position[1], this.position[2]); ???????this.camera.updateMatrixWorld(true); ???????this._updateFrustum(); ???} ???_updateFrustum() { ???????if (this.camera) { ???????????this._projScreenMatrix.multiplyMatrices(this.camera.projectionMatrix, this.camera.matrixWorldInverse); ???????????this._frustum.setFromMatrix(this._projScreenMatrix); ???????} ???} ???intersectsObject(object) { ???????this._updateFrustum(); ???????return this._frustum.intersectsObject(object); ???} ???intersectsBox(box) { ???????this._updateFrustum(); ???????return this._frustum.intersectsBox(box); ???} ???intersectsSphere(sphere) { ???????this._updateFrustum(); ???????return this._frustum.intersectsSphere(sphere); ???} ???intersectsSprite(sprite) { ???????this._updateFrustum(); ???????return this._frustum.intersectsSprite(sprite); ???}}THING.factory.registerClass(‘SurveillanceCamera‘, SurveillanceCamera);

  

第三步,鼠标悬浮事件和鼠标离开事件,这里我们使用了之前创建的SurveillanceCamera类为obj加上了一个“底座”。

//鼠标悬浮事件function onMouseOver(targetObj,viewPoint) { ???if (currentModule != null) ???????return; ???overModule = app.query(targetObj)[0]; ???overModule.style.boundingBox = true; ???overModule.moveTo({ ???????"offset": [0, 6, 0], ???????"time": 80, ???}); ???sCamera = app.create({ ???????type: ‘SurveillanceCamera‘, ???????name: ‘SurveillanceCamera_‘, ???????position:app.query(viewPoint)[0].position, ???????fov: 65, ???????aspect: 1.3, ???????far: 6, ???}); ???sCamera.angleX = 90; ???sCamera.style.opacity = 0.1;}//鼠标离开事件function onMouseOut(targetObj) { ???if (currentModule != null) ???????return; ???if (sCamera) { ???????sCamera.destroy(); ???????sCamera = null; ???} ???outModule = overModule; ???outModule.style.boundingBox = false; ???outModule.stopMoving(); ???outModule.position = [0, 0, 0]; ???outModule = null;}

  

演示地址:http://www.thingjs.com/guide/sampleindex.html?name=/uploads/wechat/S2Vyd2lu/Demo_平面图导航.js

总结

利用iframe与ThingJS进行交互完成了平面图导航功能,通过自制的HTML界面,嵌入ThingJS的面板中,形成一个可自定义的导航界面,通过偏移实现相应的视觉效果。
制作一个视锥,达到投放影像的效果,这里运用面向对象的方式是为了,能够更快捷的创建视锥,起到复用的作用。
在制作过程中,将物体悬浮的过程时出现了问题,发现如果快速的操作鼠标,物体不会达到预期的视觉效果,例如,鼠标快速的在两个导航图之间切换时,对应的两个物体会不断的上升,尽管将上升与还原的速度加快,也依然无法解决问题。最后解决的办法是:新添加一个变量,将上一次悬浮的物体记录下来,就是文中的 outModule,通过对 outModule 单独操作来解决影响问题。

基于WebGL(ThingJS)的平面图导航,室内导航,3D聚焦 (二)

原文地址:https://www.cnblogs.com/thingjs/p/10273368.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved