基于 HTML5 Canvas 的 Web SCADA 组态电机控制面板
前言
ht for web 提供完整的基于 html5 图形界面组件库。您可以轻松构建现代化的,跨桌面和移动终端的企业应用,无需担忧跨平台兼容性,及触屏手势交互等棘手问题。也可用于快速创建和部署,高度可定制化,并具有强大交互功能的拓扑图形及表盘图表等应用。ht for web 非常适用于实时监控系统的界面呈现,广泛应用于电信网络拓扑和设备管理,以及电力、燃气等工业自动化 ( hmi / scada ) 领域。ht for web 还有提供了一套一套强大的基于 webgl 技术的 3d 图形引擎,独特的 webgl 层抽象,将 model – view – presenter ( mvp ) 的设计模型延伸应用到了 3d 图形领域。使用 ht for web 您可更关注于业务逻辑功能,不必将精力投入复杂 3d 渲染和数学等非业务核心的技术细节。( )
作为刚入门的小白,我尝试着一步一步的做这个面板,用这篇文章来记录自己的一些收获(毕竟我还是个菜鸟)以及代码的实现,希望能够帮到一些朋友。当然,如果有什么意见可以直接跟我说,大家一起交流才会进步!
效果图
代码实现
话不多说,上代码。整体是一个 2d 的面板,那么要引入我们必须需要用到的 ht 核心库:ht.js 。
首先,要创建数据容器和拓扑图形组件。datemodel 作为承载 data 数据的模型,管理着data数据的增删以及变化事件派发, ht 框架所有组件都是通过绑定 datamodel,以不同的形式呈现到用户界面;同时组件也会监听 datamodel 模型的变化事件, 实时同步更新界面数据信息,掌握了 datamodel 的操作就掌握了所有组件的模型驱动方式;拓扑图形组件 ht.graph.graphview 是 ht 框架中 2d 功能最丰富的组件,其相关类库都在 ht.graph 包下。graphview 具有基本图形的呈现和编辑、拓扑节点连线及自动布局功能。
var datamodel = new ht.datamodel(); var graphview = new ht.graph.graphview(datamodel);
通过以下代码来进行一些基础操作上的设置:
// 禁止平移
graphview.setpannable(false);
// 将其重载为空函数,禁止滚动 graphview.handlescroll = function() {};
// 禁用touch上双指操作缩放 graphview.handlepinch = function() {};
// 禁止拓扑上框选操作 graphview.setrectselectable(false);
// 通过过滤器设置禁止拖动 graphview.setmovablefunc(function(data) { return false; });
// 后将组件加入到指定的 dom 元素底下,不指定则加入到 document.body 下 graphview.addtodom(); window.addeventlistener('resize', function(e) { graphview.fitcontent(); }, false);
接下来通过请求把图纸(json 文件)的 url 写好拿到我们精心设计的面板。先还原成 json 字符串,然后将其反序列化并加入 datamodal 然后就可以操作数据了。
var json = ht.default.parse(text); datamodel.deserialize(json);
然后,我们来实现其中的一些小效果。第一,我想让 alarm 的 4 个小灯每 2s 交替变化一次。那么,让咱们来写一个函数来控制它们:
var flag = true; setinterval(function () { changealarmcolor(datamodel, 'alarm1', flag); changealarmcolor(datamodel, 'alarm2', flag); changealarmcolor(datamodel, 'alarm3', flag); changealarmcolor(datamodel, 'alarm4', flag); flag = !flag; }, 2000);
function changealarmcolor(datamodel, tag, flag) { var tag = datamodel.getdatabytag(tag); if(flag) { tag.a('backgroundcolor', 'rgb(138,40,18)'); tag.a('progressivecolor', 'rgb(232,97,56)'); } else { tag.a('backgroundcolor', 'rgb(34,168,38)'); tag.a('progressivecolor', 'rgb(82,222,133)'); } }
因为我之前在 2d 编辑器中已经对它们的 tag 和属性名进行了设置,所以我在这里直接通过寻找 tag 值来返回指定标示的 data 对象。接着只需要改变它们的属性值就可以产生想要的效果了。(.a 是获取或设置 attr 属性的简写,仅有一个参数时相当于getattr,有两个参数时相当于setattr)怎么样,是不是很简单。同理,我们再将 pump 中每个部分的文字和颜色每 2.5s 变化一次。
setinterval(function () { changepumpstate(datamodel, 'pump1'); changepumpstate(datamodel, 'pump2'); changepumpstate(datamodel, 'pump3'); }, 2500);
function changepumpstate(datamodel, tag) { var tag = datamodel.getdatabytag(tag); var num = math.floor(math.random() * 3 + 1); tag.a('status', num); }
到这里,细心的朋友可能看出我换了写法,用了一个 status 属性。因为我们以后会遇到更多的属性需要根据需求同时变化,那么我们逐一去操作会写出大量的代码。对比一下“笨方法”:
function changepumpstate(datamodel, tag) { var tag = datamodel.getdatabytag(tag); var changearr = [ { instruction: 'stopped', instructioncolor: 'rgb(234,0,0)', backgroundcolor: 'rgb(138,40,18)', progressivecolor: 'rgb(232,97,56)', status: 'fault' }, { instruction: 'need to run', instructioncolor: 'rgb(221,181,0)', backgroundcolor: 'rgb(29,143,32)', progressivecolor: 'rgb(82,222,133)', status: 'no fault' }, { instruction: 'running', instructioncolor: 'rgb(92,137,34)', backgroundcolor: 'rgb(29,143,32)', progressivecolor: 'rgb(82,222,133)', status: 'no fault' } ]; i = math.floor(math.random() * (changearr.length - 1 + 1)); tag.a('instruction', changearr[i].instruction); tag.a('instructioncolor', changearr[i].instructioncolor); tag.a('backgroundcolor', changearr[i].backgroundcolor); tag.a('progressivecolor', changearr[i].progressivecolor); tag.a('status', changearr[i].status); }
所以,我在图标里自己声明了一个属性,并通过改变 status 值来控制我在编辑器中绑定在一起的属性以达到同时变换。哦对了,大家在做点击图标产生变化的时候别忘记在 2d 编辑器中选中“可交互”!下面我们再做一个 tank 进度条每 3s 随机变化一次的动画效果。
setinterval(function () { var tag = datamodel.getdatabytag('tank'); var num = math.random() * 1; ht.default.startanim({ duration: 500, action: function(v, t){ tag.a('progress', num * v); } }); }, 3000);
这里我们用到了动画。在 ht 的数据模型驱动图形组件的设计架构下,动画可理解为将某些属性由起始值逐渐变到目标值的过程, ht 提供了 ht.default.startanim 的动画函数。它支持 frame-based 和 time-based 两种方式的动画,frame-based方式是用户通过指定 frames 动画帧数,以及 interval 动画帧间隔参数控制动画效果。
我用的是 time-based 方式,该方式用户只需要指定 duration 的动画周期的毫秒数即可,ht 将在指定的时间周期内完成动画, 不同于 frame-based 方式有明确固定的帧数,即 action 函数被调用多少次,time-based 方式帧数或 action 函数被调用次数取决于系统环境, 一般来说系统配置更好的机器,更高效的浏览器则调用帧数越多,动画过程更平滑。由于 js 语言无法精确控制 interval 时间间隔, 采用 frame-based 不能精确控制动画时间周期,即使相同的 frames 和 interval 参数在不同的环境,可能会出现动画周期差异较大的问题, 因此 ht 默认采用 time-based 的方式,如果不设置 duration 和 frames 参数,则 duration 参数将被系统自动设置为 ht.default.animduration 值。action 函数就是实现动画过程中的属性变化(变化参数和进度)。
好了,如果你们还想改变其 ht 系统默认属性,可以通过全局的 htconfig 变量名指定,ht 系统只在初始化时读取 htconfig 的配置信息, 因此该属性必须在引入 ht.js 包之前初始化好,运行状态时修改 htconfig 变量不会再起作用。示例代码如下:
<script> htconfig = { color: { label: '#000', labelselect: '#fff' }, default: { tooltipdelay: 100, tooltipcontinual: true }, style: { 'select.color': '#e74c3c', 'select.width': 0// 去掉默认选中样式(绿框) } }; </script> <script src="ht.js"></script>
总结
刚开始做的时候很费劲,之前没有接触过,不过用上编辑器之后发现一切都没有想象的那么难,虽然花了些时间,但是总的来说收获还是很大的,成长了很多,人都是要不断进步嘛~
通过这个 demo 的实现,你也将会慢慢联想到很多东西。互联网+ 的概念在新兴产业上能够很好地运营,同时在传统行业中利用得当同样能够产生非常大的效益,比如智慧城市建设,智慧能源管理,智慧工厂,甚至是地铁、隧道监管等等都可以结合互联网+ 的模式来运作,在一定程度上节省了非常多的人力和时间成本!
上一篇: Hive安装、配置和使用
下一篇: MySQL的5种时间类型的比较
推荐阅读
-
基于 HTML5 Canvas 的 Web SCADA 组态电机控制面板
-
基于 HTML5 Canvas 的智能安防 SCADA 巡逻模块
-
基于HTML5的Web SCADA工控移动应用
-
基于 HTML5 WebGL 的计量站三维可视化监控系统 Web 组态工控应用
-
基于 HTML5 WebGL 的 3D 风机 Web 组态工业互联网应用
-
web前端入门到实战:基于 HTML5 Canvas 实现的文字动画特效
-
基于 HTML5 Canvas 的 Web SCADA 组态电机控制面板
-
基于HTML5的Web SCADA工控移动应用
-
基于 HTML5 的 Web SCADA 报表 SCADAHTML5ht-for-web报表矢量
-
基于HTML5的Web SCADA报表图文代码详解