今天找到了 HT 的官網裏的 Demo 網站( http://www.hightopo.com/demos/index.html ),看的我眼花繚亂,應接不暇。 並且 HT 的用戶手冊,將例子和文檔無縫融合一體,小小 10 來兆開發包竟然包含了四十五份手冊,數百個活生生的 HTML5 例子,還沒體驗過的朋友趕忙來看一看,這回可玩嗨了!html
對於 HT 初學者,面對這一堆數百個涵括通用組件、網絡拓撲圖組件、3D 組件、矢量圖形、各類編輯器等等五法八門的 HTML5 例子盛宴,每每無從下手。爲此,老鄭我打算爲像我同樣喜歡這方面的新手朋友多寫幾篇這樣的博客,慢慢的給你們講述各類各樣的愈來愈多的有趣的小功能!node
( https://hightopo.com/demo/CabinetAnimat/ )網絡
HT 提供了基於 WebGL 的 3D 技術的圖形組件 ht.graph3d.Graph3dView,WebGL 基於 OpenGL ES 2.0 圖形接口,所以 WebGL 屬於底層的圖形 API 接口,二次開發仍是有很高的門檻,HT 的 Graph3dView 組件經過對 WebGL 底層技術的封裝,與 HT 其餘組件同樣,基於 HT 統一的 DataModel 數據模型來驅動圖形顯示,極大下降了 3D 圖形技術開發的門檻。同時 HT 提供了強大的徹底基於 HTML5 技術 3D 圖形建模設計器,用戶無需編碼便可快速可視化搭建各類 3D 場景,能夠說 HT 的 3D 開發模式徹底打破了傳統 3D 開發模式,絕大部分應用再也不須要依賴精通 3ds Max 或 Maya 的專業 3D 設計師來建模,也不須要整合 Unity3d 等引擎作圖形渲染,HT 一站式的提供了從建模到渲染,包括和 2D 組件呈現和數據融合的一站式解決方案。編輯器
我本次講解的就是這個 3D 的界面,因此咱們首先要建立 3D 渲染引擎組件,可視化呈現數據模型的三維環境場景。ide
var dm = new ht.DataModel() var g3d = new ht.graph3d.Graph3dView(dm)
咱們還要設置眼睛(或Camera)所在位置以及中心點(目標)的位置,格式均爲 [x, y, z] 。函數
g3d.setEye([-376, 270, 896])
g3d.setCenter([-16, 118, -186])
這裏給你們說一下,可參考 3D 手冊( http://www.hightopo.com/guide/guide/core/3d/ht-3d-guide.html )。如上圖所示,透視投影最終顯示到屏幕上的內容只有截頭錐體 ( View Frustum ) 部分的內容, 所以 Graph3dView 提供了 eye ,center , up ,far ,near ,fovy 和 aspect 參數來控制截頭錐體的具體範圍:oop
而後咱們再給它加上一些選中效果。Graph3dView 中被選中的圖元會顯示爲較暗的狀態,變暗係數是由圖元 style 的 brightness 和 select.brightness 屬性決定,select.brightness 屬性默認值爲 0.7,最終返回值大於 1 變亮,小於 1 變暗,等於 1 或爲空則不變化。Graph3dView#getBrightness 函數控制最終圖元亮度,所以也能夠經過重載覆蓋該函數自定義選中圖元亮度。學習
g3d.getBrightness = function (data) { if (data.s('isFocused')) { return 0.7; } return null; };
lastFocusData = null; g3d.getView().addEventListener('mousemove', function (e) { // 傳入邏輯座標點或者交互 event 事件參數,返回當前點下的圖元 var data = g3d.getDataAt(e); if (data !== lastFocusData) { if (lastFocusData) { astFocusData.s('isFocused', false); } if (data) { data.s('isFocused', true); } astFocusData = data; } });
接下來咱們要爲這些零件設置吸附:動畫
dm.getDataByTag('機櫃').setHost(dm.getDataByTag('地板')) dm.getDataByTag('設備').setHost(dm.getDataByTag('機櫃')) dm.getDataByTag('門').setHost(dm.getDataByTag('機櫃'))
...
吸附功能對於設計有層次關係的模型很是方便,例如設備面板吸附上設備機框,設備端口吸附上設備面板,這樣從機框 - 面板 - 端口的層次關係吸附,使得用戶拖動總體機框時全部這個層次下的圖元都會跟隨移動。對於 3D 的場景下,吸附的概念更進一步延伸,當機框在三維空間進行任意位置偏移以及任意角度旋轉時,全部吸附的相關圖元都會正確的跟隨平移,並作出相應位置對應的旋轉,以達到總體設備各個圖形部分保持物理相對位置一致。簡單來講就是當圖元吸附上宿主圖元時,宿主移動或旋轉時會帶動全部吸附者。網站
由於我這裏是有 6 個設備,我要把每個都給一個屬性值來記錄變化的狀態一下子用到:
dm.getDataByTag('門').a('open', false) for (var i = 1; i < 7; i++) { dm.getDataByTag('設備' + i).a('open', false) }
上一篇關於 SCADA 組態電機的隨筆裏面我們已經用到過動畫,這回讓咱們經過事件監聽在雙擊它的時候來爲其加上動畫效果:
// 監聽事件 g3d.mi(function (event) { if (event.kind === 'doubleClickData') { var tag = event.data.getTag() if (tag === '門') { if (anim) { anim.stop(true) } //獲取旋轉角度 var oldAngles = event.data.getRotation(), angles = (open ? 2 : -2) //啓動動畫 anim = ht.Default.startAnim({ action : function(t) { event.data.setRotation(oldAngles + t * angles) }, }) open = !open } //檢測字符串是否以指定的前綴開始 else if (tag.startsWith('設備')) { //設備動畫函數 animation(event.data) } }
}
設備動畫的函數在這裏:
function animation(data) { //設置每一個設備依次的變化參數 var v for (var i = 1; i < 7; i++) { if (tag === '設備'+ i) { v= i / 2 }
} if (data.anim) { data.anim.stop(true) data.anim = null } var open = data.a('open'), p3 = data.p3(), s3 = data.s3() if (open) { data.anim = ht.Default.startAnim({ action : function(t) { data.p3(p3[0], p3[1], p3[2] + t * -s3[2] * v) } }) data.a('open', false) } else { data.anim = ht.Default.startAnim({ action : function(t) { data.p3(p3[0], p3[1], p3[2] + t * s3[2] * v) } }) data.a('open', true) } }
這裏面有一些簡寫跟大夥兒說下。好比 mi 是增長交互事件監聽器,addInteractorListener 的縮寫,另外 event 格式有:
同時還有 3D 的一些:
建議熟記經常使用函數簡寫可提升編碼效率,可參考入門手冊中函數簡寫( http://www.hightopo.com/guide/guide/core/beginners/ht-beginners-guide.html )。最後別忘記 g3d.addToDOM() 呦!嘿嘿~~~
這個小 demo 就說到這裏吧,我會不按期的寫一些技術隨筆,既幫助本身整理知識,也可以跟你們一塊兒學習,咱們由淺至深,按部就班。但願看了個人文章能得大家帶來幫助,同時也但願你們能多多支持和鼓勵!