物聯網( IoT ),簡單的理解就是物體之間經過互聯網進行連接。世界上的萬事萬物,均可以經過數據的改變進行智能化管理。IoT 的興起在醫療行業中具備拯救生命的潛在做用。
不斷的收集用戶信息而且實時的進行診斷,因此將來 IoT 確定在醫療行業的應用會呈覆蓋性。下面是我最近作的一個醫療物流系統,用來觀察醫療物流過程。html
ht官網連接:http://www.hightopo.com/cn-index.html前端
demo連接: https://www.hightopo.com/demo/pivas/
node
整個原場景實際上是很是暗的,因此須要使用燈光的效果照亮整個場景,使其接近真實世界的場景。函數
咱們看下對比。動畫
light 的一些屬性: this
type 表明燈光的類型spa
color 表明燈光的顏色3d
intensity 表明燈光的強度(1是最大值)code
range 表明範圍htm
addLight() { const skyBox = this.dm.getDataByTag('skyBox') // 限制視野在天空球以內 this.gv.setSkyBox(skyBox) const light = new ht.Light() const lightSource = this.dm.getDataByTag('sunlight').p3() const config = { 'light.type': 'point', 'light.color': 'white', 'light.intensity': 0.3, 'light.range': 10000 } light.s(config) light.p3(lightSource)this.dm.add(light) }
看到左下角的一個小窗口,實際上是另外一個3d場景,把它定位到左下角的,兩個場景都使用了反序列化( deserialize )。
由於要定位醫療箱移動,因此這裏使用到了 flyTo 方法 。
var renderCanvas = function (medical, duration) { ht.Default.startAnim({ duration, easing(v, t) { return t }, action(v, t) { outScreenG3d.flyTo(medical, { direction: [-5, 3, 5], distance: 300 }) } }) }
若是要實現這麼多的動畫,首先想到的是一個個物體進行移動的過程。醫療箱的行走、電梯的升降、傳送帶運送醫療箱等咱們均可以對它們的動做進行封裝。
如圖能夠看到醫療箱老是在動,因此定義了一個行走的動畫,每次醫療箱行走的距離、行走方向、動畫的配置都進行傳參。
這裏要說明的參數:
1.node(對應的元素)
2.fn(動畫執行完進行回調的函數)
3.config(動畫配置)
4.coord(方向軸)
// 行走動畫 walkAnim(node, fn, config, coord) { const { duration, space } = config const positionArray = node.p3() let isShadow = false let ShadowNode = null // 若是移動的元素是icu車或者供應車的話 獲取它的陰影跟隨元素移動 if (node.getTag() === 'supply' || node.getTag() === 'icuCar') { isShadow = true ShadowNode = this.dm.getDataByTag(`${node.getTag()}Shadow`) } ht.Default.startAnim({ duration, easing: function (t) { return t }, action(v, t) { if (coord === 'x') { node.p3(positionArray[0] + t * space, positionArray[1], positionArray[2]) isShadow && ShadowNode.p3(positionArray[0] + t * space, positionArray[1], positionArray[2]) } else if (coord === 'y') { node.p3(positionArray[0], positionArray[1] + t * space, positionArray[2]) isShadow && ShadowNode.p3(positionArray[0], positionArray[1] + t * space, positionArray[2]) } else { node.p3(positionArray[0], positionArray[1], positionArray[2] + t * space) isShadow && ShadowNode.p3(positionArray[0], positionArray[1], positionArray[2] + t * space) } }, finishFunc() { typeof fn === 'function' && fn(node) } }) }
電梯的升降會影響不少東西,好比頻臺的移動會帶着傳送帶和醫療箱,這裏我用到了 sethost 吸附方法(吸附:節點指定宿主,宿主進行改變會影響節點)。
不少場景下很是合適,我須要電梯升降的過程當中帶用醫療箱和頻臺一塊兒上升,還有醫療箱放到傳送帶的時候,醫療箱要動起來,感受是這真的傳送帶在帶動醫療箱進行運動。
這裏要說明的參數:
1.node(操做的電梯元素)
2.medicalKit(醫療箱)
3.fn(動畫執行完進行回調的函數)
4.status (電梯上升和降低的狀態)
5.config(動畫配置)
// 電梯升降動畫 elevatorAnim(node, medicalKit, fn, status, config) { const self = this // 獲取電梯的index 讓對應的頻臺也跟着動 const elevatorIndex = node.getTag().replace(/[^0-9]/ig, '') - 0 // 獲取醫療箱的index 控制電梯升降的距離 const medicalKitIndex = medicalKit.getTag().replace(/[^0-9]/ig, '') - 0 const positionArray = node.p3() const station = self.dm.getDataByTag(`station${elevatorIndex}`) //吸附宿主 station.setHost(node) medicalKit.setHost(node) // 設置升降狀態 if (elevatorIndex === 3) self.elevatorRunning = true // 升降距離 status 爲 0 的時候是降低 最低部位的距離是固定的 因此只須要控制上升的距離 const medicalKitLevel = self.returnMedicalKitLevel(medicalKitIndex) // 電梯的屬性 // 最低點的位置 Lowest // 若是有軌道的話 就去軌道的位置 不然就按照層數 orbitalP // 第一層的位置 distance let space const addSpace = medicalKitIndex === 7 ? 100 : 0 if (status == 1) { space = config.orbitalP ? config.orbitalP : config.distance + addSpace + (400 * medicalKitLevel) } else { space = config.Lowest } // 降低狀態時 醫療箱不會作動做 if (status === 0) { medicalKit.setHost() } return ht.Default.startAnim({ duration: config.orbitalP ? 2000 : (medicalKitLevel === 0 && elevatorIndex == 3 ? 700 : 2500 + (medicalKitLevel * 1000)), action(v, t) { node.p3( positionArray[0], positionArray[1] + ((space - positionArray[1]) * t), positionArray[2] ) }, finishFunc() { station.setHost() typeof fn === 'function' && fn(node) } }) }
動畫的過程當中有個問題須要處理就是等待電梯的動畫,醫療箱在動畫過程當中,須要判斷電梯是否在上升,若是不在地面的話,須要等待。
個人思路是,當醫療箱走到離電梯一點距離的時候,須要判斷電梯是否在上升狀態,若是是的話,須要調用動畫暫停的方法。
當 elevatorRunning 爲 false 的時候表明電梯沒有運動,不然在運動中。
電梯動畫開始的時候設置爲 true,結束後設置變量爲 false, 就能夠監控它的狀態了。
ht.Default.startAnim 方法返回一個實例,利用 action 方法, 實現輪詢監聽動畫狀態,而後進行操做。
當 elevatorRunning 爲 true 的話, 使用 anim.pause() 暫停當前動畫。
當 elevatorRunning 爲 false 的話, 使用 anim.resume() 繼續當前動畫。
const anim = ht.Default.startAnim({ duration, action(v, t) { node.p3( positionArray[0], positionArray[1], positionArray[2] - (tpMax - positionArray[2]) * t ); if (index > 1 && self.elevatorRunning === true) { if (node.p3()[2] <= stopMax) { anim.pause(); const t = setInterval(() => { if (self.elevatorRunning === false) { anim.resume(); clearInterval(t); } }, 100); } } }, finishFunc() { typeof fn === "function" && fn(); } });
由於須要監聽某個當前動畫的結束,而後進行相機位移。
如圖,我須要監聽第一個 3d 場景中顯示提示文字動畫結束,而後執行第二個 3d 場景的顯示。由於2個是不一樣的場景,是不能用回調的方法監聽到的,因此這裏就用到了 eventBus 事件總線。
下面是 eventBus 的使用,第一個參數表明要監聽的註冊函數名,第二個是回調函數。
// 事件總線 監聽事件 eventbus.on('animation1', _ => { const medical = dm.getDataByTag('medicalKit1') renderView(medical, dm, gv) })
下面是 eventBus 發射的使用,第一個參數表明要觸發的函數名,第二個是發射給函數的參數。
// 觸發事件 eventbus.emit("animation1", null);
作完這個 demo 以後,除了對 HT for Web 更加熟練以外,對物聯網也有了更深入的概念。
我身爲一名前端工做者,在這個時代感受很是的自豪,由於我能經過本身的技能創造出許多能造福和改善人們生活的東西。
但願你們看到個人 demo 可以獲得一些啓發,同時也要相信本身可以創造不可能,爲社會作出貢獻。