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

前言

基于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 单独操作来解决影响问题。

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

时间: 2024-10-10 04:17:50

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

RGB-D 室内导航 paper

摘要: 最近打算使用Kinect实现机器人的室内导航,收集了近年来的一些比较好的文章.<基于Kinect系统的场景建模与机器人自主导航>.<Mobile Robots Navigation in Indoor Environments Using Kinect>.<Using a Depth Camera for Indoor Robot Localization and Navigation>.<Depth Camera Based Indoor Mobile

技术杂谈 之 室内导航

这两年AI很火热,各种无人驾驶.机器人.无人机层出不穷,新零售也是AI的一个很热的方向.AI与新零售的结合现在也有不少案例了,比如京东X无人超市.超嗨的智能购物车等等.在大型百货商场或者超市,有一个很典型的场景就是室内导航,比如查询一个你不知道具体位置的品牌店铺.寻找一个不知道摆放在哪的商品.本篇就粗略的介绍一下这种室内导航所涉及的技术. 背景 在说室内导航之前,先来聊聊室外导航技术那些事.室外的导航现在已经用的很广泛了,各种汽车导航.XX地图.位置共享服务等等.主要使用的技术就是GNSS,Gl

精准时间同步应用于物联网:室内导航

物联网(Internet of Things)基于计算机互联网,以传统电信网为信息承载体,利用传感器.射频识别(RFID)技术.全球定位系统.红外感应器.激光扫描器.气体感应器等各种装置与技术,让物体(商品)与网络相连,实时采集任何需要信息交换.定位.跟踪.监管.连接.互动的物体或过程的声.光.热.电.力学.化学.生物.位置等各种所需信息,试图构造一个万事万物相连的网络.在这个网络中,无需人为干预,物品(商品)之间能够自动识别与彼此 "交流",从而实现信息互联互通.全面共享.图1 当前

室内导航开发笔记

IndoorAtlas室内导航iOS版使用方法: 引入协议  IALocationManagerDelegate 实现方法 - (void)indoorLocationManager:(IALocationManager *)manager didUpdateLocations:(NSArray *)locations; - (void)indoorLocationManager:(IALocationManager *)manager didEnterRegion:(IARegion *)re

一款基于jQuery仿淘宝红色分类导航

今天给大家分享一款基于jQuery仿淘宝红色分类导航.这款分类导航适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div id="nav"> <div class="area clearfix"> <div class="separate"> </div> <div

基于 jQuery 实现的精致作品集图片导航效果

今天,我们要用 jQuery 来创建一个作品集图像的导航模板.我们的想法是,以分组的方式显示一组作品集,并通过二维的方式(水平/垂直)来浏览.任一箭头或当前图像下方的小盒子可以作为导航使用. 在线演示     下载源码 您可能感兴趣的相关文章 网站开发中很有用的 jQuery 效果[附源码] 分享35个让人惊讶的 CSS3 动画效果演示 十分惊艳的8个 HTML5 & JavaScript 特效 Web 开发中很实用的10个效果[源码下载] 12款经典的白富美型 jQuery 图片轮播插件 本文

10款基于jQuery打造的大屏带导航焦点图

1.纯CSS3实现3D效果iPhone 6动画 iPhone 6刚发布不久,今天我们就用纯CSS3来把iPhone 6的外观简单地绘制出来,记得是用纯CSS3实现的哦,没有用一张图片.由于CSS3特性的运用,整个iPhone 6手机边框带有阴影,很有立体3D的视觉效果. 在线演示 源码下载 2.纯CSS3天气动画图标 这是一款基于纯CSS3的天气动画图标,利用CSS3特性,我们在这里绘制了7个关于天气的图标,并且每一个图标都有一套代表当前天气的动画特效,比如下雨天气,就会有下雨的动画,下雪也是如

jquery特效-基于jQuery仿淘宝红色分类导航

今天给大家分享一款基于jQuery仿淘宝红色分类导航.这款分类导航适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 实现的代码. html代码: <div id="nav"> <div class="area clearfix"> <div class="separate"> </div> <div class="

基于WebGL的炫酷元素背景水波涟漪jQuery特效

jquery.ripples是一款基于WebGL的效果非常炫酷的元素背景水波涟漪jQuery特效插件.该jQuery插件通过强大的WebGL,可以在指定的元素上添加一个水波层,制作出水波涟漪的炫酷效果,并且可以使用鼠标来和它进行互动. WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以