HTML5的WebGL3D档案馆图书可视化治理系统的实现-
前言
档案治理系统是通过创立同一的规范以标准整个文件治理,包含标准各业务系统的文件治理的完备的档案资源信息同享办事平台,主要实现档案流水化采集功能。为企事业单位的档案现代化治理,供给完备的解决方案,档案治理系统既可以自成系统,为会员供给完备的档案治理和网络查询功能,也可以与本单位的OA办公主动化和DPM设计历程治理,或者与MIS信息治理系统相联合,构成更加完美的现代化信息治理网络。传统档案馆随着社会的迅速开展与变化,其内涵情势上也产生了庞大变化,逐步蜕变为现代智慧档案馆。智慧档案馆以现代科技为依靠,充分联合现代物联网技术与云盘算技术构建完美的城市智慧档案,实现了现代社会全面治理的指标。本文以目前流行的 H5 技术为主,为现代智慧档案馆供给一套 WEB 解决方案。
代码实现
场景搭建
在本例中,将运用 HT UI 组件对页面实现布局;运用 RelativeLayout 相对布局器将页面分为三个局部:left, top, center,运用 VBoxLayout 纵向布局器将 LEFT 局部分为 logo,editor,chart 三个局部
Graph3dView 加载 3D 场景
Graph3dView 是 HT 组件中加载 3D 模型的拓扑组件,RelativeLayout 则是 HT 供给的 UI 解决方案,UI 组件中供给 HTView 组件来实现拓扑与 UI 的融合。
// 初始化相对布局器 var relativeLayout = new ht.ui.RelativeLayout(); // 初始化 3D 拓扑 var g3dView = new ht.graph3d.Graph3dView(); // 初始化 HTVIEW 组件, 并将 3D 拓扑放入其中 var htView = new ht.ui.HTView(g3dView); // 布局器加载 HTVIEW 组件 relativeLayout.addView(htView, { width: 'match_parent', // 填满 height: 'match_parent', // 填满 marginTop: 64, // 为 TOP 留下空间 marginLeft: 250 // 为 LEFT 留下空间 });
新建 LEFT 中的档案袋模型
左侧的 EDITOR 局部运用 HT 的调色板组件(ht.widget.Palette), 将档案袋增加到调色板上,并设定为可以拖拽:
var palette = new ht.widget.Palette(); // palette 面板是将图元都分在“组”里面,然后向“组”中增加图元即可 var group = new ht.Group(); // 设定分组为打开的状态 group.setExpanded(true); // 设定组的注明 group.setName('根基图元'); palette.dm().add(group); // 增加子图元 var childNode = new ht.Node(); childNode.setParent(group); childNode.setName(name); childNode.setImage(image); childNode.s({ 'draggable': true, // true 为可拖拽 'image.stretch': 'centerUniform' // 图片申展方式 }); palette.dm().add(childNode);
实现从调色板中将图元拖拽至 3D 场景
在上一步中我们对换色板中的图元属性设定了可拖拽,此时可以实现拖拽图元的动画。但是并不克不及直接将图元拖拽到 3D 场景中,实现思绪是:
在拖拽时猎取拖拽的图元信息
拖拽到对应位置时显示可摆放位置
完毕拖拽后在对应位置新建对应的 3D 模型
对应代码实现如下:
拖拽时猎取图元信息
g3dView.getView().addEventListener('dragover', function(e) { e.preventDefault(); var paletteNode = palette.dm().sm().ld();// 猎取 palette 上最后选择的节点 if (!paletteNode || !g3d.getDataAt(e)) return; // 猎取鼠标下的节点 var data = g3d.getDataAt(e); if (data.s('shape3d') === '档案柜.json') { // 记载文件袋拖拽到的是哪个档案柜 g3dView._focusData = data; } });
拖拽到对应位置时新建 3D 模型,在现实实现历程中因为很难正确地猎取到档案柜中每一个可以摆放档案袋的坐标位置,所以在本例中采纳了预置的办法。概括道理就是在先新建一个正常不成见的档案柜模型,并在其中将档案袋都摆放完备,在拖拽时,将此不成见的模型与将要摆放的模型重合,此时只需推断鼠标所在的点下可否存在预置的模型存在就可以晓得该处可否可以新建 3D 模型,实现结果如下:
g3dView.getView().addEventListener('dragover', function(e) { ... // 旧逻辑省去 // 拖拽下来的时候设定 所有的 displayName 为 box 的节点 为可见 (这样拖拽才干猎取到预置模型) array.forEach(function(data) { data.s('3d.visible', true); }); var data = g3d.getDataAt(e); if (data.s('shape3d') === '档案柜.json') { // 记载文件袋拖拽到的是哪个档案柜 g3dView._focusData = data; // 将预置模型挪移到拖拽的柜子坐标 shelf.p3(data.p3()); } if(data.getDisplayName() === 'box') { // 将对应坐标下预置的档案袋模型进行显示 // 该属性可修改模型的透亮度,更多属性可参照 HT 格调手册 data.s('shape3d.opacity', 0.8); } ... }) g3dView.getView().addEventListener('drop', function(e) { // 猎取鼠标位置模型 var data = g3dView.getDataAt(e); if(!data) return; // 鼠标位置不是预置模型,直接跳过 if(data.getDisplayName() !== 'box') return; data.s('shape3d.opacity', 0); // 罢休时候设定 所有的 displayName 为 box 的节点 不成见 array.forEach(function(data) { data.s('3d.visible', false); }); var node = new ht.Node(); node.s('shape3d', url); // 档案袋 3D 模型地址 node.r3([Math.PI/2, -Math.PI/2, 0]); // 扭转档案袋模型, 使其平放 node.p3(data.p3()); node.setParent(g3dView._focusData); node.setHost(g3dView._focusData); });
档案柜虚化结果实现
上面我们已经实现了档案袋拖拽至 3D 场景的结果,但是我们可以发明档案袋模型远小于柜子,要将档案袋摆放到准确的位置并不是那么容易。所以此时我们可以将需要操纵的档案柜放大到正中间,其它模型进行虚化处置。
// 3D 拓扑交互监听 g3dView.mi(function(e){ if(e.kind === 'doubleClickData') { // 双击事件 var shape3d = e.data.s('shape3d'), parentShape3d = e.data.getParent() && e.data.getParent().s('shape3d'); if (shape3d && shape3d.indexOf('档案柜') > -1) { // 重点突出档案柜 showDetail(e.data); } else if (parentShape3d && parentShape3d.indexOf('档案柜') > -1) { showDetail(e.data.getParent()); } } }); showDetail = function(data) { // 保留进入虚化状态前 视角 与 核心点 eyeBack = ht.Default.clone(graph3dView.getEye()); centerBack = ht.Default.clone(graph3dView.getCenter()); // 设定相机指向配置 var opt = {}; opt.animation = true; opt.ratio = 1; opt.direction = [1, 0.5, 0]; opt.center = [data.getX(), 100, data.getY()]; graph3dView.flyTo(data, opt); focusData = data; data.s('select.brightness', 1); dataModel.each(function (d) { if (d === focusData || (!d.s('3d.selectable') && d.getTag() !== 'wall') || d.getParent() === focusData || d.getDisplayName() === 'box') return; // 将拓扑中除了要操纵的柜子 与柜子中档案袋 以及墙外 透亮度都设定为 opacity (0~1) // 保留设定前配置, 复原用 if (!opacityMap[d.getId()]) { opacityMap[d.getId()] = { 'shape3d.opacity': d.s('shape3d.opacity'), 'shape3d.transparent': d.s('shape3d.transparent'), 'all.opacity': d.s('all.opacity'), 'all.transparent': d.s('all.transparent'), 'left.opacity': d.s('left.opacity'), 'left.transparent': d.s('left.transparent'), 'right.opacity': d.s('right.opacity'), 'right.transparent': d.s('right.transparent'), 'front.opacity': d.s('front.opacity'), 'front.transparent': d.s('front.transparent'), 'back.opacity': d.s('back.opacity'), 'back.transparent': d.s('back.transparent'), 'top.opacity': d.s('top.opacity'), 'top.transparent': d.s('top.transparent'), 'bottom.opacity': d.s('bottom.opacity'), 'bottom.transparent': d.s('bottom.transparent'), '3d.selectable': d.s('3d.selectable') } } // 透亮度设定为 opacity d.s({ 'shape3d.opacity': opacity, 'shape3d.transparent': true, 'all.opacity': opacity, 'all.transparent': true, 'left.opacity': opacity, 'left.transparent': true, 'right.opacity': opacity, 'right.transparent': true, 'front.opacity': opacity, 'front.transparent': true, 'back.opacity': opacity, 'back.transparent': true, 'top.opacity': opacity, 'top.transparent': true, 'bottom.opacity': opacity, 'bottom.transparent': true, '3d.selectable': false }); }); }
退出虚化模式,以监控 3D 拓扑的选择变化来实现
g3dView.dm().ms(function(e) { var lastData = g3dView.sm().ld(); // 推断可否进行虚化 if(focusData) { if(lastData === focusData || (lastData && lastData.getParetn() === focusData)) return; g3dView.setEye(eyeBack); g3dView.setCenter(centerBack); // 复原模型的原透亮度 g3dView.dm().each(function (d) { if (d === focusData) return; d.s(opacityMap[d.getId()]); }); focusData.s('select.brightness', 0.7); focusData = null; eyeBack = null; centerBack = null; } });
迅速查询功能实现
在 HT 的组件中有供给迅速查询插件 QuickFinder ,此次我们就使用该插件来实现简略的档案编号查询
// 初始化 输入框 var textField = new ht.ui.TextField; textField.setIcon("imgs/search.json"); textField.setIconPosition("left"); // 初始化查询器,前提:id var finder = new ht.QuickFinder(library.view.dm, "id"); // 输入框点击查询按钮时触发 textField.on('p:value', function(e) { var dm = library.view.dm; var value = e.newValue; var datas = finder.find(value); // 查询到对应的图元时,我们将首先个效果进行选择 if (datas && datas.size() > 0) { library.view.dm.sm().ss(datas.get(0)); } });
总结
经过以上功能的实现,一个根基的智慧档案治理系统就成形了。固然做为一个智慧治理系统,这些还是远远不足的,例如档案动态监控、档案室内人员走动监控、视频监控、温度监控、灾祸报警等等模块都是后期可以完美的地方。这里只是简略地为大家供给了一个基于 HTML5 WEBGL 的 3D 解决方案。一样道理,智能楼宇、智能机房、智能城市也可以基于此来实现。