基於 HTML5 WebGL 的 3D 機房

2021-09-07 17:19:11 字數 4183 閱讀 4355

用 webgl 渲染的 3d 機房現在也不是什麼新鮮事兒了,這篇文章的主要目的是說明一下,3d 機房中的 eye 和 center 的問題,剛好在專案中用上了,好生思考了一番,最終覺得這個例子最符合我的要求,就拿來作為記錄。

這個 3d 機房的 demo 做的還不錯,比較美觀,基礎的互動也都滿足,接下來看看怎麼實現。

首先從 index.html 中呼叫的 js 路徑順序乙個乙個開啟對應的 js,server.js 中自定義了乙個 editor.server 類由 ht 封裝的 ht.default.def 函式建立的(注意,建立的類名 editor.server 前面的 editor 不能用 e 來替代):

這個類可以建立乙個 ht.node 節點,並設定節點的顏色和前面貼圖:

var s = e.server = function(obj) );

};

這樣我在需要建立伺服器元件的位置直接 new 乙個新的伺服器元件物件即可,並且能夠直接呼叫我們上面宣告的 sethost 等函式,很快我們就會用上。

接下來建立 editor.cabinet 機櫃類 ,方法跟上面 editor.server 類的定義方法差不多:

這個類相對於前面的 editor.server 伺服器元件類要相對複雜一點,這個類中建立了乙個櫃身、櫃門以及機櫃內部的伺服器元件:

var c = e.cabinet = function(obj) ); if (math.random() > 0.5) }//表示該組是否顯示 }); } var door = this._door = new ht.doorwindow();//櫃門 door.setwidth(s3[0]);//置圖元在3d拓撲中的x軸方向的長度 door.setheight(1);//設定圖元在3d拓撲中的z軸長度 door.settall(s3[1]);//控制node圖元在y軸的長度 door.setelevation(0);//設定圖元中心在3d座標系中的y座標 door.sety(s3[2] * 0.5);//設定節點在 y 軸的位置 door.sethost(node);//設定吸附 door.s(); var serverlist = this._serverlist = ; var max = 6, list = e.randomlist(max, math.floor(math.random() * (max - 2)) + 2); 中宣告的獲取隨機數的函式 var server, h = s3[0] / 4; list.foreach(function(r) ); server.s3(s3[0] - 2, h, s3[2] - 4);//設定節點大小 server.setelevation((r - max * 0.5) * (h + 2));//設定節點中心點在 y 軸的座標 server.sethost(node);//設定節點的吸附 serverlist.push(server);//向 serverlist 中新增 server 節點 }); };

上面**中唯一沒提到的是 editor.randomlist 函式,這個函式是在 global.js 檔案中宣告的,宣告如下:

var e = window.editor =  return list; } };
好了,場景中的各個部分的類都建立完成,那我們就該將場景建立起來,然後將這些圖元都堆進去!

如果熟悉的同學應該知道,用 ht 建立乙個 3d 場景只需要 new 乙個 3d 元件,再將通過 addtodom 函式將這個場景新增進 body 中即可:

var g3d = e.main = new ht.graph3d.graph3dview(); //3d 場景
main.js 檔案中主要做的是在 3d 場景中一些必要的元素,比如牆面,地板,門,空調以及所有的機櫃的生成和排放位置,還有非常重要的互動部分。

牆體,地板,門,空調和機櫃的建立我就不貼**出來了,有興趣的請自行檢視**,這裡主要說一下雙擊機櫃以及與機櫃有關的任何物體(櫃門,伺服器裝置)則 3d 中 camera 的視線就會移動到雙擊的機櫃的前方某個位置,而且這個移動是非常順滑的,之前技藝不精,導致這個部分想了很久,最後參考了這個 demo 的實現方法。

為了能夠重複地設定 eye 和 center,將設定這兩個引數對應的內容封裝為 seteye 和 setcenter 方法,setcenter 方法與 seteye 方法類似,這裡不重複贅述:

// 設定眼睛位置

var seteye = function(eye, finish) , //動畫結束後呼叫的函式 action: function(v, t) }); };

雙擊事件倒是簡單,只要監聽 ht 封裝好的事件,判斷事件型別,並作出相應的動作即可:

g3d.mi(function(e) 

}if (!p3) return; setcenter(p3); //設定 center 目標的要移向位置為 cabinet 的位置 seteye([p3[0], 211, p3[2] + 247]); //設定 eye 眼睛要移向的位置 });

一開始看到這個例子的時候我在想,這人好厲害,我用 ht 這麼久,用 ht 的 ht.widget.******* 還沒能做出這麼漂亮的效果,看著看著發現這原來是用 form 表單做的,厲害厲害,我真是太愚鈍了。

var form = e.top = new ht.widget.formpane(); //頂部 表單元件

form.setrowheight(e.topheight);//設定行高

form.setvgap(-e.topheight);//設定表單元件水平間距 設定為行高的負值則可以使多行處於同一行

form.setvpadding(0);//設定表單頂部和頂部與元件內容的間距

form.addrow([null,

}], [40, 260]);//第二個引數為每個元素寬度資訊陣列,寬度值大於1代表固定絕對值,小於等於1代表相對值,也可為80+0.3的組合

form.addrow([null, null,

}, , null, } }, null, } }, null], [40, 42, 218, 300, 0.1, 50, 10, 50, 10]);

以上都只是能實現,但是並沒有真正地新增進 html 標籤中,也就意味著,現在介面上什麼都沒有!別忘了在頁面載入的時候將 3d 場景新增進 body 中,同時也別忘了將 form 表單新增進 body 中,並且設定視窗大小變化事件時,form 表單也需要實時更新:

window.addeventlistener('load', function() );

});

這裡說明一下 addtodom 函式,對於了解 ht 的機制非常重要。ht 的元件一般都會嵌入 borderpane、splitview 和 tabview 等容器中使用,而最外層的 ht 元件則需要使用者手工將 getview() 返回的底層 div 元素新增到頁面的 dom 元素中,這裡需要注意的是,當父容器大小變化時,如果父容器是 borderpane 和 splitview 等這些 ht 預定義的容器元件,則 ht 的容器會自動遞迴呼叫孩子元件invalidate 函式通知更新。但如果父容器是原生的 html 元素, 則 ht 元件無法獲知需要更新,因此最外層的 ht 元件一般需要監聽 window 的視窗大小變化事件,呼叫最外層元件 invalidate 函式進行更新。

為了最外層元件載入填充滿視窗的方便性,ht 的所有元件都有 addtodom 函式,其實現邏輯如下,其中 iv 是 invalidate 的簡寫:

addtodom = function(), false); //視窗大小變化監聽事件,通知元件變化更新 }
這樣,所有的**就結束了,可以自己右鍵「檢查」,network 中可以獲取相對應的 json 檔案。

基於 HTML5 WebGL 的 3D 機房

用 webgl 渲染的 3d 機房現在也不是什麼新鮮事兒了,這篇文章的主要目的是說明一下,3d 機房中的 eye 和 center 的問題,剛好在專案中用上了,好生思考了一番,最終覺得這個例子最符合我的要求,就拿來作為記錄。這個 3d 機房的 demo 做的還不錯,比較美觀,基礎的互動也都滿足,接下...

基於 HTML5 WebGL 的醫療物流系統

物聯網 iot 簡單的理解就是物體之間通過網際網路進行鏈結。世界上的萬事萬物,都可以通過資料的改變進行智慧型化管理。iot 的興起在醫療行業中具有拯救生命的潛在作用。不斷的收集使用者資訊並且實時的進行診斷,所以未來 iot 肯定在醫療行業的應用會呈覆蓋性。下面是我最近做的乙個醫療物流系統,用來觀察醫...

HTML5 WEBGL學習1 3D基礎知識

本系列學習資源來自 html5 與webgl程式設計 中國工信出版集團 人民郵電出版社 在計算機裡顯示3d圖形,就是說在平面裡顯示三維圖形。面對計算機在座標系沒有旋轉的情況下,z軸實際上垂直螢幕向裡的。另外,webgl的y軸正方向是由視窗的下方向上,而2d canvasapi 和 css 變化中的y...