基于 HTML5 + Canvas 实现楼宇自控系统

前言

楼宇自控是指楼宇中电力设备,如电梯、水泵、风机、空调等,其主要工做性质是强电驱动。一般这些设备是开放性的工做状态,也就是说没有造成一个闭环回路。只要接通电源,设备就在工做,至于工做状态、进程、能耗等,没法在线及时获得数据,更谈不上合理使用和节约能源。如今楼宇自控是将上述的电器设备进行在线监控,经过设置相应的传感器、行程开关、光电控制等,对设备的工做状态进行检测,并经过线路返回控制机房的中心电脑,由电脑得出分析结果,再返回到设备终端进行调解。html

(具体效果请参考连接:http://www.hightopo.com/demo/building-automation-system/)浏览器

代码实现

首先第一步咱们仍是要对整个界面作一下基础的设置:缓存

复制代码
gv.getSelectWidth = () => { return 0 } // 隐藏选中边框
gv.setMovableFunc(() => { return false }) // 禁止图元移动
gv.handleScroll = () => {} // 禁止鼠标缩放
gv.handlePinch = () => {} // 禁止 touch 下双指缩放
gv.setPannable(false) // 禁止平移
gv.setRectSelectable(false) // 禁止框选
gv.setScrollBarVisible(false) // 隐藏滚动条
window.document.oncontextmenu = () => { return false } // 全局设置右键菜单禁用
复制代码

接下来就开始对面板进行封装,实现每块中包含的动画效果,这些动效制做起来既简单又能展示出整个系统的运动感,其实现的方式相仿,我就用一段例子来演示:dom

复制代码
function chillerPanelAnim() {
  let num = []
  let n = []
  for (let i = 0; i < 10; i++) {
    if (i < 8) {
      num.push(Math.random() * 2)
    }
    else if (i === 8) {
      n.push(Math.random() * 40 + 60)
    }
    else {
      n.push(Math.random() * 31)
    }
  }
  let oldNumValue1 = chillerPanel.a('l1.l.clipPercentage')
  let oldNumValue2 = chillerPanel.a('l2.l.clipPercentage')
  let oldNumValue3 = chillerPanel.a('l3.l.clipPercentage')
  ht.Default.startAnim({
    duration: 2000,
    easing: (t) => { return t },
    action: (v, t) => {
      chillerPanel.a('l1.l.clipPercentage', oldNumValue1 + (num[0] - oldNumValue1) * v)
      chillerPanel.a('l2.l.clipPercentage', oldNumValue2 + (num[1] - oldNumValue2) * v)
      chillerPanel.a('l3.l.clipPercentage', oldNumValue3 + (num[2] - oldNumValue3) * v)
    },
    finishFunc: () => {
      setTimeout(() => {
        chillerPanelAnim()
      }, 2000)
    }
  })
}
复制代码

关于动画的方法你们能够理解为将某些属性由起始值逐渐变到目标值的过程,HT 提供了 ht.Default.startAnim,它支持 Frame-Based 和 Time-Based 两种方式的动画,我使用 Time-Based 方式,优势在于只须要指定 duration 的动画周期的毫秒数便可,HT 将在指定的时间周期内完成动画,也就是说帧数或 action 函数被调用次数取决于系统环境,通常来讲系统配置更好的机器,更高效的浏览器则调用帧数越多,动画过程更平滑。避免了因为 js 语言没法精确控制 interval 时间间隔,可能会出现动画周期差别较大的问题。这其中还有个 easing 属性能够经过数学公式计算来配置动画的 缓动效果,感兴趣的朋友能够打开来本身试着玩一玩。ide

2.5D 设备的管道部分,我用调度的方式给你们介绍一下:函数

复制代码
// 流动动画
let flowTask = {
  interval: 10, action: (data) => { if (data.getDisplayName() === 'flow1') { data.s('shape.dash.offset', data.s('shape.dash.offset') + 1) } if (data.getDisplayName() === 'flow2') { data.s('shape.dash.offset', data.s('shape.dash.offset') - 1) } if (data.getDisplayName() === 'flow3') { data.s('shape.dash.offset', data.s('shape.dash.offset') + 5) } } }
dm.addScheduleTask(flowTask)
复制代码

这也是一种实现动效的方式,它主要用于在指定的时间间隔进行函数回调处理,经常使用于实现图形的流动和闪烁等动画效果。流程是先经过 DataModel 添加调度任务,DataModel 会在调度任务指定的时间间隔到达时,遍历全部图元回调调度任务的 action 函数,可在该函数中传入的 Data 图元作相应的属性修改以达到动画效果。更多参数和设置能够参考 调度手册性能

咱们还要注意最好给须要交互的图元的鼠标移入移出事件分别设置 view.setCursor('pointer') 和 view.setCursor('default') 来加强交互体验感。同时,制做 2.5D 的图元其实须要花费超出正常 2D 图元数倍的工做量,除了要按照真实角度的透视图去建模外,还须要把每一个部分单独制做。这就出现了有可能卡顿的问题,咱们作的时候要注意用缓存规则来优化性能,尽量的把每一个细节作好。cacheRule 就至关于都用同一个 image,默认规则时:图标名 + 宽 + 高 + 缩放,若是规则断定一致,就会用同一张贴图,若是有其余的须要影响,就多返回一些信息,例如 data.a( 'color' ),这样会额外断定他们这个属性也是否一致,只有都一致的才会用同一张缓存,不一致的话尝试新建缓存贴图,比较适合静态的。优化

总结

在二十一世纪的今天,随着计算机技术和信息技术日新月异的发展。对大楼内的各类设备的状态监视和测量再也不是随线式,而是采用扫描测量。智能建筑 (Intelligent Buildings) 是建筑技术与互联网技术相结合的产物,是信息社会与经济国际化的须要。今天咱们打造的楼宇自动化控制系统 (BAS) 就属于这其中的一类,还有通讯自动化系统 (CAS) 和办公自动化系统 (OAS) 等组成。现在已经普遍应用于各个领域,极大的提升了管理效率和能源的有效利用率以及设备监测等智能化为一体的操做系统。还有更多高大上的智能操做系统在等待着咱们推进社会信息化的进步!动画

HT for Web :(http://www.hightopo.com/demos/cn-index.html)ui

相关文章
相关标签/搜索