您好,登錄后才能下訂單哦!
小編給大家分享一下HTML如何實現3D隧道,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!
目前,物資采購和人力成本是隧道業發展的兩大瓶頸。比如依靠民間借貸,融資成本很高;采購價格不透明,沒有增值稅發票;還有項目管控和供應鏈管理的問題。成本在不斷上升,利潤在不斷下降,隧道產業的“互聯網+”迫在眉睫。隧道業的機械化程度高,機械制造和采購成本非常大,此外,隧道業的發展還面臨建筑市場的嚴峻考驗。“互聯網+”提供大數據、信息流,為傳統隧道企業由機械化向數字化挺進提供了機遇,隧道產業的建設工程需要持續的技術支持,也需要經驗分享,如果可以借助互聯網整理和分享相關經驗,將為隧道產業發展帶來智慧動力。
通過視頻監控圖像與語音錄像系統,就能隨時掌握各工點的施工情況,及時解決施工遇到的問題,從而提高管理效率;在比較特殊的地段,比如大山溝里,點多線長,交通不便,施工組織管理難度大,在傳統的施工過程中,基本靠人來回穿梭于各工點之間或電話溝通,檢查、監督施工,往往需要很多人參與管理,但仍然管不好,經常出現信息不對稱,管理不到位等問題,基于“互聯網+”的視頻監控圖像與語音錄像系統應運而生。
首先創建 3D 場景,HT(http://hightopo.com) 有 3D 組件,可以直接通過 new ht.graph4d.Graph4dView 3D 組件(https://hightopo.com/guide/gu...)來創建一個實例,然后通過 getView() 函數獲取組件的底層 p,既然是 p,那位置顯示控制就容易得多了:
dm = new ht.DataModel();// 數據容器,可以將顯示在界面上的所有數據通過 dataModel.add 存儲在數據容器中 g3d = new ht.graph4d.Graph4dView(dm);// 3D 組件 g3d.addToDOM();// 將 3D 組件的底層 p 添加到 body 中
HT 的組件一般都會嵌入 BorderPane、SplitView 和 TabView 等容器中使用,而最外層的 HT 組件則需要用戶手工將 getView() 返回的底層 p元素添加到頁面的 DOM 元素中,這里需要注意的是,當父容器大小變化時,如果父容器是 BorderPane 和 SplitView 等這些HT預定義的容器組件,則HT的容器會自動遞歸調用孩子組件 invalidate 函數通知更新。但如果父容器是原生的 html 元素, 則HT組件無法獲知需要更新,因此最外層的 HT 組件一般需要監聽 window 的窗口大小變化事件,調用最外層組件 invalidate 函數進行更新。
為了最外層組件加載填充滿窗口的方便性,HT 的所有組件都有 addToDOM 函數,其實現邏輯如下,其中 iv 是 invalidate 的簡寫:
addToDOM = function(){ var self = this, view = self.getView(),// 獲取組件的底層 p style = view.style; document.body.appendChild(view);// 將組件的底層 p 添加進 body 中 style.left = '0';// HT 組件默認設置 position 樣式屬性為 absolute 絕對定位方式 style.right = '0'; style.top = '0'; style.bottom = '0'; window.addEventListener('resize', function () { self.iv(); }, false); }
最讓我開心的應該是我的開發基本上跟設計部分完全分離了,因為 HT 可以通過 ht.Default.xhrLoad 函數直接加載 json 文件的場景,這樣我跟設計師就是雙進程了,非常開心呢~加載場景有三個步驟,如下:
ht.Default.xhrLoad('scenes/隧道.json', function(text){// 加載 json 場景 var json = ht.Default.parse(text);// 轉義 json 文件 dm.deserialize(json);// 將 json 內容反序列化到場景中 // 可以在這個里面任意操作 datamodel 數據容器中的數據了 }
我在場景中添加了一些功能,包括前面提到過的一些動畫操作,HT 封裝好的 dataModel.addScheduleTask(task) 通過操作數據容器 dataModel 來控制加載動畫(https://hightopo.com/guide/gu...),動畫部分在參數 task 中聲明,task 為 json 對象,可指定如下屬性:
interval:間隔毫秒數,默認值為 10
enabled:是否啟用開關,默認為 true
action:間隔動作函數,該函數必須設置
我的動畫一共三個,兩個隧道中各有一個風扇、一個風向儀以及一個卷閘門。設置這三個圖元變化即可,我在 json 中分別將這三個圖元的 tag 設置為 feng、feng2 以及 door,在代碼中我就可以直接調用這三個圖元的 tag 屬性:
var task = { action: function(data){ if(!data.getTag()) return; var tag = data.getTag();// 獲取圖元的 tag 屬性 if(tag === 'feng'){ data.r3(0, (data.r3()[1]+Math.PI/12), 0);// r3 為 3d 中的旋轉,這里 y 軸在原來的基礎上再旋轉 Math.PI/12 角度 }else if(tag === 'feng2'){ data.r3(0, 0, data.r3()[2]+Math.PI/12); }else if(tag === 'door'){ if(data.getTall() > 0){// 獲取圖元的 tall 屬性,高度 data.setTall(data.getTall()-20);// 設置高度為當前高度減去20 } } } } dm.addScheduleTask(task);// 在數據容器 dataModel 中添加調度任務
接著是創建 form 表單,在表單上添加一些信息,比如交通燈的切換等等,場景默認顯示的右上角的 form 表單我們這里不做解釋,內容跟點擊交通燈出現的 form 表單差不多,所以我們主要說明一下點擊交通燈時出現的表單:
表單中重復的部分比較多,我挑出三個部分來解釋一下:文本部分、“當前狀態”顯示的圖標以及下面“修改狀態”中的圖標點擊選擇部分:
form.addRow([// addRow 添加一行 我這個部分是添加一個標題 { element: '交通燈控制',// 這一行第一部分的顯示文本 align: 'center',// 文本對齊方式 color: 'rgb(0,210,187)',// 文本顏色 font: 'bold 16px arial, sans-serif'// 文本字體 } ], [0.1]);// 記得要設置這行的寬度 form.addRow([ // 這行中有兩個部分,一個“設備描述”,一個 文本“0”,所以要設置兩個寬度,寬度要放在一個數組中 '設備描述:',// 第一部分 {// 第二部分 element: '0', color: 'rgb(0,210,187)' } ],[80, 0.1], 34);// addRow 函數第二個參數為寬度設置,將上面內容的寬度依次放進這個數組中。第三個參數為高度 form.addRow([ '當前狀態:', {// 也可以將數組中的某個部分設置為空字符串,占據一些寬度,這樣比例比較好調 element: '' }, { id: '105',// id唯一標示屬性,可通過formPane.getItemById(id)獲取添加到對應的item對象 button: {/ /按鈕,設置了該屬性后HT將根據屬性值自動構建ht.widget.Button對象,并保存在element屬性上 icon: 'symbols/隧道用圖標/light.json',// 按鈕上的顯示圖標 background: 'rgba(0,7,26,0.60)',// 按鈕背景 borderColor: 'rgb(0, 7, 26)',// 按鈕邊框顏色 clickable: false// 是否可點擊 } } ],[80, 0.1, 84], 30); form.addRow([// 如果和上面一行的距離差別與其它行間距不同,可以通過增加一行空行,設置高度即可 '', { element: '' } ], [200, 0.1], 10); form.addRow([ '修改狀態:', { element: '' }, { button: { icon: 'symbols/隧道用圖標/light.json',// 設置按鈕的圖標 background: 'rgba(0,7,26,0.60)', borderColor: 'rgb(0, 7, 26)', groupId: 'btn',// 通過getGroupId和setGroupId獲取和設置組編號,屬于同組的togglable按鈕具有互斥功能。后面的三個按鈕也是設置了同一個 groupId onClicked: function(e){// 點擊后的回調函數 btnClick('light'); } } } ],[80, 0.1, 84], 30);
這個 form 表單的背景只是設置了一張圖片而已:
background: url('assets/控制.png') no-repeat;
上面還有一個部分沒有提及,就是點擊按鈕后調用的 btnClick 函數:
function btnClick(imageName){ if(flag === 1){// 做的判斷是根據3d的事件來處理的,等下會提 dm.getDataByTag('light').s({// 通過getDataByTag獲取節點,設置節點的style樣式 'back.image': 'symbols/隧道用圖標/'+imageName+'.json',// 設置圖元的背面圖片 'front.image': 'symbols/隧道用圖標/'+imageName+'.json'// 設置圖元你的前面圖片 }); }else if(flag === 2){ dm.getDataByTag('light1').s({ 'back.image': 'symbols/隧道用圖標/'+imageName+'.json', 'front.image': 'symbols/隧道用圖標/'+imageName+'.json' }); }else{} form.getViewById(105).setIcon('symbols/隧道用圖標/'+imageName+'.json');// 設置id為105的item內容顯示的圖標為form表單上點擊的交通燈的按鈕的圖標 }
最后就是點擊事件了,點擊交通燈會直接切換交通燈的顏色(實際上是切換模型的貼圖):
g3d.mi(function(e){// addInteractorListener 函數 監聽場景中的事件 if(e.kind === 'clickData') { if (e.data.getTag() === 'jam') { createDialog(e.data); } else if (e.data.getTag() === 'light') {// 如果圖元是背面的隧道的燈 var frontImage = e.data.s('front.image'); var imageName = frontImage.slice(frontImage.lastIndexOf('/')+1, frontImage.lastIndexOf('.')); btnClick('light', imageName); } else if (e.data.getTag() === 'light1'){// 正面的隧道的燈 var frontImage = e.data.s('front.image'); var imageName = frontImage.slice(frontImage.lastIndexOf('/')+1, frontImage.lastIndexOf('.')); btnClick('light1', imageName); } } });
互聯網+的概念在新興產業上能夠很好地運營,同時在傳統行業中利用得當同樣能夠產生非常大的效益,比如智慧城市建設,智慧能源管理,智慧工廠,甚至是地鐵監管等等都可以結合互聯網+的模式來運作,在一定程度上節省了非常多的人力和時間成本。
看完了這篇文章,相信你對HTML如何實現3D隧道有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。