基於 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

相關文章
相關標籤/搜索