前言

在数据量很大的 2D 场景下,要找到具体的模型比较困难,并且只能显示出模型的的某一部分,显示也不够直观,这种时候能快速搭建出 3D 场景就有很大需求了。但是搭建 3D 应用场景又依赖于通过 3ds Max 或 Maya 的专业 3D 设计师来建模,Unity 3D 引擎做图形渲染等,这对用户来说都是挑战!不过,HT 一站式的提供了从建模到渲染,包括和 2D 组件呈现和数据融合的一站式解决方案。HT 基于 WebGL 的 3D 技术的图形组件 ht.graph3dView 组件通过对 WebGL 底层技术的封装,与 HT 其他组件一样, 基于 HT 统一的 DataModel 数据模型来驱动图形显示,极大降低了 3D 图形技术开发的门槛,在熟悉HT 数据模型基础上,一般程序员只需要 1 小时的学习即可上手 3D 图形开发。

好了,废话不多说,先附上 Demo:http://www.hightopo.com/demo/blog_3dedge_20170630/index.html

当然,这里的我只是用简单的图形来表示设备,脑洞大开的你当然可以将其换成更有意思的模型。

3D 场景的搭建

1、准备工作:

3D 和 2D 的 API 的设计上保持了很多一致性,3D 视图组件是 ht.graph3d.Graph3dView, 2D 视图组件是 ht.graph.GraphView,两者可共享同一数据模型 DataModel。在 HT 中,为了让了获得接近真实三维物体的视觉效果,我们通过透视投影使得远的对象变小,近的对象变大,平行线会出现先交等更接近人眼观察的视觉效果:

如上图所示,透视投影最终显示到屏幕上的内容只有截头椎体部分的内容,因此 GraphView 提供了 eye,center,up,far,near, fovy 和 aspect 参数来控制截头椎体的具体范围,我们在实际运用中用到更多的是 eye 和 center:

  • getEye() | setEye([x, y, z]),决定眼睛(或 Camera)所在位置,默认值为 [0, 300, 1000];

  • getCenter() | setCenter([x, y, z]),决定目标中心点(或 Target)所在位置,默认值为 [0, 0, 0];

详情看 HT for Web 3D 手册。

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、创建设备:

服务器,Demo 中的服务器其实是通过 addStyleIcon 方式在服务器的位置添加图片,详情可看 HT for Web 入门手册:

//注册图片
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);

工作台,这里的工作台实际上是立体圆柱来表示的,HT 在 GraphView 的 2D 图形上,呈现各种图形是通过 style 的shape 属性决定,类似的 HT 在 3D 上提供了 shape3d属性,预定义了多种 3D 的形体,详情见 HT for Web 3D 手册。不过在这里我并没有用预定义的图形,而是通过 ht.Default.createRingModel 的方式创建圆柱,该方法可以根据 xy 平面的曲线,环绕一周形成 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);

平台上的设备,我们一共创建了 32 个设备:

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);
}

为了让创建的设备在平台上的布局更加合理,根据 index 计算出设备摆放角度,并且根据圆柱中心,圆盘半径和角度计算出每个设备摆放的位置:

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;
}

其他设备,

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 提供了默认的直线和多点的连线类型能满足大部分基本拓扑图形应用,但在这里我们需要根据实际需求绘制曲线,所以,需要用到自定义连线类型,详情看 HT for Web 连线类型手册:

用 ht.Default.setEdgeType(type, func, mutual) 函数可用于自定义新连线类型:

  • type:字符串类型的连线类型,对应 style 的 edge.type 属性;

  • func:函数类型,根据传入参数(edge,gap,graphView,sameSourceWithFirstEdge)返回连线走向信息

1、edge:当前连线对象;

2、gap:多条连线成捆时,本连线对象对应中心连线的间距;

3、graphView:当前对应拓扑组件对象;

4、 sameSourceWithFirstEdge:boolean 类型,改连线是否与同组的第一条同源;

5、返回值为 {points: new ht.List(…),segments:new ht.List(…)} 结构的连线走向信息,segments 可取值如下:

1)、moveTo,占用 1 个点信息;

2)、lineTo,占用 1 个点信息;

3)、quadraticCurveTo,占用 2 个点信息;

4)、bezierCurveTo,占用 3 个点信息;

5)、closePath,不占用点信息;

  • mutual:该参数决定连线是否影响起始或结束节点上的所有连线,默认为 false 代表只影响同 source 和 target 的 EdgeGroup 中的连线,HT 预定义的连线类型中,后缀为 2 的类型都是 mutural 为 true 的复杂连线类型。

在 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])};
});

连线类型定义好,接下来就是创建连线,但是连线上还有流动效果,这个又怎么实现呢?我们 HT 有扩展流动线插件,可以在 ht.Shape 和 ht.Edge 上增加流动效果,支持内部流动元素或用户自定义的流动元素沿着路径步进,要使用也非常方便,只需要引入 ht-flow.js 文件,详情可见 HT for Web 流动线手册,但是插件并不适用于 3D 模型中,那在 3D 模型中该怎么办呢?即使不能使用现成的插件,我们也可以实现流动效果,可以看 HT for Web 入门手册 中连线部分,我们可以将连线样式通过 edge.dash 设置为虚线后,动态改变 edge.dash.offset 虚线偏移,即可实现流动效果,所以,我们创建连线时:

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;
}

最后,要让虚线流动起来,可以使用 HT 中的调度,详情可看 HT for Web 调度手册:

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 中的主要技术点都已经介绍了一遍,可以看出我们 HT 的强大之处,当然我们官网上还有很多很有意思的效果,大家也可以看一看,也可以玩一玩我们的 HT 感受它的强大之处,再次附上 Demo 地址: http://www.hightopo.com/demo/blog_3dedge_20170630/index.html。

基于 HTML5 WebGL 的 3D 网络拓扑图相关推荐

  1. c#web页面显示弹窗_基于 HTML5 WebGL 的 3D 风机 Web 组态工业互联网应用

    前言 在目前大数据时代背景之下,数据可视化的需求也变得越来越庞大,在数据可视化的背景之下,通过智能机器间的链接并最终将人机链接,结合软件和大数据分析的工业互联网也将变得越来越容易实现! 国家也敏锐意识 ...

  2. html5 光影效果,基于 HTML5 WebGL 的 3D 场景中的灯光效果

    原标题:基于 HTML5 WebGL 的 3D 场景中的灯光效果 构建 3D 的场景除了创建模型,对模型设置颜色和贴图外,还需要有灯光的效果才能更逼真的反映真实世界的场景.这个例子我觉得既美观又代表性 ...

  3. 基于 HTML5 WebGL 的 3D 服务器与客户端的通信

    这个例子的初衷是模拟服务器与客户端的通信,我把整个需求简化变成了今天的这个例子.3D 机房方面的模拟一般都是需要鹰眼来辅助的,这样找产品以及整个空间的概括会比较明确,在这个例子中我也加了,这篇文章就算 ...

  4. 基于 HTML5 WebGL 的 3D 智慧隧道漫游巡检

    前言 这次为大家展示的是通过 HT for Web 灵活的图型化编辑工具打造的智慧隧道监控系统.通过 HTML5 技术实现了桌面和移动端的跨平台性,同时现实了可视化运维. 这次主要跟大家分享里面的漫游 ...

  5. 基于 HTML5 WebGL 的 3D 棉花加工监控系统

    前言 现在的棉花加工行业还停留在传统的反应式维护模式当中,当棉花加下厂的设备突然出现故障时,控制程序需要更换.这种情况下,首先需要客户向设备生产厂家请求派出技术人员进行维护,然后生产厂家才能根据情况再 ...

  6. 基于 HTML5 WebGL 的 3D 机房

    前言 用 WebGL 渲染的 3D 机房现在也不是什么新鲜事儿了,这篇文章的主要目的是说明一下,3D 机房中的 eye 和 center 的问题,刚好在项目中用上了,好生思考了一番,最终觉得这个例子最 ...

  7. 基于 HTML5 WebGL 的 3D 工控裙房系统

    前言 工业物联网在中国的发展如火如荼,网络基础设施建设,以及工业升级的迫切需要都为工业物联网发展提供了很大的机遇.中国工业物联网企业目前呈现两种发展形式并存状况:一方面是大型通讯.IT企业的布局:一方 ...

  8. 基于HTML5 WebGL实现3D飞机叶轮旋转

    在上一篇<基于HT for Web矢量实现2D叶轮旋转>中讲述了叶轮旋转在2D拓扑上的应用,今天我们就来讲讲叶轮旋转在3D上的应用. 在3D拓扑上可以创建各种各样的图元,在HT for W ...

  9. 基于 HTML5 WebGL 的 3D 仓储管理系统

    仓储管理系统(WMS)是一个实时的计算机软件系统,它能够按照运作的业务规则和运算法则,对信息.资源.行为.存货和分销运作进行更完美地管理,使其最大化满足有效产出和精确性的要求.从财务软件.进销存软件C ...

  10. 基于 HTML5 WebGL 的 3D 渲染引擎构建工厂运作系统

    前言 今天为大家带来一个很酷的作品,依然运用了强大的 HT for Web 的 3D 图形组件,动作流畅性能好,大家可以先来欣赏一下效果! 点我进入! 整体风格为科技金属风,制作精良,由于上传 gif ...

最新文章

  1. STM8单片机定时器驱动的深度解析
  2. Leetcode刷题第1题:两数之和(基于Java语言)
  3. PHP文件上传,下载,Sql工具类!
  4. linux定时备份mysql数据库文件脚本
  5. Spring Boot 最佳实践(四)模板引擎Thymeleaf集成
  6. c语言1 2 10000,C语言1~10000之间所有水仙花数
  7. java中的特殊字符集合
  8. C语言中全局变量存放在哪个位置?
  9. 面试题之SpringMVC整体工作流程
  10. NCBI数据库以及常用编号
  11. Django 国际化翻译中的 gettext 和 gettext_lazy
  12. “安全删除硬件”图标 隐藏
  13. 防风雨密封胶的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  14. 百度地图API申请——服务端
  15. 2020总结及2021展望
  16. 阻击黑客,你需要了解这些云安全“潜规则”
  17. Generative Time Series Forecasting with Diffusion, Denoise, and Disentanglement
  18. [ISSUE]angularjs resolve: $injector:unpr] Unknown provider:
  19. 大数据的流处理和批处理及其框架
  20. 获取周一到周日的日期

热门文章

  1. 抖音实战~搜索页面~扫描二维码
  2. ios 表情符号 键盘_iOS自定义的emoji表情键盘
  3. 动态规划—1.2 买卖股票的最佳时机
  4. 白杨SEO:企业口碑问答营销如何做?渠道选择、推广流程及注意事项
  5. MOSS系列之三列表和文档库[转帖]
  6. css动画怎么暂停,纯CSS代码实现动画的暂停与播放
  7. EBS常用查询语句_查询银行账户
  8. 升级mysql后zpanel无法进入_升级到mysql5.7无法启动问题解决
  9. Grafana dashboard 定时报表(Grafana-reporter)
  10. 网页验证码识别实例VB.NET2019(二)