最近项目开发任务告一段落,刚好有时间整理这大半年的一些成果。使用html5时间还不久,对js的认识还不够深入。没办法,以前一直搞java,对js的一些语言特性和概念一时还转换不过来。
上一篇第一弹介绍了项目中做的一个彩虹爆炸图,主要用了 html5的canvas的2d绘制技术。这一回我想介绍一下项目中的一个亮点技术:html5的3D,以及如何用它打造精美的3D机房监控系统。
目标效果图
下图是领导给找的一张的效果参考图,客户希望机房至少能达到下面的3D效果。懂的人都知道,这可是一张设计公司出的装修效果图啊,就算是用max建模,也需要大量的工作,何况咱可是程序员在做数据中心的可视化项目啊。。。强忍心中奔腾的万千头**马,静下心来思考,那就先从搭建一个webGL的场景开始把。
WebGL基本场景搭建
在html5里面使用3D已经不是什么高深技术,它的基础是WebGL,一个openGL的浏览器子集,支持大部分主要3D功能接口。目前最新的浏览器都有比较好的支持,IE需要到11(是的,你没有看错)。
要检测你的浏览器是否支持webGL,直接访问网页http://get.webgl.org/ 看是否能看到一个旋转的立方体。如果能看到,说明你的浏览器支持webgGL,否则,可以下一个最新的chrome试试吧。相对来说chrome对webGL的支持最好,效率也很优秀。
要在浏览器里面使用webGL,就要研究webGL相关的技术和用法。做3D应用并不是一件轻松的事。就算最简单的搭建一下webGL场景,也需要下面这些代码:
<script> var width = window.innerWidth; var height= window.innerHeight; var container = document.createElement( 'div' ); document.body.appendChild( container ); var webglcanvas = document.createElement('canvas'); container.appendChild(webglcanvas); var gl = webglcanvas.getContext("experimental-webgl"); function updateFrame () { gl.viewport ( 0, 0, width, height ); gl.clearColor(0.4, 0.4, 0.7, 1); gl.clear ( gl.COLOR_BUFFER_BIT ); setTimeout( function(){updateFrame()}, 20); } setTimeout( function(){ updateFrame(); }, 20); </script>
和html一样,需要先创建一个canvas元素,并获得其webgl上下文:
var gl = webglcanvas.getContext("experimental-webgl");
然后在一个updateFrame的函数中,像html5的2d context一样,去绘制3D的内容。另外,要再起一个死循环,每隔**毫秒调用一次这个updateFrame函数来重绘场景。和2D不同,3D场景里面的变化是随时随地的,所以需要不停刷新,就像播放电影或视频,静止不动的画面基本没有,所以死循环刷新基本是必要的。不过实际项目使用中会有很多优化,尽量做到“按需刷新”,节省cpu和移动设备电量。这一点也是很重要的,有感兴趣的同学,可以单独写文章介绍。这段程序基本上什么也没做,就画了一个静止不动的区域,如下图:
虽然看不见任何3D的内容,不过它已经是一个最简单的webgl程序了。我们的精美的3D机房,也是要在这上面不断丰富而已。
对象封装
要做项目,搭建下去工作量太大了,时间周期也不允许。使用第三方辅助工具是不可避免的,像Three.js、twaver.js都是选择。这些工具都可以提供3D的基本对象和各种特效。当然这都不是最主要的,主要是如何利用它做出我想要的效果:好看。为了避免大量修改代码,在项目里做了一些封装,把原始3D的立方体等对象进行进一步封装,让一个json数据就可以提供这些对象的定义。这样使用起来就比较方便了。Json大致结构如下:
var json={ objects: [{ name: '地板', … },{ … }], }
下面我们逐一来看这些3D对象是怎么进行美化的,过程可能稍显啰嗦,但实际工作就是这么繁琐的有木有?
地板和斜坡
第一个要做,也是应该比较简单的,就是地板。这个地板应该是一个有点厚度、有格子贴图的薄薄立方体平面。还好经过封装,就写一段json对象就能定义了:
{ name: '地板', type: 'cube', width: 1600, height: 10, depth: 1300, style: { 'm.color': '#BEC9BE', 'm.ambient': '#BEC9BE', } }
通过定义,创建一个13米*16米的地板块:
只有颜色还不够,找一个地板砖纹理图。需要注意的是,纹理图的尺寸都需要是宽和高都是2的幂,例如128x128、256*256等,这样出来效果才会好。这也是3D软件一般所要求的。另外纹理要能连续拼接不露破绽,这样才好。例如下面我google出来的图:
在style里面添加:
'top.m.texture.image': 'images/floor.png', 'top.m.texture.repeat': new mono.Vec2(10,10),
效果如下:
有图片材质纹理,效果果然好多了。不过客户说他们这里底面有一个方便运送设备的斜坡,要画出来。这……
后来想到twaver里面的对象可以支持运算。可以定义一个斜的立方体,让地板剪掉立方体,应该可以做到。于是继续定义json:
{ name: '地板切坡', type: 'cube', width: 200, height: 20, depth: 260, translate: [-348,0,530], rotate: [Math.PI/180*3, 0, 0], op: '-', style: { …, } }
这里定义的一个倾斜的立方体,通过translate定义位置,通过rotate定义旋转角度,然后再通过op定义运算符,这里是“减去”,就用“-”。被剪掉的立方体也可以设置材质、纹理、贴图、颜色….等等。看看效果:
走廊桌
按要求走廊要放一个接待桌。为了简单就偷懒做一个立方体表示吧!这个简单,继续使用上述办法:
{ name: '走廊板凳', type: 'cube', width: 300, height: 50, depth: 100, translate: [350, 0, -500], }
效果如下:
再增加一点配色并启动阴影效果后,看着就好多了。尽管只是个简单的立方体,但只要和整体风格一致,并不显得简陋。很3D里面最重视的就是效率,千万不要放一些很复杂的模型,尤其是这些非业务对象。
墙体
墙体是机房里很重要的一个部分,有好的光照、阴影的效果才能看起来更加逼真。由于墙体是不规则的路径,一段一段去生成还真挺麻烦的,还好引擎支持这种物体,甚至曲线路径都可以。这里只要在json里面定义一组数字的坐标,让这些数字依次连接,组成一个墙体,最后生成3D对象放入场景中就行啦。
json定义如下:
{ name: '主墙体', type: 'path', width: 20, height: 200, translate: [-500, 0, -500], data:[ [0, 0], [1000, 0], [1000, 500], [500, 500], [500, 1000], [0, 1000], [0,0], ], }
注意这里的类型变成了path,data中定义了一个二维坐标数组来描述墙体。由于墙都是从底面开始的,所以只定义它的平面的x、y坐标就行了。看看效果:
不如前文所说,还是需要上色、上阴影,才能有更好的效果。这里我们启用阴影并咨询设计师美眉几个颜色值,加上去,再看下效果:
还有细节:
门
看着雪白的墙,是不是觉得少了点什么?对,就是门。在3D机房的监控系统里,门禁是很重要的一块,客户要求门应该与实际位置相对应,并且要有开门关门的动画效果。这样,实际的门禁信息采集上来后,就能在界面实时看到门的状态了。
这里,考虑到门如果直接放上去,会被墙盖住;如果比墙厚,又难看不符合实际。还是应该先定义一个门洞立方体,把门所在的位置挖掉:
{ name: '门洞', type: 'cube', width: 195, height: 170, depth: 30, op: '-', translate:[-350,2,500], }
刚好挖在斜坡的位置,这样设备进屋就方便了:
不过这门没有一个门框,感觉不太生动。多一个门框会感觉立体感强一些。门框可以是一个比门洞略大的立方体,在挖门洞之前添加:
{ name: '门框', type: 'cube', width: 205, height: 180, depth: 26, translate: [-350, 0, 500], op: '+', }
加上阴影和光线等综合效果,还不错,挺有档次的。
来张全景图看看:
接着,只要把门安上去就行了。门的定义比较简单,就是一个薄的立方体。不过为了做到玻璃效果,需要设置透明度,让它看上去更像一个玻璃,再让设计师美眉弄一张好看一点的门的图,贴上去。尽管有了webGL,复杂的建模工作可以省略了,不过设计师美眉的配合仍然很重要。
先做左边的门:
{ name: '左门', type: 'cube', width: 93, height: 165, depth: 2, translate:[-397,4,500], style:{ 'm.transparent': true, 'm.texture.image': 'images/door_left.png', }
上面增加的style主要透明和贴图两项。看看效果:
同样的方法,再把右侧门贴上就搞定了。为了增加体验,也是用户的要求,门上面设置了动画:双击可以自动打开,再双击可以直接关闭。动画功能引擎做好了封装,在json中直接指定动画类型就行了。不过要注意左右门的动画旋转方向要相反,要不然一个向里开一个向外开感觉比较怪异。
窗
项目中,窗本身不需要有任何业务属性,但是美观度的要求可一点都不能少。方法和门类似,先放窗框后挖窗体。不过为了有点变化,这里不做窗框了,做一个窗台,方法和道理与门相同。
{ name: '主窗户洞', type: 'cube', width: 420, height: 150, depth: 50, translate: [200, 30, 500], op: '-', },{ name: '主窗户台', type: 'cube', width: 420, height: 10, depth: 40, translate: [200, 30, 510], op: '+', }
定义了一个窗洞(挖掉)、一个窗台(添加)。一个大窗户就做好了:
再添加一个略带颜色的透明玻璃。玻璃设置点高光和反射,增加“玻璃”感觉:
{ name: '主窗户玻璃', type: 'cube', width: 420, height: 150, depth: 2, translate: [200, 30, 500], op: '+', style: { 'm.transparent': true, 'm.opacity':0.4, 'm.color':'#58ACFA', }, }Json中玻璃设置了透明度和颜色。这样一个半透明的茶色玻璃就好了:
到这里突然在想:盖房子如果像写程序一样简单就好了,所有的程序猿就不会是无房一族单身狗了。当然写程序和盖房子一样:该封装好的要封装好,最后就是搭积木组装就行了。如果盖房子都是从挖土活泥巴开始,那就杯具了。写程序也是一样,如果从webGL的main开始写……这3D机房的系统要几个月甚至几年才能做出来呢?
外侧墙
按照项目实际要求,继续增加更多建筑物墙体。主要是房间外侧有两道走廊隔墙。这是一个中间有大片透明玻璃的走廊隔墙,需要做的好看一点。由于是直线墙,没有复杂走向,直接用立方体定义得了:
{ name: '左外墙', type: 'cube', width: 20, height: 200, depth: 1300, translate: [-790, 0, 0], op: '+', }
效果如下:
再继续挖掉中间的窗户部分:
{ name: '左外墙洞', type: 'cube', width: 30, height: 110, depth: 1300, translate: [-790, 60, 0], op: '-', }
空白显得很奇怪,加上玻璃试试:
{ name: '左外墙玻璃', type: 'cube', width: 4, height: 110, depth: 1300, translate: [-790, 60, 0], op: '+', style: { 'm.transparent': true, 'm.opacity':0.6, }, }
有了半透明和高光的效果,看起来就有质感了,右边也如法炮制:
这样,整个建筑的外观就基本完成了。最后,放一些绿植,增加些生气吧。
植物
做一盆植物,需要有一个空的花盆,花盆里面有泥土,上面有一株植物。这些东西用3D做起来都有点啰嗦。不过也不难。花盆用一个大圆柱剪掉中间的小圆柱,做成空心花盆;植物用贴图+透明模拟一下就行,不用真的去做植物的3D模型,否则要累死了。
根据上面的思路,在项目中通过仔细调整,把创建花盆的代码封装好,然后在json中定义花盆位置就行了。下面定义一个:
{ name: '花1', type: 'plant', translate: [560, 0, 400], }程序中解析如果type是plant则创建植物对象并添加场景。
在房间、走廊、甚至窗台上都可以放几盆,窗台上的可以通过设置scale缩小一些,并提升其高度到窗台位置即可。
看看下整体效果,还不赖吧。
写了那么一大篇,才终于把3D机房的外观装修完成,咱也算是个设计师程序员的混合型人才了呢。其实机房最核心的资源——机柜,还没找落呢,没办法,形象工程也是项目建设的一大亮点。
机柜
机柜,以及其中的服务器设备。这才是3D机房里面最终要管理的内容。在我们的实际项目中,这些资产都是在数据库中存储,并通过json接口加载到浏览器中显示。这里为了演示方便,直接写几个机柜的片段,看一下显示效果。
机柜对象在项目中是这样封装的:用一个立方体来表示机柜,并加上贴图。项目中,为了提高显示速度,机柜一开始并不加载内部服务器内容,而是只显示自身一个立方体。当用户双击后,会触发一个延迟加载器,从服务器端加载机柜内部服务器,并加载到对应的位置上。此时,机柜会被挖空成一个空心的立方体,以便视觉上更像一个机柜。
定义机柜的json如下:
{ name: '机柜', type: 'rack', lazy: true, width: 70, depth: 100, height: 220, translate: [-370, 0, -250], severity: CRITICAL, }上面的机柜定义中,有一个lazy标记,标记它是否延迟加载其内容。如果延迟加载,则双击触发,否则程序显示时直接加载其内容。Severity是定义了机柜的告警信息,它是否有业务告警。如果有告警,会用一个气泡显示在机柜的上方,同时机柜也会被染色成告警对应的颜色。
加入更多的机柜看看效果:
设备
简单起见,这里管理的设备假设都是机架设备,尺寸规格比较规整,因此比较容易在机柜中组织。一个设备的外观确定后,在数据库中定义好模板,加载时根据其所在机柜的位置放置即可。
这里只是随机生成了几个服务器设备,并按位置摆放。在实际应用中,可以通过手工录入或者智能机架报送的信息来确定服务器的类型和位置。
如果需要监控到端口级别,还可以在服务器弹出后,再进一步延迟加载设备商的板卡、端口对象,并点击后进一步进行配置、监控等操作。当然加载的数据越细,对3D引擎和浏览器的压力会越大。可以通过动态延迟加载/卸载策略,获取一些平衡折中。
电视机
纯属无聊,再做一个电视机挂在墙上。依旧,定义一个立方体、挖空屏幕,放上透明玻璃,再贴上我们喜欢的电视节目画面,就ok了。
{ name: '电视机体', type: 'cube', width: 150, height: 80, depth: 5, translate: [80, 100, 13], op: '+', },{ name: '电视机挖空', type: 'cube', width: 130, height: 75, depth: 5, translate: [80, 102.5, 17], op: '-', },{ name: '电视机屏幕', type: 'cube', width: 130, height: 75, depth: 1, translate: [80, 102.5, 14.6], op: '+', style: { 'front.m.texture.image': 'images/screen.jpg', }, }
当然,实际项目中,也可以换上监控大屏幕的效果:
总结
整个场景写到最后,我也已经脑洞大开游刃有余了。3D场景,尤其是这类业务系统,并不一定要死抠模型的仿真度,才能做到“好看”的效果。先来一张全景看一下:
怎么样,还算精美吧?基本不输前面看到的广告公司的效果图。但和效果图一张死图片不一样,我们这是一个能操作、能漫游、能缩放、有动画、显示流畅、浏览器无需插件就能直接打开的3D机房小程序,就一个json文件和一百多行代码和一天的时间就搞定了,还是让人有点惊讶的。
不用插件、不用3Dmax,不用模型库,干干净净纯粹的小程序,手机和平板也能用哦,而且还很流畅!上一张我的Nexus5截图瞅瞅:
经过优化,场景加载已经控制在600毫秒以内,缩放漫游也很流畅。当然技术和美化永无止境,用户的需求也千变万化精益求精。但只要我们选择好了技术和工具,就能事半功倍。Html5就是极佳的一个选择。
Html5,也许它还不是银弹,但它确实是很好的一个炮弹。本文这一弹,你还喜欢吗?欢迎来信留言索取代码、技术交流:tw-service@servasoft.com
相关推荐
在“HTML+CSS+JS数据可视化大屏平台模板实例27-智慧机房监测通用模板”中,我们可以深入探讨这些技术在智慧机房监测场景中的应用。 首先,HTML(HyperText Markup Language)负责构建页面的基本结构。在智慧机房...
【Python数据可视化】 在Python中,数据可视化是利用各种图表和库来展示和理解数据的重要工具。Python的流行很大程度上得益于其强大的数据可视化能力,尤其是对于数据分析和科学研究领域。本章涉及的知识点包括基本...
HTML5炫酷科技感十足数据可视化HTML5炫酷科技感十足数据可视化HTML5炫酷科技感十足数据可视化HTML5炫酷科技感十足数据可视化HTML5炫酷科技感十足数据可视化HTML5炫酷科技感十足数据可视化HTML5炫酷科技感十足数据...
基于 HTML5 的 3D 数据可视化 HTML5 标准规范的制定完成,标志着基于浏览器的应用的蓬勃发展,为数据可视化提供了新的实现方法。本文对 HTML5 的数据可视化在浏览器的应用进行研究实践,并利用 HTML5 中新生 API ...
全书共8章,分别介绍了准备工作环境、了解数据、绘制并定制化图表、学习更多图表和定制化、创建3D可视化图表、用图像和地图绘制图表、使用正确的图表理解数据以及更多matplotlib知识。 《Python数据可视化编程实战》...
3D可视化机房运营全景管控平台建设方案 数据中心3D可视化项目建设方案
HTML/CSS的大屏数据可视化集合案例源码(99套)数据可视化集合。 基于HTML/CSS/Echarts的会议展览、业务监控、风险预警、数据分析展示等多种展示需求可视化集合,76套数据可视化源码,25套数据可视化源码。数据都是...
3D可视化机房运营全景管控平台是现代数据中心管理和运维的重要工具,它利用先进的3D建模和大数据分析技术,提供了一种直观、高效的方式来管理和监控复杂的IT环境。本方案旨在构建一个综合性的3D可视化解决方案,帮助...
《Python数据可视化编程实战》这本书是为那些希望通过Python进行数据可视化的人量身打造的实践指南。书中涵盖了Python在数据可视化领域的各种工具和技术,旨在帮助读者理解如何有效地展示数据,提升数据分析和解读的...
本书《Python数据可视化编程实战(英文第二版)》深入浅出地介绍了如何利用Python库进行数据可视化,源代码提供了丰富的示例和实践项目,为学习者提供了宝贵的资源。 在Python中,最常用的可视化库包括Matplotlib、...
3D可视化不仅仅是将二维图表扩展到第三个维度,而是通过对数据的多层次、多角度分析,创造出更接近真实世界的视觉效果。这种技术常用于地理信息系统、科学模拟、工程设计、商业智能等领域,尤其是在大数据分析中,能...
数据可视化是一种将复杂的数据集通过图表、图形或其他视觉表示方式呈现出来的方法,使得非专业人员也能快速理解数据背后的含义和趋势。在这个“数据可视化大屏源码(12套).zip”压缩包中,包含了12套不同的数据可视化...
课程分享——地图Web3D可视化-WebGL、Three.js,附源码 课程概述 - 本课程讲解如何在web上实现地图3D可视化 - 学习本课程有前端基础即可,如果了解three....章节5、密集位置数据可视化 章节6、信息流数据可视化(飞线)
数据可视化的教学代码: 包括折线图+柱状图+饼图+盒图+散点图+直方图+3d图 画布的布局、画图中中文乱码的解决、背景板的选择等 简单的数据分析和可视化案例: titanic数据的简单分析可视化 iris数据的聚类可视化 GDP...
在本项目中,"基于echarts的3d地球数据可视化展示.zip" 提供了一个使用ECharts库实现3D地球数据可视化的示例。ECharts是一个由百度开发的开源JavaScript图表库,它支持丰富的2D图表类型,同时也扩展到了3D场景,如3D...
Python在数据可视化方面的主要优势在于其第三方库,例如Matplotlib、Seaborn、Plotly等。这些库能够帮助开发者快速地将数据转换为可视化的图表,包括但不限于折线图、散点图、条形图、饼图、热力图等。通过这些工具...
在本项目中,我们主要探讨的是如何利用Python进行数据可视化分析,特别是针对北京房屋出租市场的数据,通过3D展示来揭示潜在的市场趋势和模式。Python作为一种强大的编程语言,其丰富的库资源使得数据分析和可视化变...
数据可视化 大作业 广东工业大学 数据可视化 好莱坞数据集
Python数据分析与应用是一个涵盖多个领域的综合主题,包括数据获取、数据清洗、数据分析、数据可视化以及相关的编程技巧。在这个领域,Python以其简洁易读的语法和丰富的库支持,成为了数据科学界的首选工具。以下是...