得益於 HTML5 WebGL 技術的成熟,從技術上對工控管理的可視化,數據可視化變得簡單易行!完成對工控設備的管理效率,資源管理,風險管理等的大幅度提高,同時也對國家工業4.0計劃作出有力響應! 如本案例所示,是一個基於 HTML5 WebGL 技術實現的計量站三維可視化監控系統,在本案例中,具... ...
得益於 HTML5 WebGL 技術的成熟,從技術上對工控管理的可視化,數據可視化變得簡單易行!完成對工控設備的管理效率,資源管理,風險管理等的大幅度提高,同時也對國家工業4.0計劃作出有力響應!
同樣的其中功能組件具有很高的復用性,所以也會非常方便的應用到其他場景中!
如下所示,便是本案例運行動態圖:
此項目鏈接:基於 HTML5 WebGL 的計量站三維可視化監控系統 Web 組態工控應用
(http://www.hightopo.com/demo/metering-station/)
在這個場景中主要有如下幾個功能:
1、點擊來回切換場景;
2、管線流動效果;
3、數據面板動態顯示;
確認功能需求後就可以開始實施實現,動手實現之前要先確認場景有哪些,如下所示主要有油田外景和內景。
內景:
技能儲備
實現功能
1、預設視角
gv.setFar(100000); gv.setEye([1247, 600, 1972]); gv.setCenter([0, 0, 0]);
2、視角限制
具體實現是通過 setEye 方法和 setCenter 方法控制場景的 eye 和 center 變數實現,放置到 gv.mp 函數內。
mp(listener, scope, ahead) 增加自身屬性變化事件監聽器
//限制eye gv.mp(function (e) { if (e.property === 'eye') { if (gv.getEye()[1] < 90) { gv.getEye()[1] = 90; } if (gv.getEye()[1] > 1500) { gv.getEye()[1] = 1500; } if (gv.getEye()[0] > 2400) { gv.getEye()[0] = 2400; } if (gv.getEye()[0] < -2400) { gv.getEye()[0] = -2400; } if (gv.getEye()[2] > 2500) { gv.getEye()[2] = 2500; }if (gv.getEye()[2] < -2400) { gv.getEye()[2] = -2400; } } })
3、點擊切換場景
首先在點擊時候有個拉近效果和周圍模型透明化效果,則是通過 flyTo 實現拉近效果和 setStyle 方法實現拉近後其他模型透明化。
具體代碼如下:
gv.mi(function (e) { if (e.kind === 'clickData') { for (var i = 1; i <= 2; i++) { if (e.data.getTag() === 'engineRoom' + i) { //點擊拉近場景 gv.flyTo(e.data, { animation: true, distance: 500 }); //選中模型實化 e.data.setStyle('shape3d.transparent', false); e.data.setStyle('shape3d.opacity', 1); //其他模型透明化 dm.each(data => { if (data.getTag() != 'engineRoom' + i) { data.setStyle('shape3d.transparent', true); data.setStyle('shape3d.opacity', 0.3); data.setStyle('all.transparent', true); data.setStyle('all.opacity', 0.5); } }) } } } })
實現效果如下:
然後在完成拉近場景和透明化其他模型後,開始搞場景切換效果。
gv.deserialize('scenes/油田.json', function (json, dm, gv, datas) { if (json.title) document.title = json.title; if (json.a['json.background']) { var bgJSON = json.a['json.background']; if (bgJSON.indexOf('displays') === 0) { var bgGv = new ht.graph.GraphView(); bgGv.deserialize(bgJSON); bgGv.addToDOM(); graphView.addToDOM(bgGv.getView()); } else if (bgJSON.indexOf('scenes') === 0) { var bgG3d = new ht.graph3d.Graph3dView(); bgG3d.deserialize(bgJSON); bgG3d.addToDOM(); graphView.addToDOM(bgG3d.getView()); } graphView.handleScroll = function () { }; } })
所以在前面要先加一行代碼:
dm.clear();
最終這部分完整代碼如下:
function jump(position3d) { var timer = setInterval(function () { clearInterval(timer) var distance = ht.Default.getDistance(gv.getEye(), position3d); if (distance <= 501) { var home = g2d.dm().getDataByTag('home'); home.s('2d.visible', true); var line = g2d.dm().getDataByTag('line'); line.s('2d.visible', true); dm.clear(); gv.deserialize('scenes/油田.json', function (json, dm, gv, datas) { if (json.title) document.title = json.title; if (json.a['json.background']) { var bgJSON = json.a['json.background']; if (bgJSON.indexOf('displays') === 0) { var bgGv = new ht.graph.GraphView(); bgGv.deserialize(bgJSON); bgGv.addToDOM(); graphView.addToDOM(bgGv.getView()); } else if (bgJSON.indexOf('scenes') === 0) { var bgG3d = new ht.graph3d.Graph3dView(); bgG3d.deserialize(bgJSON); bgG3d.addToDOM(); graphView.addToDOM(bgG3d.getView()); } graphView.handleScroll = function () { }; } }) } }, 500) }
我將它放置到 jump 函數內,然後將 jump 函數放到前面點擊事件中調用,讓代碼整體簡潔一些。
實現效果如下圖:
4、管線流動效果和動態數據面板
最後兩個功能實現非常簡單,我就放到一塊來說。
首先效果如下圖所示:
管線流動效果的實現核心就是控制 UV 貼圖偏移,所以通過動畫控制器 startAnim 控制 UV 貼圖偏移量就可以實現,在動畫結束時,在 finishFunc 內回調函數即可實現動畫迴圈。
pipelineAnim(0.1) function pipelineAnim(offset1) { var anim1 = ht.Default.startAnim({ duration: 2000, action: function () { offset1 += 0.015; var pipelines = gv.dm().getDataByTag('pipeline'); pipelines.setStyle('shape3d.uv.offset', [-offset1, 0]); }, finishFunc: function () { pipelineAnim(offset1); } }) }
數據面板則是通過定時器在固定間隔時間迴圈執行賦予隨機數即可,在這裡通過隨機數模擬真實數據,在實際當中是通過和後臺對接實現真實數據動態變化,代碼如下:
setInterval(function () { for (var i = 1; i <= 4; i++) { var panels = gv.dm().getDataByTag('panel' + i); for (var j = 1; j <= 3; j++) { if (panels.a('text' + j) != undefined) { var num = parseFloat(Math.random() * (100 - 10 + 1) + 10, 10).toFixed(2); var textJson = { "參數名": "出口溫度", "參數值": num, "參數單位": panels.a('text' + j)['參數單位'] }; panels.a('text' + j, textJson); } } } }, 1000)
結束語