基于 HTML5 WebGL 的 3D 服务器与客户端的通信

这个例子的初衷是模拟服务器与客户端的通信,我把整个需求简化变成了今天的这个例子。3D 机房方面的模拟一般都是需要鹰眼来辅助的,这样找产品以及整个空间的概括会比较明确,在这个例子中我也加了,这篇文章就算是我对这次项目的一个总结吧。对了,这个例子我是参考一个 DEMO 来完成的,和示例中的显示有些不同,大家莫惊奇。

例子链接: http://www.hightopo.com/demo/3DEdgeFlow/index.html

本文动图:

这个例子没有设计师的参与,样式上面大家将就将就,但是我觉得还不错啊,哈哈~

进入正题,整个例子差不多用了 200 行的代码来实现的,这就是我喜欢用 HT 的原因,现在 Web3d 技术兴起,大体就是分为两派:插件派和 HTML5 派。HT 就是基于 HTML5 的,不需要安装任何插件,啊,跑题了。。。

首先,还是从场景的搭建开始,这个界面是在 body 体上添加了三个部分:3d 组件,属性组件以及拓扑组件(2d 组件)。添加的方式是这样的:为了最外层组件加载填充满窗口的方便性,HT 的所有组件都有 addToDOM 函数,其实现逻辑如下,其中 iv 是 invalidate 的简写:

addToDOM = function(){   var self = this,view = self.getView(),   style = view.style;document.body.appendChild(view);            style.left = '0';style.right = '0';style.top = '0';style.bottom = '0';      window.addEventListener('resize', function () { self.iv(); }, false);            
}

因为这个函数是将 style 中的位置都固定了,所以不能将所有的组件都用这个函数,我们按照这个函数的方式将拓扑组件和属性组件添加进界面中,3d 组件直接利用 addToDOM 函数即可:

dm = new ht.DataModel();
g3d = new ht.graph3d.Graph3dView(dm);//3d 组件
g3d.addToDOM();//将组件添加进 body 体中
g3d.setDashDisabled(false);//开启虚线流动
g3d.setMovableFunc(function(){//重载移动函数return false;//返回false,所有的图元都不可移动
});
g3d.setEye([-813, 718, 1530]);//设置 eye 
g3d.setCenter([140, -25, 217]);//设置 center(target)
gv = new ht.graph.GraphView(dm);//2d 组件
gv.getView().className = 'graphview';//HT 组件根层都是一个 div,通过 getView() 函数获取
document.body.appendChild(gv.getView());//将拓扑组件添加进 body 体中
gv.fitContent(true);//缩放平移整个拓扑以展示所有的图元

propertyView = new ht.widget.PropertyView(dm);//属性组件   
propertyView.getView().className = 'property';
propertyView.setWidth(240);//设置组件宽度
propertyView.setHeight(150);//高度
document.body.appendChild(propertyView.getView());

拓扑组件和属性组件的样式我就不再赘述了,只是设置了一个背景颜色以及 left right top bottom 位置而已。这里要声明一下,HT 组件一般都以设置 position 为 absolute 的绝对定位方式。

大家可能会好奇,这个鹰眼怎么生成的?在 HT 中,只要 2D 和 3D 共用同一个数据容器 dataModel 即可共同拥有所有在这个 dataModel 中的元素,并且位置都是对应的,只需要类似这种做法即可:

dm = new ht.DataModel();
g3d = new ht.graph3d.Graph3dView(dm);
gv = new ht.graph.GraphView(dm);

是不是非常简单。。。可以省去大把时间开发。。。

这个例子中除了连线之外的所有元素都是 ht.Node 类型的节点,所以我们将这个节点的创建方法封装一下,好重复利用:

function createNode(p3, s3, name, shape){//创建节点var node = new ht.Node();//创建类型为 ht.Node 类的节点dm.add(node);//将节点添加进数据容器 dataModel 中node.s({//设置节点的样式,s 为 setStyle 的简写'shape3d': shape,//指定节点的形体,这边是传入 3d 模型的 json 文件'label.position': 23,//文字显示位置'label.transparent': true,//文字在3d下是否透明 可消除字体周围的锯齿'label.color': '#eee',//文字颜色'label.t3': [0, 0, -151],//文字在3d下的偏移'label.r3': [0, Math.PI, 0],//文字在3d下的旋转'label.scale': 2//文字缩放
    });node.r3(0, Math.PI, 0);//节点旋转node.p3(p3);//设置节点在 3d 下的位置node.s3(s3);//设置节点在 3d 下的大小node.setName(name);//设置节点的显示名称return node;//返回节点
}

以及连线的创建:

function createEdge(exchange, service){//创建连线var edge = new ht.Edge(exchange, service);dm.add(edge);edge.s({'edge.width': 4,//连线宽度'edge.color': 'red',//连线颜色'edge.dash': true,//是否显示虚线'edge.dash.color': 'yellow',//虚线颜色'edge.dash.pattern': [32, 32],//连线虚线样式默认为[16, 16]
    });edge.a({//用户自定义属性 为 setAttr 的缩写'flow.enable': true,//是否启用流动'flow.direction': 1,//方向'flow.step': 4//步进
    });return edge;
}

我们界面中的显示的连线都是虚线流动的,HT 默认是关闭虚线流动的功能的,通过下面这句来开启虚线流动的功能:

g3d.setDashDisabled(false);//开启虚线流动

同时我们还需要设置动画,控制时间间隔,使得连线虚线偏移,形成一种“流动”的状态,动画请参考 schedule 调度手册:

flowTask = {interval: 40,action: function(data){if(data.a('flow.enable')){data.s('edge.dash.offset', data.s('edge.dash.offset')+(data.a('flow.step')*data.a('flow.direction')));}}
};
dm.addScheduleTask(flowTask);//添加flowTask动画

以下是界面上出现的所有的服务器以及客户端的节点的声明,都是基于 createNode 和 createEdge 函数创建的:

floor = createNode([0, 5, 0], [1000, 10, 500]);//地板图元
floor.s({//设置图元的样式 s 为 setStyle 的缩写'all.color': 'rgb(47, 79, 79)'//六面体的整体颜色
});exchange = createNode([0, 300, -400], [200, 20, 150], 'H3C 核心交换机', 'models/机房/机柜相关/机柜设备6.json');//交换机//五台不同作用的服务器
service1 = createNode([-400, 140, 0], [100, 260, 100], '备用', 'models/机房/机柜相关/机柜2.json');
service2 = createNode([-200, 140, 0], [100, 260, 100], '网站', 'models/机房/机柜相关/机柜2.json');
service3 = createNode([0, 140, 0], [100, 260, 100], 'OA', 'models/机房/机柜相关/机柜2.json');
service4 = createNode([200, 140, 0], [100, 260, 100], '广告', 'models/机房/机柜相关/机柜2.json');
service5 = createNode([400, 140, 0], [100, 260, 100], '受理', 'models/机房/机柜相关/机柜2.json');//创建交换机与服务器之间的连线
createEdge(exchange, service1);
createEdge(exchange, service2);
createEdge(exchange, service3);
createEdge(exchange, service4);
createEdge(exchange, service5);
//第二台交换机
exchange2 = createNode([-100, 60, 400], [200, 20, 150], 'Procurve Switch 2010-23 交换机', 'models/机房/机柜相关/机柜设备6.json').s('label.color', '#000');createEdge(exchange2, service1);
createEdge(exchange2, service2);
createEdge(exchange2, service3);
createEdge(exchange2, service4);
createEdge(exchange2, service5);floor2 = createNode([-100, 5, 800], [1000, 10, 500]);
floor2.s({'all.color': 'rgb(47, 79, 79)'
});device1 = createNode([-400, 20, 650], [200, 20, 100], 'VLS 12000(上)', 'models/机房/机柜相关/机柜设备6.json');
device2 = createNode([100, 20, 650], [200, 20, 100], 'VLS 12000(下)', 'models/机房/机柜相关/机柜设备6.json');
device3 = createNode([-200, 20, 800], [200, 20, 100], 'HP Strage Works 8/8 SAN Switch(上)', 'models/机房/机柜相关/机柜设备6.json');
device4 = createNode([200, 20, 800], [200, 20, 100], 'HP Strage Works 8/8 SAN Switch(下)', 'models/机房/机柜相关/机柜设备6.json');
device5 = createNode([-300, 20, 950], [200, 20, 100], 'EVA 8400 HSV450(上)', 'models/机房/机柜相关/机柜设备6.json');
device6 = createNode([100, 20, 950], [200, 20, 100], 'EVA 8400 HSV450(下)', 'models/机房/机柜相关/机柜设备6.json');createEdge(exchange2, device1);
edge1 = createEdge(exchange2, device2);
createEdge(device1, device3);
createEdge(device1, device4);
createEdge(device2, device3);
createEdge(device2, device4);
createEdge(device3, device5);
createEdge(device3, device6);
createEdge(device4, device5);
createEdge(device4, device6);
dm.sm().ss(edge1);//设置选中 edge1

最后,需要在属性栏中添加属性,这里我们只对“连线”进行了属性的显示及调整,总共 5 个属性,包括我通过 setAttr(简写为 a)自定义的属性 flow.enable、flow.direction、flow.step 和样式属性 edge.color 以及 edge.dash.color。我们通过 name 属性结合 accessType 属性实现对 Data 节点的存取:

 

 

//连线的属性
edgeProperties = [{name: 'flow.enable',//用于存取 name 属性accessType: 'attr',//操作存取属性类型displayName: 'Enable Flow',//用于存取属性名的显示文本值,若为空则显示 name 属性值valueType: 'boolean',//用于提示组件提供合适的 renderer 渲染,boolean 类型,显示为勾选框editable: true//设置该属性是否可编辑
    },{name: 'flow.direction',accessType: 'attr',displayName: 'Flow Direction',enum: {//枚举类型属性 传递数值和文字数组values: [-1, 1],labels: ['正向流动', '反向流动']},editable: true},{name: 'flow.step',displayName: 'Flow Step',                        editable: true,accessType: 'attr',slider: {//表单插件中的滑动条 所以要添加 ht-form.js min: 0,//最小值max: 10,//最大值step: 0.1//步进
        }},{name: 'edge.color',accessType: 'style',displayName: 'Edge Color',editable: true,valueType: 'color',//颜色类型,以填充背景色的方式显示colorPicker: {//颜色选择框instant: true//获取和设置是否处于即时状态,默认为true,代表作为表格和属性页的编辑器时,将实时改变模型值
        }},{name: 'edge.dash.color',displayName: 'Dash Color',accessType: 'style',valueType: 'color',editable: true,colorPicker: {instant: true}}
];
propertyView.setEditable(true);//设置属性组件可编辑
propertyView.addProperties(edgeProperties);//添加连线属性

是不是非常简单~  快动手实践一下吧!

转载于:https://www.cnblogs.com/xhload3d/p/8124629.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是顺序执行以及其特点

顺序执行是程序的一种执行方式。是把一个具有独立功能的程序独占处理机直至最终结束的过程称为程序的顺序执行 顺序执行的特点:顺序性:程序顺序执行时,其执行过程可看作一系列严格按程序规定的状态转移过程,也即是每执行一条指令&…

一年成为Emacs高手(像神一样使用编辑器)

作者: 陈斌(redguardtoo) 更新时间: 2012-02-10 五 原创时间: 2012-01-31 周二 15:08 很容易.一年多前我还在Vi阵营,偶尔使用Emacs还总是忘记退出(C-x C-c)的快捷键,但是一年后我跨入高手行列. 现在网上很多中文文章都是和你强调Emacs有多牛,以激发你的兴趣.最有名的大概是王垠…

七种常见的核酸序列蛋白编码能力预测工具 | ncRNAs | lncRNA

注:这些工具的应用都是受限的,有些本来就是只能用于预测动物,在使用之前务必用ground truth数据来测试一些。我想预测某一个植物的转录本,所以可以拿已经注释得比较好的拟南芥来测试一下。(测试的结果还是比较惊人的&a…

android预览界面编译出错,Android O预览findViewById编译错误

我试图测试Android O Developer Preview的第二阶段。 项目创建后,我只是点击了构建并运行但我没有任何成功。Android默认生成的代码如下:Toolbar toolbar (Toolbar) findViewById(R.id.toolbar);发生编译错误。Error:(18, 37) error: reference to find…

中断与异常的区别

中断: 中断是CPU(硬件)所具备的功能 ,它是指系统停止当前正在运行的程序而转向其他服务,可能是因 为优先级高的请求服务了,或者是因为人为安排中断。中断是属于正常现象。主要由CPU以外的事件引起的 中断…

寒武纪找到了引领中国AI芯片走向世界的路

大约6亿年前在地质学上被称作“寒武纪”的时代,大量无脊椎动物在短时间内出现“生命大爆发”。如今,“寒武纪”这个名字再次被人们提及,它源自中科院计算所研发的人工智能芯片处理器的命名,意喻人工智能即将迎来大爆发的时代。“寒…

浅谈PPM (Project Portfolio Management)

前言: 本文以纯理论性的PPM讲解为主,不会涉及到具体如何实施,我会在以后介绍详细的PPM实施方案介绍。 PPM,可能很多人并不清楚甚至可能没听说过,这是一个近些年才流行起来的概念,是Project Portfolio Mana…

poj 3071 Football

http://poj.org/problem?id3071 2^n 支足球队比赛,共比n场,第一场1号与2号比,3号与4号比…… 每场胜出者进入下一场,输者淘汰 每一场都是相邻的两个队伍比拼 已知任意两个队伍比拼获胜的概率 求最后哪只队伍获胜的概率最大 dp[i]…

进程调度与作业调度

进程调度是真正让某个就绪状态的进程到处理机上运行,而作业调度只是使作业具有了竞争处理机的机会。进程调度(又称微观调度、低级调度、短程调度): 是按照某种调度算法从就绪状态的进程中选择一个进程到处理机上运行。负责进程调…

tensorflow源码安装

主要参考:https://www.tensorflow.org/install/install_sources#ConfigureInstallation卸载tensorflow sudo pip uninstall tensorflow 安装git 安装git时记得先安装,后更新系统 sudo apt install git安装jdk8: myubuntu:~$ java myubun…

Makefile学习之通配符和自动变量

规则中的通配符 “*” ,“?” ,“ [...]”, " % " , " wildcard " 1.“*” *.c表示所有后缀为.C的文件; 如果文件中用到通配符,使用“\*”; 2.通配符在变量中的使用; objects*.c 注意…

英语中十二个月名称的由来

转自网络,原出处不详。 公历一年有12个月,但不少人并不知道12 个月的英语名称的来历。公历起源于古罗马历法。罗马的英语原来只有10 个月,古罗马皇帝决定增加两个月放在年尾,后来朱里斯*凯撒大帝把这两个月移到年初,…

进程和程序的关系

1 进程是一个动态概念,而程序是一个静态概念。 2 进程具有并行特征,程序没有。 3 进程是竞争资源的基本单位。 4 一个程序对应多个进程,一个进程为多个程序服务。

Android怎么插手机卡,魅蓝E手机卡怎么装 魅蓝E手机SIM卡安装图文教程

昨天下午,魅族发布了全新系列魅蓝手机——魅蓝E,定位魅蓝高端产品线,售价1299元,李楠号称魅蓝E采用三四千元的旗舰机工艺,外观/屏幕/拍照提升明显。此外,魅蓝E依旧支持全网通双卡双待。那么魅蓝E怎么插卡/装…

快速幂总结

快速幂总结 快速幂这个东西比较好理解,但实现起来到不老好办,记了几次老是忘,今天把它系统的总结一下防止忘记。 首先,快速幂的目的就是做到快速求幂,假设我们要求a^b,按照朴素算法就是把a连乘b次,这样一来…

第三章

一.项目前期的主要工作 1.现状分析 ①.硬件分析 ②.软件分析 2.需求收集 3.粗略设计 ①.体系结构分析 ②.硬件(网络)设计 ③.应用系统设计 ④.安全设计 ⑤.配套设计 4.可行性分析 二.结构的项目前期实例 1.组织分析 3.需求收集 4.粗略设计 ①.系统体系结…

进程的静止和活动状态

进程有3个主要状态,即就绪,执行和等待。当一个进程被创建的时候,处于就绪状态,严格地说是静止就绪状态,等到被激活,该进程就处于活动就绪状态,如果时间片轮到该进程,那么该进程就执行…

荣耀magic3会用鸿蒙,赵明:荣耀Magic3芯片领先行业,大家看到以后会换掉手机!...

荣耀CEO赵明亲自参加高通2021技术峰会,宣布与高通达成战略合作,未来全系产品采用高通平台。赵明同时透露未来的产品动向,不排除未来与华为继续合作,采用鸿蒙操作系统的可能。赵明表示,Android操作系统依旧是荣耀的首选…

公司里从员工到经理,不同层级应该关注的事情

最近在看《领导梯队》,超级棒的一本书,受益匪浅,推荐给各位从事管理方向的朋友 第一阶段:从管理自我到管理他人(leader级)   新员工工作的最初几年是个人贡献者。无论他们从事的是销售、会计、工程或是市…

继续教育学习脚本

/* 本脚本运行于浏览器conlose中,自动点击“继续学习”按钮,以实现阻止视频的暂停 */ (function(){ var getStylefunction(obj,styleName){ if(obj.style){ return obj.style[styleName]; }else if(obj.currentStyle){ …