基于HTML5Canvas的WebSCADA组态电机控制⾯板
前⾔
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 = aph.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 = DataByTag(tag);
if(flag) {
tag.a('backgroundColor', 'rgb(138,40,18)');
tag.a('progressiveColor', 'rgb(232,97,56)');
canvas动画} 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 = DataByTag(tag);
  var num = Math.floor(Math.random() * 3 + 1);
  tag.a('status', num);
}
到这⾥,细⼼的朋友可能看出我换了写法,⽤了⼀个 status 属性。因为我们以后会遇到更多的属性需要根据需求同时变化,那么我们逐⼀去操作会写出⼤量的代码。对⽐⼀下“笨⽅法”:
function changePumpState(dataModel, tag) {
  var tag = DataByTag(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 = DataByTag('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: {
      'lor': '#E74C3C',
      'select.width': 0// 去掉默认选中样式(绿框)
    }
  };
</script>
<script src="ht.js"></script>
总结
刚开始做的时候很费劲,之前没有接触过,不过⽤上编辑器之后发现⼀切都没有想象的那么难,虽然花了些时间,但是总的来说收获还是很
⼤的,成长了很多,⼈都是要不断进步嘛~
通过这个 demo 的实现,你也将会慢慢联想到很多东西。互联⽹+ 的概念在新兴产业上能够很好地运营,同时在传统⾏业中利⽤得当同样能够产⽣⾮常⼤的效益,⽐如智慧城市建设,智慧能源管理,智慧⼯⼚,甚⾄是地铁、隧道监管等等都可以结合互联⽹+ 的模式来运作,在⼀定程度上节省了⾮常多的⼈⼒和时间成本!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。