基於 H5 Canvas 實現樓宇自控系統


 

前言

樓宇自控是指樓宇中電力設備,如電梯、水泵、風機、空調等,其主要工作性質是強電驅動。通常這些設備是開放性的工作狀態,也就是說沒有形成一個閉環回路。只要接通電源,設備就在工作,至於工作狀態、進程、能耗等,無法在線及時得到數據,更談不上合理使用和節約能源。現在樓宇自控是將上述的電器設備進行在線監控,通過設置相應的傳感器、行程開關、光電控制等,對設備的工作狀態進行檢測,並通過線路返回控制機房的中心電腦,由電腦得出分析結果,再返回到設備終端進行調解。

(具體效果請參考鏈接: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 } // 全局設置右鍵菜單禁用
復制代碼
復制代碼

接下來就開始對面板進行封裝,實現每塊中包含的動畫效果,這些動效制作起來既簡單又能展現出整個系統的運動感,其實現的方式相仿,我就用一段例子來演示:

復制代碼
復制代碼
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 屬性可以通過數學公式計算來配置動畫的 緩動效果,感興趣的朋友可以打開來自己試着玩一玩。

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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM