基于HT for Web 3D技术快速搭建设备面板

2023-12-16 13:30

本文主要是介绍基于HT for Web 3D技术快速搭建设备面板,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

以真实设备为模型,搭建出设备面板,并实时获取设备运行参数,显示在设备面板上,这相比于纯数值的设备监控系统显得更加生动直观。今天我们就在HT for Web的3D技术上完成设备面板的搭建。

我们今天模拟的设备是机房设备,先来目睹下最终效果:

我来解释下这个模型,一个带有透明玻璃门的机柜,机柜里装有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://v.youku.com/v_show/id_XMTMwNTY2ODE0NA==.html

 

这篇关于基于HT for Web 3D技术快速搭建设备面板的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500639

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

Java Web指的是什么

Java Web指的是使用Java技术进行Web开发的一种方式。Java在Web开发领域有着广泛的应用,主要通过Java EE(Enterprise Edition)平台来实现。  主要特点和技术包括: 1. Servlets和JSP:     Servlets 是Java编写的服务器端程序,用于处理客户端请求和生成动态网页内容。     JSP(JavaServer Pages)

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

v0.dev快速开发

探索v0.dev:次世代开发者之利器 今之技艺日新月异,开发者之工具亦随之进步不辍。v0.dev者,新兴之开发者利器也,迅速引起众多开发者之瞩目。本文将引汝探究v0.dev之基本功能与优势,助汝速速上手,提升开发之效率。 何谓v0.dev? v0.dev者,现代化之开发者工具也,旨在简化并加速软件开发之过程。其集多种功能于一体,助开发者高效编写、测试及部署代码。无论汝为前端开发者、后端开发者