摘要:基于的技術(shù)的圖形組件組件通過對(duì)底層技術(shù)的封裝,與其他組件一樣,基于統(tǒng)一的數(shù)據(jù)模型來驅(qū)動(dòng)圖形顯示,極大降低了圖形技術(shù)開發(fā)的門檻,在熟悉數(shù)據(jù)模型基礎(chǔ)上,一般程序員只需要小時(shí)的學(xué)習(xí)即可上手圖形開發(fā)。
在數(shù)據(jù)量很大的2D 場(chǎng)景下,要找到具體的模型比較困難,并且只能顯示出模型的的某一部分,顯示也不夠直觀,這種時(shí)候能快速搭建出 3D 場(chǎng)景就有很大需求了。但是搭建 3D 應(yīng)用場(chǎng)景又依賴于通過 3ds Max 或 Maya 的專業(yè) 3D 設(shè)計(jì)師來建模,Unity 3D 引擎做圖形渲染等,這對(duì)用戶來說都是挑戰(zhàn)!不過,HT 一站式的提供了從建模到渲染,包括和 2D 組件呈現(xiàn)和數(shù)據(jù)融合的一站式解決方案。HT 基于 WebGL 的 3D 技術(shù)的圖形組件 ht.graph3dView 組件通過對(duì) WebGL 底層技術(shù)的封裝,與 HT 其他組件一樣, 基于 HT 統(tǒng)一的 DataModel 數(shù)據(jù)模型來驅(qū)動(dòng)圖形顯示,極大降低了 3D 圖形技術(shù)開發(fā)的門檻,在熟悉HT 數(shù)據(jù)模型基礎(chǔ)上,一般程序員只需要 1 小時(shí)的學(xué)習(xí)即可上手 3D 圖形開發(fā)。
好了,廢話不多說,先附上 Demo:http://www.hightopo.com/demo/...
當(dāng)然,這里的我只是用簡(jiǎn)單的圖形來表示設(shè)備,腦洞大開的你當(dāng)然可以將其換成更有意思的模型。
接下來看看我們是怎么做到的:
1、準(zhǔn)備工作:
3D 和 2D 的 API 的設(shè)計(jì)上保持了很多一致性,3D 視圖組件是 ht.graph3d.Graph3dView, 2D 視圖組件是 ht.graph.GraphView,兩者可共享同一數(shù)據(jù)模型 DataModel。在 HT 中,為了讓了獲得接近真實(shí)三維物體的視覺效果,我們通過透視投影使得遠(yuǎn)的對(duì)象變小,近的對(duì)象變大,平行線會(huì)出現(xiàn)先交等更接近人眼觀察的視覺效果:
如上圖所示,透視投影最終顯示到屏幕上的內(nèi)容只有截頭椎體部分的內(nèi)容,因此 GraphView 提供了 eye,center,up,far,near, fovy 和 aspect 參數(shù)來控制截頭椎體的具體范圍,我們?cè)趯?shí)際運(yùn)用中用到更多的是 eye 和 center:
getEye() | setEye([x, y, z]),決定眼睛(或 Camera)所在位置,默認(rèn)值為 [0, 300, 1000]; getCenter() | setCenter([x, y, z]),決定目標(biāo)中心點(diǎn)(或 Target)所在位置,默認(rèn)值為 [0, 0, 0];
詳情看 HT for Web 3D 手冊(cè) 手冊(cè) (http://www.hightopo.com/guide...)。
dataModel = new ht.DataModel(); g3d = new ht.graph3d.Graph3dView(dataModel); g3d.setEye(1800, 800, 1000); g3d.setCenter(0, 100, 0); g3d.setDashDisabled(false); g3d.getView().style.background = "rgb(10, 20, 36)"; g3d.addToDOM();
2、創(chuàng)建設(shè)備:
服務(wù)器,Demo 中的服務(wù)器其實(shí)是通過 addStyleIcon 方式在服務(wù)器的位置添加圖片,詳情可看 HT for Web 入門手冊(cè)(http://www.hightopo.com/guide...):
//注冊(cè)圖片 ht.Default.setImage("server", "server.png"); var server = new ht.Node(); server.s3(0, 0, 0); server.p3(0, 60, 0); server.addStyleIcon("icon", { position: 0, width: 200, autorotate: true, transparent: true, height: 200, names: ["server"] }); dataModel.add(server);
工作臺(tái),這里的工作臺(tái)實(shí)際上是立體圓柱來表示的,HT 在 GraphView 的 2D 圖形上,呈現(xiàn)各種圖形是通過 style 的shape 屬性決定,類似的 HT 在 3D 上提供了 shape3d屬性,預(yù)定義了多種 3D 的形體,詳情見HT for Web 3D 手冊(cè)。不過在這里我并沒有用預(yù)定義的圖形,而是通過 ht.Default.createRingModel 的方式創(chuàng)建圓柱,該方法可以根據(jù) xy 平面的曲線,環(huán)繞一周形成 3D 模型,所以可以用來定義多種圓形 3D 模型。
var desktop = new ht.Node(); desktop.s({ "3d.selectable": false, "shape3d": ht.Default.createRingModel([ 0, 40, 450, 40, 450, 0, 0, 40 ], null, 20, false, false, 50), "shape3d.color": "#003333" }); desktop.s3(1, 1, 1); dataModel.add(desktop);
平臺(tái)上的設(shè)備,我們一共創(chuàng)建了 32 個(gè)設(shè)備:
var count = 32; radius = 400; index = count/2; for (var i = 1; i <= count/2; i++) { var device1_angle1 = Math.PI * 2 * (index - i) / count; device1_angle2 = Math.PI * 2 * (index + i) / count; device1_angle3 = Math.PI * 2 * index / count; var device1_1 = createDevice(device1_angle1, radius, 60); device1_2 = createDevice(device1_angle2, radius, 60); device1_3 = createDevice(device1_angle3, radius, 60); layoutDevice1(device1_1, device1_angle1); var device1_edge1 = createEdge(device1_1, server, "line1"); device1_edge1.s({"shape3d.color": "rgb(205, 211, 34)"}); dataModel.add(device1_1); dataModel.add(device1_edge1); layoutDevice1(device1_2, device1_angle2); var device1_edge2 = createEdge(device1_2, server, "line1"); device1_edge2.s({"shape3d.color": "rgb(205, 211, 34)"}); dataModel.add(device1_2); dataModel.add(device1_edge2); layoutDevice1(device1_3, device1_angle3); var device1_edge3 = createEdge(device1_3, server, "line1"); device1_edge3.s({"shape3d.color": "rgb(205, 211, 34)"}); dataModel.add(device1_3); dataModel.add(device1_edge3); }
為了讓創(chuàng)建的設(shè)備在平臺(tái)上的布局更加合理,根據(jù) index 計(jì)算出設(shè)備擺放角度,并且根據(jù)圓柱中心,圓盤半徑和角度計(jì)算出每個(gè)設(shè)備擺放的位置:
function createDevice (angle, x, y) { var node = new ht.Node(); cos = Math.cos(angle); sin = Math.sin(angle); node.p3(x*sin, y, x*cos); return node; }
其他設(shè)備,
var num = 18; var h = [800, 900, 1000, 1100, 1200]; var v = [40, 60, 80, 100]; var colors = ["#fcfc63", "#00E1E4"]; for (var j = 0; j < num; j++) { var device2_angle = Math.PI * j / num; var device2 = createDevice(device2_angle, h[Math.floor(Math.random()*5)], v[Math.floor(Math.random()*4)]); device2.s3(100, 20, 100); device2.s({ "shape3d": "cylinder", "shape3d.color": colors[Math.floor(Math.random()*2)] }); var device2_edge = createEdge(device2, desktop , "line2"); device2_edge.s({"shape3d.color": "rgb(0, 203, 94)"}); dataModel.add(device2); dataModel.add(device2_edge); }
3、連線
HT for Web 提供了默認(rèn)的直線和多點(diǎn)的連線類型能滿足大部分基本拓?fù)鋱D形應(yīng)用,但在這里我們需要根據(jù)實(shí)際需求繪制曲線,所以,需要用到自定義連線類型,詳情看HT for Web 連線類型手冊(cè):
用 ht.Default.setEdgeType(type, func, mutual) 函數(shù)可用于自定義新連線類型:
type:字符串類型的連線類型,對(duì)應(yīng) style 的 edge.type 屬性;
func:函數(shù)類型,根據(jù)傳入?yún)?shù)(edge,gap,graphView,sameSourceWithFirstEdge)返回連線走向信息:
edge:當(dāng)前連線對(duì)象;
gap:多條連線成捆時(shí),本連線對(duì)象對(duì)應(yīng)中心連線的間距;
graphView:當(dāng)前對(duì)應(yīng)拓?fù)浣M件對(duì)象;
sameSourceWithFirstEdge:boolean 類型,改連線是否與同組的第一條同源;
返回值為 {points: new ht.List(...),segments:new ht.List(...)} 結(jié)構(gòu)的連線走向信息,segments 可取值如下:
1、moveTo,占用 1 個(gè)點(diǎn)信息; 2、lineTo,占用 1 個(gè)點(diǎn)信息; 3、quadraticCurveTo,占用 2 個(gè)點(diǎn)信息; 4、bezierCurveTo,占用 3 個(gè)點(diǎn)信息; 5、closePath,不占用點(diǎn)信息;
mutual:該參數(shù)決定連線是否影響起始或結(jié)束節(jié)點(diǎn)上的所有連線,默認(rèn)為 false 代表只影響同 source 和 target 的 EdgeGroup 中的連線,HT 預(yù)定義的連線類型中,后綴為 2 的類型都是 mutural 為 true 的復(fù)雜連線類型。
在 Demo 中定義了兩種類型的連線,分別為 line1 和 line :
ht.Default.setEdgeType("line1", function(edge){ var sourcePoint1 = edge.getSourceAgent().getPosition(), targetPoint1 = edge.getTargetAgent().getPosition(), points1 = new ht.List(); points1.add(sourcePoint1); points1.add({ x: (sourcePoint1.x + targetPoint1.x)/2 + 200, e: sourcePoint1.e, y: (sourcePoint1.y + targetPoint1.y)/2 }); points1.add(targetPoint1); return { points: points1, segments: new ht.List([1, 3]) }; }); ht.Default.setEdgeType("line2", function(edge){ var sourcePoint = edge.getSourceAgent().getPosition(), targetPoint = edge.getTargetAgent().getPosition(), points = new ht.List(); points.add(sourcePoint); points.add({ x: (sourcePoint.x + targetPoint.x)/2, e: ((sourcePoint.e + targetPoint.e)/2 || 0) - 300, y: (sourcePoint.y + targetPoint.y)/2 }); points.add({ x: targetPoint.x, e: targetPoint.e -80, y: targetPoint.y }); return { points: points, segments: new ht.List([1, 3]) }; });
連線類型定義好,接下來就是創(chuàng)建連線,但是連線上還有流動(dòng)效果,這個(gè)又怎么實(shí)現(xiàn)呢?我們 HT 有擴(kuò)展流動(dòng)線插件,可以在 ht.Shape 和 ht.Edge 上增加流動(dòng)效果,支持內(nèi)部流動(dòng)元素或用戶自定義的流動(dòng)元素沿著路徑步進(jìn),要使用也非常方便,只需要引入 ht-flow.js 文件,詳情可見 HT for Web流動(dòng)線手冊(cè)(http://www.hightopo.com/guide...),但是插件并不適用于 3D 模型中,那在 3D 模型中該怎么辦呢?即使不能使用現(xiàn)成的插件,我們也可以實(shí)現(xiàn)流動(dòng)效果,可以看HT for Web 入門手冊(cè) 中連線部分,我們可以將連線樣式通過 edge.dash 設(shè)置為虛線后,動(dòng)態(tài)改變 edge.dash.offset 虛線偏移,即可實(shí)現(xiàn)流動(dòng)效果,所以,我們創(chuàng)建連線時(shí):
function createEdge (source, target , type) { var edge = new ht.Edge(source, target); edge.s({ "edge.color": "yellow", "edge.dash": true, "edge.dash.3d": true, "edge.dash.width": 4, "edge.type": type, "edge.dash.color": "rgb(10, 20, 36)", "edge.dash.pattern": [20, 25] }); edge.a({ "flow.enabled": true, "flow.direction": -1, "flow.step": 4 }); return edge; }
最后,要讓虛線流動(dòng)起來,可以使用 HT 中的調(diào)度,詳情可看HT for Web 調(diào)度手冊(cè)(http://www.hightopo.com/guide...):
flowTask = { interval: 50, action: function(data){ if(data.a("flow.enabled")){ var offset = data.s("edge.dash.offset") + data.a("flow.step") * data.a("flow.direction"); data.s("edge.dash.offset", offset); } } }; dataModel.addScheduleTask(flowTask);
到這里,Demo 中的主要技術(shù)點(diǎn)都已經(jīng)介紹了一遍,可以看出我們 HT 的強(qiáng)大之處,當(dāng)然我們官網(wǎng)上還有很多很有意思的效果,大家也可以看一看,也可以玩一玩我們的 HT 感受它的強(qiáng)大之處,再次附上 Demo 地址: http://www.hightopo.com/demo/...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83757.html
摘要:在文末,我會(huì)附上一個(gè)可加載的模型方便學(xué)習(xí)中文藝術(shù)字渲染用原生可以很容易地繪制文字,但是原生提供的文字效果美化功能十分有限。 showImg(https://segmentfault.com/img/bVWYnb?w=900&h=385); WebGL 可以說是 HTML5 技術(shù)生態(tài)鏈中最為令人振奮的標(biāo)準(zhǔn)之一,它把 Web 帶入了 3D 的時(shí)代。 初識(shí) WebGL 先通過幾個(gè)使用 Web...
閱讀 1323·2021-11-16 11:45
閱讀 2247·2021-11-02 14:40
閱讀 3888·2021-09-24 10:25
閱讀 3035·2019-08-30 12:45
閱讀 1267·2019-08-29 18:39
閱讀 2479·2019-08-29 12:32
閱讀 1617·2019-08-26 10:45
閱讀 1926·2019-08-23 17:01