基于 WebGL 3D 的 HTML5档案馆可视化管理系统

2024-08-30 11:08

本文主要是介绍基于 WebGL 3D 的 HTML5档案馆可视化管理系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

档案管理系统是通过建立统一的标准以规范整个文件管理,包括规范各业务系统的文件管理的完整的档案资源信息共享服务平台,主要实现档案流水化采集功能。为企事业单位的档案现代化管理,提供完整的解决方案,档案管理系统既可以自成系统,为用户提供完整的档案管理和网络查询功能,也可以与本单位的OA办公自动化和DPM设计过程管理,或者与MIS信息管理系统相结合,形成更加完善的现代化信息管理网络。传统档案馆随着社会的快速发展与变化,其内在形式上也发生了巨大变化,逐渐演变为现代智慧档案馆。智慧档案馆以现代科技为依托,充分结合现代物联网技术与云计算技术构建完善的城市智慧档案,实现了现代社会全面管理的目标。本文以当前流行的 H5 技术为主,为现代智慧档案馆提供一套 WEB 解决方案。

代码实现

场景搭建

在本例中,将使用 HT UI 组件对页面实现布局;使用 RelativeLayout 相对布局器将页面分为三个部分:left, top, center,使用 VBoxLayout 纵向布局器将 LEFT 部分分为 logo,editor,chart 三个部分

Graph3dView 加载 3D 场景

Graph3dView 是 HT(www.hightopo.com) 组件中加载 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 场景中,实现思路是:

1.  在拖拽时获取拖拽的图元信息
2.  拖拽到对应位置时显示可摆放位置
3.  结束拖拽后在对应位置创建对应的 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')}}// 透明度设置为 opacityd.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");// 初始化查询器,条件:idvar 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 解决方案。同样原理,智能楼宇、智能机房、智能城市也可以基于此来实现。

最终效果可查看:https://hightopo.com/demo/intelligent-archives/

这篇关于基于 WebGL 3D 的 HTML5档案馆可视化管理系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

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

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

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',