以真实设备为模型,搭建出设备面板,并实时获取设备运行参数,显示在设备面板上,这相比于纯数值的设备监控系统显得更加生动直观。今天我们就在HT for Web的3D技术上完成设备面板的搭建。
我们今天模拟的设备是机房设备,先来目睹下最终效果:http://www.hightopo.com/demo/blog_3d_20150810/server.html
我来解释下这个模型,一个带有透明玻璃门的机柜,机柜里装有5台设备,门可以开合,设备可以插拔,那么我么该如何搭建这样的设备呢?方法不难,我们一步一步来。
我们先从设备开始,设备的示意图如下:
看起来有模有样的,其实呢,它就是一个长方体,然后在长方体的正面贴上一张图片,这样子设备的壳就出来了,创建代码如下:
var node = createNode([0, 0, 0], [475, 100, 0]); node.s({ 'front.image': 'panel', 'all.color': '#E6DEEC' }); node.setToolTip('Double click to pop the server’);
其中设置设备的正面图片的方法是通过设置节点的front.image样式属性来实现的,在代码中将front.image属性设置为’panel’,而’panel’属性是已经通过ht.Default.setImage()方法注册了的图片的别名,在代码中还设置了长方体各个面的颜色和鼠标悬停时的提示语。
在代码中还调用了createNode()的方法,该方法并没有做什么特殊的操作,只是将创建3D拓扑节点的代码封装起来,精简代码,避免相同的代码重复书写,具体的封装如下:
/** * 创建3D拓扑节点,并添加到dataModel中 * @param p3 {array} 位置信息 * @param s3 {array} 长宽高信息 * @returns {ht.Node} 3D拓扑节点 */ function createNode(p3, s3) { var node = new ht.Node(); node.s({ 'shape' : 'rect' }); node.p3(p3); node.s3(s3); dataModel.add(node); return node; }
该方法通过传入位置信息和大小信息创建出一个3D拓扑节点,并添加到dataModel中,最后返回该节点对象。
刚刚我们只是创建了设备的外壳而已,在设备上又部分端口是被被占用的,所以接下来我们要做的就是填充设备端口,仔细看了下设备的端口形状,发现形状是不规则的呢,那么设备端口该如何填充呢?我们只需要找一个和端口形状一样的图片贴在长方体的正面,然后套在设备上就可以了,具体的实现如下:
/** * 创建端口节点,并吸附到指定的节点上 * @param indexes {array} 端口位置信息 * @param host {ht.Node} 被吸附的节点对象 */ function createPort(indexes, host) { var p3 = host.p3(), s3 = host.s3(), x = -s3[0] / 2, y = 100 / 2 + p3[1], z = 1 + s3[2] / 2; indexes.forEach(function(index) { var port = new ht.Node(); port.setName('Port'); port.s({ 'front.image' : 'port_green', 'all.light' : true }); port.setHost(host); port.setSize3d(28, 23, 10); if (index % 2 === 0) { var col = (index - 2) / 2; port.setPosition3d(x + 67.5 + col * 32, y - 60.5, z); port.s({ 'front.uv' : [0, 1, 0, 0, 1, 0, 1, 1] }); } else { var col = (index - 1) / 2; port.setPosition3d(x + 67.5 + col * 32, y - 26.5, z); } dataModel.add(port); }); }
在设备上总共有20个端口,我们通过传入的端口位置信息来确定创建出来的节点位置,仔细观察设备端口可以发现,第二排的端口和第一排的端口方向不一样,所以在创建第二排的端口时需要通过设置front.uv属性来控制贴图的翻转,当然贴图也是我们事先注册好了的。
好了,到这里我们的设备模型就构建出来了,那么接下来就是创建机柜了,机柜的创建就和设备外壳的创建基本相似,不一样的地方在于,机柜有一个门,这个门有开合的功能,由于拓扑节点无法单独对节点的某一面分离出来做旋转操作,所以门必须是一个单独的拓扑节点,我们先来看看机柜的效果图:
效果图种,我们把门稍微装饰了一下,在门的边缘上加上了蓝色的贴边,让门看起来更有质感,效果图和思路都有了,代码自然而然就出来了,瞧瞧下面的代码,有一点点小复杂哦。
var h = 1000, w = 477, d = 400, k = 20; // 创建机柜 var main = createNode([0, 0, 0], [w, h, d]); main.s({ 'all.color' : '#403F46', 'front.visible' : false }); // 创建门 var face = new ht.Shape(), s = {'all.visible' : false, 'front.visible' : true}; dataModel.add(face); face.addPoint({x : -w / 2, y : d / 2 - 1}); face.addPoint({x : w / 2, y : d / 2 - 1}); face.addPoint({x : w + w / 2, y : d / 2 - 1}); face.setSegments([1, 2, 1]); face.setTall(h); face.setThickness(1); face.s(s); face.setHost(main); face.s({ 'all.color' : 'rgba(0, 40, 60, 0.7)', 'all.reverse.flip' : true, 'all.transparent' : true, '3d.movable' : false }); face.face = true; face.open = false; face.angle = -Math.PI * 0.6; face.setToolTip('Double click to open the door'); // 创建门的贴边 var up = createNode([0, h / 2 - k / 2, d / 2], [w, k, 1], false, false).s(s), down = createNode([0, -h / 2 + k / 2, d / 2], [w, k, 1], false, false).s(s), right = createNode([w / 2 - k / 2, 0, d / 2], [k, h, 1], false, false).s(s), left = createNode([-w / 2 + k / 2, 0, d / 2], [k, h, 1], false, false).s(s); up.setHost(face); down.setHost(face); left.setHost(face); right.setHost(face);
代码的逻辑是这样的,先创建一个长方体作为机柜的外壳,然后将长方体的正面设置为隐藏,然后创建一个多边形作为门,将门设为浅蓝色半透明,最后创建4个蓝色长方体贴到门的边缘作为装饰,如此一个机柜就搭建完成了。
设备模型有了,机柜有了,接下来的工作就是将两者合并起来,方法很简单,就是创建设备并将设备吸附到机柜上,具体的代码如下:
var num = 5, start = 400; for (var i = 0; i < num; i++) { var y = start - 170 * i, z = (d - 30) / 2; var node = createNode([0, y, 0], [w - 2, 100, d - 30]); node.s({ 'front.image' : 'panel', 'all.color' : '#E6DEEC', 'all.reverse.cull' : true, '3d.movable' : false }); node.pop = false; node.setToolTip('Double click to pop the server'); node.setHost(main); createPort([1, 2, 3, 4, 5, 6, 7, 13, 16, 17, 20], node); }
还记得前面构建设备模型和机柜门的代码中,我们对这两个模型添加了鼠标悬停时的提示内容,双击可以打开门,双击可以抽出设备,那么我们现在就来实现这两个效果,首先我们来分析下具体的实现方案:
双击的事件要添加在哪里呢?对每个拓扑节点做监听吗?这是最直接的方法,但是这样做的话,有多少节点将会有多少个对应的处理函数,而且同一类型的处理函数又是一样的,那么这就会导致系统资源的浪费,所以对每个节点做双击的监听方案是不可取的,那么我们该如何处理双击事件呢?我们可以换个角度思考,所有的节点都是添加到3D拓扑组件上的,那么我们是否可以通过监听3D拓扑组件的双击事件,然后通过事件对象获取到对应的节点,然后通过判断节点上设置的自定义标识属性来做相应的处理,具体的代码如下:
// 监听3D拓扑组件的dataDoubleClicked事件 g3d.onDataDoubleClicked = function(data, e, dataInfo) { // 若果节点为门 if (data.face) { // 遍历所有吸附在机柜下的节点 data.getHost().getAttaches().each(function(attach) { // 如果节点状态为弹出,则调用函数还原节点位置 if (attach.pop) { toggleData(attach); } }); } // 如果节点为端口节点,则触发其所吸附设备的双击事件 else if (data.a('port')) { toggleData(data.getHost()); return; } toggleData(data); };
阅读上面的代码,大家会发现实现的方案和我们提到的方案不太一样,我们通过监听3D拓扑组件的dataDoubleClicked事件就可以直接获取到被双击的节点对象,而无需我们自己通过事件对象获取对应的节点对象,当然就监听dataDoubleClicked事件了。
在代码中,我们调用了toggleData()方法来处理双击事件,具体的处理代码如下:
/** * 节点双击处理函数 * @param data {ht.Node} 被双击的节点 */ function toggleData(data) { var angle = data.angle, pop = data.pop; // 当前双击的对象为门 if (angle != null) { if (anim) { anim.stop(true); } var oldAngle = data.getRotation(); if (data.open) { angle = -angle; } data.open = !data.open; anim = ht.Default.startAnim({ action : function(t) { data.setRotation(oldAngle + t * angle); } }); } // 当前双击的对象为设备 else if (pop != null) { if (anim) { anim.stop(true); } var p3 = data.p3(), s3 = data.s3(), dist = (pop ? -s3[2] : s3[2]) / 2; data.pop = !data.pop; anim = ht.Default.startAnim({ action : function(t) { data.p3(p3[0], p3[1], p3[2] + t * dist); } }); } }
在代码中,根据节点预设的不同的属性值来确认该做什么处理,如果节点对象是门的话,则通过ht.Default.startAnim()方法缓慢的修改门的rotation;如果节点对象是设备的话,则缓慢修改设备的position。
到这里,今天的Demo的所有表现和功能就完成了,今天的内容中有设计到节点的style应用,我没有做深入的讲解,后续会给大家一一介绍,感兴趣的朋友可以通过HT for Web的样式手册来了解更多的内容。
下面附上今天的Demo源码及视频。
我已经把今天的Demo上传至官网了,感兴趣的朋友可以点击这里访问。
http://www.hightopo.com/demo/blog_3d_20150810/server.html
http://v.youku.com/v_show/id_XMTMwNTY2ODE0NA==.html
相关推荐
用 WebGL 渲染的 3D 机房现在也不是什么新鲜事儿了,这篇文章的主要目的是说明一下,3D 机房中的 eye 和 center 的问题,刚好在项目中用上了,好生思考了一番,最终觉得这个例子最符合我的要求,就拿来作为记录。...
HTML5是下一代网页标记语言,它的出现极大地扩展了网页的交互性和功能,其中WebGL(Web Graphics Library)是一项关键的技术,它使得浏览器可以直接在用户的设备上进行硬件加速的3D图形渲染,无需任何插件。...
此外,它提供了丰富的图形元素库,如设备、线缆、标签等,能够快速构建出逼真的3D机房环境。在“3D机房Demo”中,我们可以看到TWaver如何将机柜、服务器、交换机等设备以三维形式呈现,并允许用户进行旋转、缩放、平...
【基于WEBGL纯js无框架3D机房源码】是一个技术含量较高的项目,它利用了WebGL技术,这是一种JavaScript API,允许在浏览器中进行交互式的3D图形渲染,无需插件支持。此项目的核心特点在于它没有依赖任何现有的...
在IT行业中,3D机房开源示例是一个非常有趣且实用的项目,它结合了前端技术和3D开发,为用户提供了一种可视化的方式来管理和监控数据中心。本文将深入探讨这个项目的相关知识点,包括3D开发的基本概念、Vizi框架的...
通过3D建模,可以构建出与实际机房布局一致的虚拟环境,用户可以通过交互式界面,如同身临其境般地查看机房内的设备分布、温度、湿度、电力供应等关键信息。这种可视化方式不仅提高了监控效率,也便于管理人员进行...
3D机房项目"是一个基于three.js库开发的三维可视化应用,主要用于模拟和展示数据中心的机房环境。这个项目利用WebGL技术在浏览器中渲染出逼真的3D场景,让操作者能够以第一人称视角或者上帝视角观察和互动。 ...
3D机房监控系统通过三维仿真技术,模拟真实环境,当设备出现异常时,对应的楼层会在三维模型上显示警告,便于快速定位问题。用户可以在虚拟环境中自由漫游,查看设备状态,甚至模拟操作,如开启机柜门等,提高了故障...
WebGL是一种在HTML5 Canvas元素中渲染3D图形的标准,它基于OpenGL ES 2.0,由Khronos Group维护。通过Three.js,我们可以利用WebGL的能力,轻松地构建复杂的3D场景。 实现3D机房效果,首先需要理解机房的基本架构和...
在3D机房展示中,这些数据可以被JavaScript解析并应用到3D模型上,实现动态的、基于真实数据的机房模拟。 在实际应用中,3D数据中心机房的WEB展示具有诸多优势。它能帮助管理人员更直观地了解机房的布局和设备状态...
3D机房不仅展示设备的物理形态,还可以结合数据可视化,例如用颜色或大小表示设备的温度、负载等参数,帮助运维人员直观理解机房状态。 总的来说,这个项目展示了如何利用three.js和jQuery创建一个交互式的3D机房...
"机房设备巡检报告" 机房设备巡检报告是对机房中各种设备的巡检和维护报告,旨在确保机房设备的正常运行和稳定运作。下面是对机房设备巡检报告的详细解析: 一、机房 UPS 系统巡检报告 机房 UPS 系统是机房中非常...
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料...用three.js构建的一个3D机房(源码+项目说明).zip
在本项目中,我们主要探讨如何使用Three.js、原生JavaScript和jQuery来创建一个3D机房模拟系统。这个系统不仅展示了一个逼真的3D环境,还具备实用的功能,如设备管理、告警处理和机柜布局调整。下面将详细阐述这些...
在构建3D机房时,开发者通常会使用"盒子模型"来代表机房中的硬件设备,如服务器和存储柜。这些模型可以由简单的几何形状(如立方体)组成,并通过调整尺寸和位置来精确匹配实际设备。 "路径"可能是指物体在3D空间中...
### 3D机房系统接口文档关键知识点 #### 1. 概述 3D机房系统的接口文档主要描述了该系统所提供的开放式应用程序接口(API),以便第三方能够调用并集成到自己的应用或服务中。该接口采用了RESTful Web Service的...
文件名"threeMachineRoom-master"可能是一个包含机房3D建模项目源代码或相关资料的文件,可能包括机房设计的3D模型、设备布局图、交互式演示等内容,对于理解和实践上述知识点非常有价值。在深入研究这个项目时,...