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