当前位置:文档之家› HTML5+WebGL 3D机房开发实例

HTML5+WebGL 3D机房开发实例

HTML5+WebGL 3D机房开发实例前阵子写了一篇HMTL5 3D机房开发的例子,介绍了如何用html5在网页上创建无插件的精美3d机房场景,收到很多朋友的鼓励,深表感谢。

对于索要源代码的朋友,已经尽力邮件回复。

由于精力所限,如未能收到的朋友请留言或给我发送邮件:tw-service@。

最近项目第二期又要紧锣密鼓地开始了,所以想抓紧把一些新增的内容补充上,进一步完善这个html5 3d机房的呈现效果。

上一篇中主要介绍的是如何从最基础的webgl封装到创建3d物体对象,再通过3d物体对象“搭积木”式的组建整个3d机房场景。

这一篇主要介绍一些如何在这个场景上进一步丰富更多的功能和呈现效果,以及实现这些功能在技术上的思路。

首先我们来看看上一期已经实现的纯天然无添加无PS的HTML5 3D机房效果:已经拿到过代码的朋友应该知道,这一场景可通过一个json文件进行组装和加载,可以很方便地进行修改和维护。

在此基础上,这一次我又增加了”机柜标签、机柜门、复杂设备、机房走线、人员轨迹“等效果,下面我就把第二季的干货一一为大家奉上。

机柜标签机房中最重要的物理资源——机柜——是机房管理、规划、监控人员最关注的对象之一。

对于规模在几十个、上百个甚至上千个机柜的机房,每个机柜必然会进行资产编号,方便检索和管理。

这个在多数资产管理系统中,都是最基本的。

但是在3d场景中,如何显示这些机柜编号,才能让用户更直观的看到每个机柜的位置呢?传统的方式是用标签显示资产编号,例如可以用“告警冒泡”那样的方式显示一个文字气泡。

不过当机柜产生告警时,两个气泡会有所冲突。

而且过多的气泡会产生相互遮挡覆盖,有点混乱,比如像这样:因此我尝试了一种不同的思路:把文字渲染到一个内存图片,“溶解”到机柜的上方贴图中。

想要生成一个内存的图片文字,可以通过下面的函数实现:Js代码.generateAssetImage: function(text){.var width=512, height=256;..var canvas = document.createElement('canvas');.canvas.width = width;.canvas.height = height;..var ctx = canvas.getContext('2d');.ctx.fillStyle='white';.ctx.fillRect(0,0,width,height);.ctx.font = 150+'px "Microsoft Yahei" bold';.ctx.fillStyle = 'black';.ctx.textAlign = 'center';.ctx.textBaseline = 'middle';.ctx.fillText(text, width/2,height/2);.ctx.strokeStyle='black';.ctx.lineWidth=15;.ctx.strokeText(text, width/2,height/2);..return canvas;.}需要留意的是:1. 生成的图片宽高数值最好是2的幂,例如128、256、512等,这样在3d中渲染不容易出现闪烁和锯齿。

相关原理请查阅google。

2. 文字绘制尽量居中、充满整个图,不要太小,否则看上去比较奇怪。

3. 空白处保持透明,不必填充色,方便和机柜本身贴图的“溶解”。

4. 直接返回canvas对象即可,不必生成图片点阵数组。

生成canvas后,可以这样直接贴图使用:Js代码.var labelCanvas=demo.Default.generateAssetImage(label);.rack.setStyle('top.m.texture.image', labelCanvas);.rack.setStyle('top.m.specularmap.image', labelCanvas);通过上面代码,把贴图作为机柜立方体top面的贴图和反射映射图。

这样出来的效果如下:这样,既不用增加3d对象,也不影响机柜的美观度,关键是看得非常清晰,在大场景中也不干扰用户的视线:机柜门上一篇里,由于时间紧迫,也考虑到呈现效率,机柜采用了“双击机柜出现设备”的方案。

一个立方体的机柜虽然简单直接,但是没有机柜门,总觉得假了一点,客户也提到了这一点,因此按照机房门的思路,增加一个机柜门,增加双击开门的效果,这个比较简单:Js代码..rackDoor.s({.'m.type':'phong',.'m.color': '#A5F1B5',.'m.ambient': '#A4F4EC',.'front.m.texture.image': 'images/rack_front_door.png',.'back.m.texture.image': 'images/rack_door_back.png',.'m.envmap.image': demo.Default.getEnvmap('envmap1'),.});.rackDoor.setParent(rack);.rackDoor.setPosition(0, 0, depth/2+1);.rackDoor.setClient('animation','rotate.right.120');上面代码创建了一个薄薄的立方体作为机柜门。

设置贴图、颜色等,再设置其parent是机柜。

这样,如果拖拽机柜位置,机柜也会跟着移动,简单方便。

最后,在设置一下机柜门的动画。

通过一个字符串进行定义:rotate.right.120表示动画是“向右侧旋转120度”,在双击的时候触发。

复杂电信设备第一季里,机柜内的设备,主要用乐服务器来表现,加入了设备弹出、告警等效果。

后期根据现场和用户的交流,用户进一步提出要显示机架上需要安装更加复杂的电信设备,包括板卡、板卡的插拔动作、呈现方法等,也就是在机柜上显示一个有多个板卡的设备,双击板卡可以弹出。

要做这个,需要把原来的一个立方体的服务器设备做一个“挖空”处理,变成一个空的设备框的样子。

然后再生成一系列的板卡对象,插入这个空框。

每个板卡应该由面板+电路板组成,可以用两个立方体进行拼接,添加适当的贴图完成。

代码如下:Js代码.var parts=[{.//card panel.type: 'cube',.width: width,.height: height,.depth: 1,.translate: [x, y, z+1],.rotate: rotate,.op: '+',.style:{.'m.color': color,.'m.ambient': color,.'m.texture.image': 'images/gray.png',.'front.m.texture.image': pic,.'back.m.texture.image': pic,.}.},{.//card body.type: 'cube',.width: 1,.height: height*0.95,.depth: depth,.translate: [x, y, z-depth/2+1],.rotate: rotate,.op: '+',.style:{.'m.color': color,.'m.ambient': color,.'m.texture.image': 'images/gray.png',.'left.m.texture.image': 'images/card_body.png',.'right.m.texture.image': 'images/card_body.png',.'left.m.texture.flipX': true,.'m.transparent': true,.}.}];.var card=demo.Default.createCombo(parts);.card.setClient('animation', 'pullOut.z');.box.add(card);上面代码可以生成一个板卡对象。

循环重复,设置位置,即可生成整个设备。

通过设置animation属性,定义板卡动画为“双击拉出”,再次双击推回。

效果如下图:当然,实际项目中,各种结构的电信设备千奇百怪,要通过代码定义是不现实的。

所以我们还开发了一个设备编辑器,可以通过拖拽方式快速生成设备结构图。

机房线缆和走线架除了机柜之外,线缆的连接走向和连接关系是管理员关注的另外一个焦点。

机架中的电信设备或服务器设备会通过端口和线缆进行连接,组成一定结构的网络。

而线缆的走向在物理上通过肉眼是很难看清晰的。

更多线缆会从机柜连出,延伸到屋顶上方或地板下方的隐蔽工程中(例如走线架)固定和布线,用肉眼更无法观察。

此时,需要3d机房界面能清晰的显示电缆从端口到走线架再到端口的“端到端”的物理走线,方便管理员了解网络情况和管理。

伦理片/线缆线缆,可以用一个空间的`path`来定义,并设置其贴图:Js代码.var path = demo.Default.create3DPath(json.data);.var cable=new mono.PathNode(path, 100, 1);.cable.s({.'m.type': 'phong',.'m.specularStrength': 30,.'m.color': json.color,.'m.ambient': json.color,.'m.texture.image': 'images/flow.jpg',.'m.texture.repeat': new mono.Vec2(200, 1),.});.box.add(cable);通过json定义的[x, y, z]数组来生成一个path对象,然后用它来生成一个空间的“管子”对象。

相关主题