基于 WebGL(ThingJS)的室内平面图 2D/3D 导航 DEMO(Part 1)

简介: 前言 利用CampusBuilder来搭建自己的虚拟世界过程有这样一个问题:如何快速聚焦到虚拟场景的某一位置。当然我们可以创建几个按钮对应查找我们需要去的位置(参照物)并聚焦,但是按钮并不是很炫酷也不能很好的反馈给我们一些信息。


前言

利用CampusBuilder来搭建自己的虚拟世界过程有这样一个问题:如何快速聚焦到虚拟场景的某一位置。当然我们可以创建几个按钮对应查找我们需要去的位置(参照物)并聚焦,但是按钮并不是很炫酷也不能很好的反馈给我们一些信息。接下来我们就用平面导航图来解决这一问题。


实现

第一步,使用CampusBuilder搭建模拟场景,CampusBuilder操作简单,分分钟就可以上手。这里为每一个房间都创建一个小球作为视点参照物体并勾选预览时隐藏,这样不会对我们的场景造成影响,也便于我们聚焦到指定房间。注意:要将我们每个房间中的设备框选之后组合在一起,为下一阶段的做准备。


 


第二步,把我们编辑好的场景加载到ThingJS中。


//加载场景代码
var app = new THING.App({
	// 场景地址
	"url": "http://www.thingjs.com/./uploads/wechat/S2Vyd2lu/scene/Campus04",
});
//场景相关
//************************************************************************************/
app.on('load', function () {
    app.camera.flyTo({
        'position': [36.357131498969785, 61.953024217074265, 69.12160670337104],
        'target': [-1.3316924326803257, -4.9370371421622625, 33.619521849828544],
        'time': 2000,
    });
});



第三步,为平面图创建一块面板,并调整一下面板的位置以及大小。
图片下载地址:
链接:https://pan.baidu.com/s/1gmNjIj2ekbw1rO3MoujHqQ 提取码:i0c1


//面板相关
//************************************************************************************/
var panel = new THING.widget.Panel({
    closeIcon: false,
    dragable: false, 
    retractable: true,
    opacity: 0.9,
    hasTitle: true,
});
panel.width = 600;
panel.position = [0, 200];
var dataObj = {
    iframe: ''
};
var iframe = panel.addIframe(dataObj, 'iframe').caption('').setHeight("290px");


第四步,编写iframe页。写完记得将这个页面和图片上传到页面资源,资源 => 页面资源 => 按钮(上传) 。

<!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')" >
              
    <img class="model_imag" src="发电室2.jpg" style="float: left;display: block;width: 78px;height: 84px" 
			onclick="onClick('PowerGenerationGroup_02','viewPoint_2')" >
              
    <img class="model_imag" src="发电室3.jpg" style="float: left;display: block;width:170px;height: 84px" 
			onclick="onClick('PowerGenerationGroup_03','viewPoint_3')" >
              
    <img class="model_imag" src="发电室4.jpg" style="float: left;display: block;width:167px;height: 84px" 
			onclick="onClick('PowerGenerationGroup_04','viewPoint_4')" >
              
    <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')" >
        <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')" > 
              
    <img class="model_imag" src="会议室1.jpg" style="float: left;display: block;width: 138px;height: 145px"  alt="" 
			onclick="onClick('BoardRoom_01','viewPoint_6')">
              
    <img class="model_imag" src="会议室2.jpg" style="float: left;display: block;width: 138px;height: 145px"  alt="" 
			onclick="onClick('BoardRoom_02','viewPoint_7')" > 
</div>

<script>
    function onClick(viewPoint,target){
        window.parent.onClick(viewPoint,target);
    }
	function initViewPoint(){
        window.parent.initViewPoint();
    }
</script>
</body>
</html>


第五步,完成onClick()和initViewPoint()方法。

//事件相关
//************************************************************************************/
var currentModule = null;

//点击事件
function onClick(targetObj, viewPoint) {
    currentModule = app.query(targetObj)[0];
    currentModule.position = [0, 0, 0];
    currentModule.style.opacity = 1;
    app.camera.flyTo({
        'object': app.query(viewPoint)[0],
        'offset': [0, 13, 7],
        'time': 1000,
        complete: function () {
            currentModule.brothers.style.opacity = 0.3;
        }
    });
}
//返回事件
function initViewPoint() {
    currentModule.brothers.style.opacity = 1;
    currentModule = null;
    app.camera.flyTo({
        'position': [36.357131498969785, 61.953024217074265, 69.12160670337104],
        'target': [-1.3316924326803257, -4.9370371421622625, 33.619521849828544],
        'time': 1000,
    });
}


小结

第一部分我们主要完成了iframe与我们的3D场景的简单交互,这里也没有做什么特效只是做了一个点击事件。这里值得一提的是currentModule这个全局变量,开始我没有创建这个变量只是将我当前点击的物体obj.style.opacity = 1;obj.brothers.style.opacity = 0.3, 但是执行initViewPoint(){app.query(’.Thing’).style.opacity=1}无法将场景的opacity 属性还原(自己可以试一下,或者有解决方案留言)。第二部分我会给iframe页加上鼠标悬停事件让iframe页的img标签和我们场景中的obj一起动起来!


完整代码

可以粘到 ThingJS 网站在线开发环境运行 http://www.thingjs.com/guide/?m=sample


	//加载场景代码
var app = new THING.App({
	// 场景地址
	"url": "http://www.thingjs.com/./uploads/wechat/S2Vyd2lu/scene/Campus04",
});
//场景相关
//************************************************************************************/
app.on('load', function () {
    app.camera.flyTo({
        'position': [36.357131498969785, 61.953024217074265, 69.12160670337104],
        'target': [-1.3316924326803257, -4.9370371421622625, 33.619521849828544],
        'time': 2000,
    });
});
//面板相关
//************************************************************************************/
var panel = new THING.widget.Panel({
    closeIcon: false,
    dragable: false, 
    retractable: true,
    opacity: 0.9,
    hasTitle: true,
});
panel.width = 600;
panel.position = [0, 200];
var dataObj = {
    iframe: '/uploads/wechat/S2Vyd2lu/file/平面图导航/ifram.html'
};
var iframe = panel.addIframe(dataObj, 'iframe').caption('').setHeight("290px");

//事件相关
//************************************************************************************/
var currentModule = null;

//点击事件
function onClick(targetObj, viewPoint) {
    currentModule = app.query(targetObj)[0];
    currentModule.position = [0, 0, 0];
    currentModule.style.opacity = 1;
    app.camera.flyTo({
        'object': app.query(viewPoint)[0],
        'offset': [0, 13, 7],
        'time': 1000,
        complete: function () {
            currentModule.brothers.style.opacity = 0.3;
        }
    });
}
//返回事件
function initViewPoint() {
    currentModule.brothers.style.opacity = 1;
    currentModule = null;
    app.camera.flyTo({
        'position': [36.357131498969785, 61.953024217074265, 69.12160670337104],
        'target': [-1.3316924326803257, -4.9370371421622625, 33.619521849828544],
        'time': 1000,
    });
}

 

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
目录
相关文章
|
定位技术 API 网络架构
地图图层接入:从mapbox转向cesium
由于地图坐标系的不统一,地图图商提供的图层服务也各有特色,在图层对接的开发过程中常会遇到许多坑,从二维图层到三维图层,地图引擎mapbox再到cesium,本文将分享笔者在近期地图图层接入过程中总结的一些经验。
3611 10
|
5天前
|
JavaScript API 开发工具
(H5-Web3D-ThreeJS)在网页三维CAD中绘制窗户模型
本文介绍了如何使用mxcad3d在网页中创建一个简单的三维窗户模型。通过官方教程搭建环境,编写绘制窗户模型的代码,并在点击按钮后展示模型效果。最终模型包括窗框和玻璃部分,具备丰富的三维建模功能和便捷的API支持。
|
16天前
|
数据采集 监控 安全
厂区地图导航制作:GIS技术与路径导航算法融合
在智能化、数字化时代,GIS技术为厂区的运营管理带来了革命性变化。本文探讨了如何利用GIS技术,通过数据采集、地图绘制、路径规划、位置定位和信息查询等功能,打造高效、精准的智能厂区地图导航系统,提升企业的竞争力和管理水平。
22 0
厂区地图导航制作:GIS技术与路径导航算法融合
|
2月前
UE5使用Dash插件实现程序化地形场景制作
本文介绍了如何在Unreal Engine 5中使用Dash插件来实现程序化地形场景制作,包括插件激活、基本使用、资产导入路径和练习成果展示。
UE5使用Dash插件实现程序化地形场景制作
|
6月前
|
C#
halcon联合c#、WPF学习笔记三(dispatcherTimer实时相机显示)
halcon联合c#、WPF学习笔记三(dispatcherTimer实时相机显示)
276 1
halcon联合c#、WPF学习笔记三(dispatcherTimer实时相机显示)
|
移动开发 前端开发 JavaScript
分享8个前端可以制作360度WebVr全景视图框架
分享8个前端可以制作360度WebVr全景视图框架
1750 0
分享8个前端可以制作360度WebVr全景视图框架
|
算法 JavaScript 数据可视化
基于leaflet-velocity的二维动态风场展示
本文讲解了leaflet-velocity插件,并利用插件进行了模拟的动态风场、洋流等信息的综合展示,让读者掌握集成方式。
1030 0
基于leaflet-velocity的二维动态风场展示
|
存储 移动开发 数据可视化
使用 WebGL 为 HTML5 游戏创建逼真的地形
在本文中,我将分享我们应对这些有趣挑战之一的方法:一种创建逼真的大型地形的简单方法。
76 0
|
XML 人工智能 搜索推荐
Echarts实战案例代码(5):liquidFill水球组件利用svg path定制你自己的个性化图标动态图
Echarts实战案例代码(5):liquidFill水球组件利用svg path定制你自己的个性化图标动态图
439 0
|
移动开发 JavaScript 数据可视化
基于Three.js的全景展示框架-TPano
在一些全景展示类应用中,经常需要对采集到全景照片进行展示,一般情况下,可以通过制作人员使用pano2vr进行数据处理(教程可参见:实战!使用pano2vr生成html5全景页面),将处理好的数据发布至静态服务器,再关联相应位置即可完成全景展示(详情见基于Leaflet的全景综合展示实战)
689 1
基于Three.js的全景展示框架-TPano