基於HTML5快速搭建3D機房裝置皮膚
以真實裝置為模型,搭建出裝置皮膚,並實時獲取裝置執行引數,顯示在裝置皮膚上,這相比於純數值的裝置監控系統顯得更加生動直觀。今天我們就在HT for Web的3D技術上完成裝置皮膚的搭建。
我們今天模擬的裝置是機房裝置,先來目睹下最終效果:http://www.hightopo.com/demo/blog_3d_20150810/server.html
我來解釋下這個模型,一個帶有透明玻璃門的機櫃,機櫃裡裝有5臺裝置,門可以開合,裝置可以插拔,那麼我麼該如何搭建這樣的裝置呢?方法不難,我們一步一步來。
我們先從裝置開始,裝置的示意圖如下:
看起來有模有樣的,其實呢,它就是一個長方體,然後在長方體的正面貼上一張圖片,這樣子裝置的殼就出來了,建立程式碼如下:
var node = createNode([0, 0, 0], [475, 100, 0]); node.s({ `front.image`: `panel`, `all.color`: `#E6DEEC` }); node.setToolTip(`Double click to pop the server’);
其中設定裝置的正面圖片的方法是通過設定節點的front.image樣式屬性來實現的,在程式碼中將front.image屬性設定為’panel’,而’panel’屬性是已經通過ht.Default.setImage()方法註冊了的圖片的別名,在程式碼中還設定了長方體各個面的顏色和滑鼠懸停時的提示語。
在程式碼中還呼叫了createNode()的方法,該方法並沒有做什麼特殊的操作,只是將建立3D拓撲節點的程式碼封裝起來,精簡程式碼,避免相同的程式碼重複書寫,具體的封裝如下:
/** * 建立3D拓撲節點,並新增到dataModel中 * @param p3 {array} 位置資訊 * @param s3 {array} 長寬高資訊 * @returns {ht.Node} 3D拓撲節點 */ function createNode(p3, s3) { var node = new ht.Node(); node.s({ `shape` : `rect` }); node.p3(p3); node.s3(s3); dataModel.add(node); return node; }
該方法通過傳入位置資訊和大小資訊建立出一個3D拓撲節點,並新增到dataModel中,最後返回該節點物件。
剛剛我們只是建立了裝置的外殼而已,在裝置上又部分埠是被被佔用的,所以接下來我們要做的就是填充裝置埠,仔細看了下裝置的埠形狀,發現形狀是不規則的呢,那麼裝置埠該如何填充呢?我們只需要找一個和埠形狀一樣的圖片貼在長方體的正面,然後套在裝置上就可以了,具體的實現如下:
/** * 建立埠節點,並吸附到指定的節點上 * @param indexes {array} 埠位置資訊 * @param host {ht.Node} 被吸附的節點物件 */ function createPort(indexes, host) { var p3 = host.p3(), s3 = host.s3(), x = -s3[0] / 2, y = 100 / 2 + p3[1], z = 1 + s3[2] / 2; indexes.forEach(function(index) { var port = new ht.Node(); port.setName(`Port`); port.s({ `front.image` : `port_green`, `all.light` : true }); port.setHost(host); port.setSize3d(28, 23, 10); if (index % 2 === 0) { var col = (index - 2) / 2; port.setPosition3d(x + 67.5 + col * 32, y - 60.5, z); port.s({ `front.uv` : [0, 1, 0, 0, 1, 0, 1, 1] }); } else { var col = (index - 1) / 2; port.setPosition3d(x + 67.5 + col * 32, y - 26.5, z); } dataModel.add(port); }); }
在裝置上總共有20個埠,我們通過傳入的埠位置資訊來確定建立出來的節點位置,仔細觀察裝置埠可以發現,第二排的埠和第一排的埠方向不一樣,所以在建立第二排的埠時需要通過設定front.uv屬性來控制貼圖的翻轉,當然貼圖也是我們事先註冊好了的。
好了,到這裡我們的裝置模型就構建出來了,那麼接下來就是建立機櫃了,機櫃的建立就和裝置外殼的建立基本相似,不一樣的地方在於,機櫃有一個門,這個門有開合的功能,由於拓撲節點無法單獨對節點的某一面分離出來做旋轉操作,所以門必須是一個單獨的拓撲節點,我們先來看看機櫃的效果圖:
效果圖種,我們把門稍微裝飾了一下,在門的邊緣上加上了藍色的貼邊,讓門看起來更有質感,效果圖和思路都有了,程式碼自然而然就出來了,瞧瞧下面的程式碼,有一點點小複雜哦。
var h = 1000, w = 477, d = 400, k = 20; // 建立機櫃 var main = createNode([0, 0, 0], [w, h, d]); main.s({ `all.color` : `#403F46`, `front.visible` : false }); // 建立門 var face = new ht.Shape(), s = {`all.visible` : false, `front.visible` : true}; dataModel.add(face); face.addPoint({x : -w / 2, y : d / 2 - 1}); face.addPoint({x : w / 2, y : d / 2 - 1}); face.addPoint({x : w + w / 2, y : d / 2 - 1}); face.setSegments([1, 2, 1]); face.setTall(h); face.setThickness(1); face.s(s); face.setHost(main); face.s({ `all.color` : `rgba(0, 40, 60, 0.7)`, `all.reverse.flip` : true, `all.transparent` : true, `3d.movable` : false }); face.face = true; face.open = false; face.angle = -Math.PI * 0.6; face.setToolTip(`Double click to open the door`); // 建立門的貼邊 var up = createNode([0, h / 2 - k / 2, d / 2], [w, k, 1], false, false).s(s), down = createNode([0, -h / 2 + k / 2, d / 2], [w, k, 1], false, false).s(s), right = createNode([w / 2 - k / 2, 0, d / 2], [k, h, 1], false, false).s(s), left = createNode([-w / 2 + k / 2, 0, d / 2], [k, h, 1], false, false).s(s); up.setHost(face); down.setHost(face); left.setHost(face); right.setHost(face);
程式碼的邏輯是這樣的,先建立一個長方體作為機櫃的外殼,然後將長方體的正面設定為隱藏,然後建立一個多邊形作為門,將門設為淺藍色半透明,最後建立4個藍色長方體貼到門的邊緣作為裝飾,如此一個機櫃就搭建完成了。
裝置模型有了,機櫃有了,接下來的工作就是將兩者合併起來,方法很簡單,就是建立裝置並將裝置吸附到機櫃上,具體的程式碼如下:
var num = 5, start = 400; for (var i = 0; i < num; i++) { var y = start - 170 * i, z = (d - 30) / 2; var node = createNode([0, y, 0], [w - 2, 100, d - 30]); node.s({ `front.image` : `panel`, `all.color` : `#E6DEEC`, `all.reverse.cull` : true, `3d.movable` : false }); node.pop = false; node.setToolTip(`Double click to pop the server`); node.setHost(main); createPort([1, 2, 3, 4, 5, 6, 7, 13, 16, 17, 20], node); }
還記得前面構建裝置模型和機櫃門的程式碼中,我們對這兩個模型新增了滑鼠懸停時的提示內容,雙擊可以開啟門,雙擊可以抽出裝置,那麼我們現在就來實現這兩個效果,首先我們來分析下具體的實現方案:
雙擊的事件要新增在哪裡呢?對每個拓撲節點做監聽嗎?這是最直接的方法,但是這樣做的話,有多少節點將會有多少個對應的處理函式,而且同一型別的處理函式又是一樣的,那麼這就會導致系統資源的浪費,所以對每個節點做雙擊的監聽方案是不可取的,那麼我們該如何處理雙擊事件呢?我們可以換個角度思考,所有的節點都是新增到3D拓撲元件上的,那麼我們是否可以通過監聽3D拓撲元件的雙擊事件,然後通過事件物件獲取到對應的節點,然後通過判斷節點上設定的自定義標識屬性來做相應的處理,具體的程式碼如下:
// 監聽3D拓撲元件的dataDoubleClicked事件 g3d.onDataDoubleClicked = function(data, e, dataInfo) { // 若果節點為門 if (data.face) { // 遍歷所有吸附在機櫃下的節點 data.getHost().getAttaches().each(function(attach) { // 如果節點狀態為彈出,則呼叫函式還原節點位置 if (attach.pop) { toggleData(attach); } }); } // 如果節點為埠節點,則觸發其所吸附裝置的雙擊事件 else if (data.a(`port`)) { toggleData(data.getHost()); return; } toggleData(data); };
閱讀上面的程式碼,大家會發現實現的方案和我們提到的方案不太一樣,我們通過監聽3D拓撲元件的dataDoubleClicked事件就可以直接獲取到被雙擊的節點物件,而無需我們自己通過事件物件獲取對應的節點物件,當然就監聽dataDoubleClicked事件了。
在程式碼中,我們呼叫了toggleData()方法來處理雙擊事件,具體的處理程式碼如下:
/** * 節點雙擊處理函式 * @param data {ht.Node} 被雙擊的節點 */ function toggleData(data) { var angle = data.angle, pop = data.pop; // 當前雙擊的物件為門 if (angle != null) { if (anim) { anim.stop(true); } var oldAngle = data.getRotation(); if (data.open) { angle = -angle; } data.open = !data.open; anim = ht.Default.startAnim({ action : function(t) { data.setRotation(oldAngle + t * angle); } }); } // 當前雙擊的物件為裝置 else if (pop != null) { if (anim) { anim.stop(true); } var p3 = data.p3(), s3 = data.s3(), dist = (pop ? -s3[2] : s3[2]) / 2; data.pop = !data.pop; anim = ht.Default.startAnim({ action : function(t) { data.p3(p3[0], p3[1], p3[2] + t * dist); } }); } }
在程式碼中,根據節點預設的不同的屬性值來確認該做什麼處理,如果節點物件是門的話,則通過ht.Default.startAnim()方法緩慢的修改門的rotation;如果節點物件是裝置的話,則緩慢修改裝置的position。
到這裡,今天的Demo的所有表現和功能就完成了,今天的內容中有設計到節點的style應用,我沒有做深入的講解,後續會給大家一一介紹,感興趣的朋友可以通過HT for Web的樣式手冊來了解更多的內容。
下面附上今天的Demo原始碼及視訊。
我已經把今天的Demo上傳至官網了,感興趣的朋友可以點選這裡訪問。
http://www.hightopo.com/demo/blog_3d_20150810/server.html
http://v.youku.com/v_show/id_XMTMwNTY2ODE0NA==.html
相關文章
- 基於HT for Web 3D 技術快速搭建裝置皮膚Web3D
- 基於HTML5快速搭建TP-LINK電信拓撲裝置皮膚HTML
- 基於 HTML5 WebGL 的 3D 機房HTMLWeb3D
- 基於 HTML5 Canvas 的 3D 機房建立HTMLCanvas3D
- 基於 WebGl HTML5 的 3D 視覺化機房WebHTML3D視覺化
- 基於 HTML5 Canvas 實現的 TP-LINK 電信拓撲裝置皮膚HTMLCanvas
- BlueHost主機Plesk皮膚快速安裝WordPress教程
- 基於 HTML5 的 3D 機房視覺化實景監控HTML3D視覺化
- 基於HTML5的電信網管3D機房監控應用HTML3D
- 基於HTML5的WebGL經典3D虛擬機器房漫遊動畫HTMLWeb3D虛擬機動畫
- 基於HTML5的WebGL電信網管3D機房監控應用HTMLWeb3D
- 基於 HTML5 和 VR 技術的 3D 機房資料中心視覺化HTMLVR3D視覺化
- 基於 HTML5 WebGL 的 3D 挖掘機HTMLWeb3D
- 後續來啦:Winform/WPF中快速搭建日誌皮膚ORM
- 初學者使用1Panel皮膚快速搭建WordPress網站網站
- 基於“SMemory”的部落格園皮膚美化
- 基於 HTML5 WebGL 的 3D 科幻風機HTMLWeb3D
- 基於 Electron 實現 uTools 的超級皮膚
- 基於Bootstrap的後臺管理皮膚:Bootstrap Metro Dashboardboot
- win10怎麼快速開啟控制皮膚 win10快速開啟控制皮膚的方法Win10
- 基於 HTML5 Canvas 電信網路拓撲圖的快速搭建HTMLCanvas
- 基於 HTML5 的 3D 飛機飛行軌道控制HTML3D
- 手機端除錯皮膚除錯
- WDCP控制皮膚安裝解除安裝
- 三款Linux下的免費控制皮膚及快速安裝Linux
- .NET基礎之主題和皮膚
- 寶塔Linux皮膚搭建與安全狗安裝(WEB伺服器搭建與WAF安裝)LinuxWeb伺服器
- 新款iPad Pro的OLED顯示皮膚成本可能高於前代機型的Mini LED液晶皮膚iPad
- 基於 HTML5 WebGL 的 3D 風機視覺化系統HTMLWeb3D視覺化
- 基於 HTML5 WebGL 的挖掘機 3D 視覺化應用HTMLWeb3D視覺化
- 基於HTML5 WebGL實現3D飛機葉輪旋轉HTMLWeb3D
- BlueHost cPanel皮膚安裝Nginx教程Nginx
- 寶塔Windows皮膚的安裝Windows
- 基於 HTML5 的 3D 工控隧道案例HTML3D
- win10控制皮膚中的裝置打不開怎麼解決Win10
- 基於 HTML5 的工業網際網路雲平臺監控機房 U 位HTML
- win10控制皮膚快捷鍵是什麼 快速開啟控制皮膚的具體方法Win10
- 小喬皮膚