Hightopo 公司 3D 可视化产品有对应的官方手册。但是这些手册内容比较多。对于想学习的新同学来说可能相对比较繁琐。这里本人根据个人使用经验做了一些总结。希望对读者有所帮助。
官方手册地址:Structure (hightopo.com)
本文会提到一些前端开发的概念,如 H5, JavaScript,JSON 等。没有开发经验的读者还需要先补一下相关概念。再继续阅读。
HT for Web,通常简称为 HT,这是一个基于 JavaScript 开发的 WebGL 引擎。可用于 2D/3D 可视化开发,其核心文件只有一个,就是 ”ht.js”。在 index.html 中使用 script 标签进入后便可使用,该文件总共1M左右。
<body>
<script src="lib/core/ht.js"></script>
</body>
由于其可扩展性比较强,因此还提供了一系列插件。比如:矢量,动画,obj,右键菜单等。在开发的过程中可根据需要引入。
该引擎由国内 Hightopo 公司自主研发,是100%的国产前端可视化引擎。有可视化开发经验的同学可能知道一个前端开源 3D 引擎 Three.js。据了解, HT for Web 开发的时间比 Three.js 还要早。经过不断地迭代优化,其无论是在学习曲线,开发效率,还是渲染效果,运行性能方面都可圈可点。
其对 2D 和 3D的支持都非常好,并且 2D/3D 共用相同的数据容器和操作逻辑,具有更友好的API和简化的开发模式,因此非常便于学习使用。最值得称赞的一点是,它拥有强大的矢量绘图能力,可以几乎100%地将设计师的设计图用代码还原到网页。这也解释了为什么它官网能做出那么多精彩的案例。
官网案例地址:图扑软件 - 构建先进 2D 和 3D 可视化所需要的一切 (hightopo.com)
与使用 Three.js + H5 + echarts 等结构的可视化框架相比,HT for Web 在开发周期,开发成本,以及运行性能表现方面的表现要优秀不少。
该引擎的缺点是目前并不开源,需要商业授权才能使用。但是感兴趣的开发者可以从其官网申请免费的试用包。该试用包除了包括核心引擎文件,还包括使用手册及大量插件。试用包的有效期通常为3个月,但是到期后我们还可以继续申请,不影响后面的使用。下面是我的试用包里面包含的插件:
试用申请链接:图扑软件申请试用 (hightopo.com)
本章的主要内容是先帮大家把 HT for Web 里面的几个主要概念捋清楚一下。方便后续理解。
基础数据 - ht.Data
ht.Data简称 Data,是 HT for Web 中最基础的数据类型(或数据元素)。举个例子:比如一个表格有3行数据。那么每一行数据就可以用一个 Data 来表示。
在 Data 中我们可以存放和配置业务数据。如上面表格的第一行我们可以用一个 Data 来存放其行数据:
let row1 = new ht.Data(); // 新建空白的Data用以存放行数据
// 给Data(行数据)赋值。其中冒号前为key,后面为显示的值。
// 至于key如何与表格列数据绑定,这个会在后面table章节中叙述。
row1.a({
"empNo": "ht424",
"name": "唐尼",
"sex": "男",
"job": "CEO"
});
let table = new ht.ui.TableView(); // 创建表格
table.dm().add(row1); // 将新建的行数据添加到表格中。其中table.dm()为后面要讲的数据容器
上面代码中,row1.a() 是 row1.setAttr() 的简写形式。用于将自定义属性存放到该 Data 中。
在将 Data 存放到 Table 后,如果我们想知道当前 Table 总共有多少行,或者想对每一行的添加,删除,选中,取消选中等操作进行监听做进一步处理该怎么操作?此时就用到了数据模型与选择模型。
数据模型(容器) - ht.DataModel
ht.DataModel 简称 DataModel 或 dm。它是一个用来存放和管理 ht.Data 的容器。DataModel 也是HT for Web 中的一个最基本概念。HT 中的表格,列表,2D图纸,3D场景等都是用的 DataModel 来对里面的 Data 进行管理。因此只要理解了 ht.Data 与 ht.DataModel 的关系及它们的作用,再使用 HT 各种组件的时候就会的心用手。
DataModel 是一个容器,HT 的不同视图组件(如:表格,列表,2D图纸,3D场景等)都会使用DataModel 来对其下面的 Data 进行管理。只不过是在不同的视图组件上每个 Data 的表现形式不同而已。
每个视图组件都会有 getDataModel() 和 setDataModel() 方法,分别用来获取和设置其所用的 DataModel。比如:
let table = new ht.ui.TableView(); // 创建表格
const dm = table.getDataModel(); // 获取table所用的DataModel
// const dm = table.dm(); // 同上一句,都是获取table所用的DataModel
// 设置table的DataModel
const newDM = new ht.DataModel();
table.setDataModel(newDM); // 设置table的DataModel
// table.dm(newDM); // 同上一句,设置table的DataModel
为了书写代码方便,可以用 dm() 来代替 getDataModel() 和 setDataModel() 方法。如果里面不带参数,就是执行 getDataModel(),如果带参数就是执行 setDataModel() 方法。
选择模型 - ht.SelectionModel
以列表(List)为例,在交互的时候,使用者可能需要对列表中的某些行进行单选或多选操作。那么该如何处理这些操作?
这里就用到了 HT 的选择模型 ht.SelectionModel(简称 sm)。
ht.SelectionModel 管理 DataModel 模型中 Data 对象的选择状态,每个 DataModel 对象都内置一个 SelectionModel(选择模型),控制这个 SelectionModel 即可控制所有绑定该 DataModel 的组件的对象选择状态。
可以通过 dataModel.getSelectionModel() 或 listView.getSelectionModel() 来获取列表的选择模型 sm。获取选择模型后,可以使用 sm.getSelection() 和 sm.setSelection(datas) 来分别获取和设置 Data 的选中状态。如:
const sm = dataModel.getSelectionModel(); // 获取当前dataModel的选择模型
sm.setSelection(data); // 选中某个Data。假设该Data已经被创建并添加到的dataModel中
基础数据,数据模型,选择模型的详细手册都可以从下面链接找到:
数据模型手册 - HT for Web (hightopo.com)
视图组件
视图组件是显示给用户,可用于交互的HTML元素。例如我们之前提的表格,2D图纸,以及3D场景等。由于HT对原生HTML元素进行了封装,并且每个视图组件都绑定了DataModel和Data,因此,我们只需要通过JS代码来修改Data的属性便可以驱动视图组件的变化。这套逻辑在各个视图组件中使用起来基本一致,因此熟悉这种操作逻辑后,在开发过程中会非常方便。
以3D场景为例。下面代码会在body下添加一个3D场景,并且显示网格线。在添加完场景后,又新建了一个HT节点。
const g3d = new ht.graph3d.Graph3dView(); // 创建一个3D场景
g3d.setGridVisible(true); // 显示地面网格
g3d.addToDOM(); // 将3D场景添加到DOM
const dm = g3d.dm(); // 获取3D场景的DataModel
let node = new ht.Node(); // 新建一个HT节点,ht.Node由ht.Data扩展而来,其本质也是一个ht.Data
dm.add(node); // 添加该节点到3D场景中。
const p3 = node.getPosition3d(); // 默认位置:[0, 0, 0]
所谓HT节点(ht.Node)实际上是由ht.Data扩展出来的一个类。在ht.Node上,其拥有更丰富的属性定义。如:设置大小,缩放,旋转角度,位置,贴图等。在3D场景中,每个HT节点都可以用来表示一个3D模型,也可以用来代表一些其他的东西。比如这里我们没有为其配置属性,因此其默认显示一个六面体。
上面示例中我们创建了一个3D场景视图组件。每个3D场景会对应又一个DataModel。在获取该场景的DataModel后,我们接着又添加了一个ht.Node。由于没有指定位置,因此系统会将其放到默认位置 [0, 0, 0];
按照上面步骤,当我们创建了自己的3D场景并添加了许多模型进去后,我们会希望能把这个场景里面的所有数据保存下来便于下次继续使用。此时就用到了序列化与反序列化功能。
序列化与反序列化
序列化和反序列化是HT中的一个非常重要的概念。序列化可以让我们把DataModel中的数据转换成字符串,进而保存成文件。而反序列化可以帮助我们把文件还原成DataModel。由于DataModel对应到视图组件,这样便可以实现我们视图数据的保存与恢复。
在HT中,我们可以使用DataModel的serialize()和deserialize()方法来进行序列化和反序列化操作。在序列化后,DataModel数据将会被转换成JSON字符串。
const json = dm.serialize(); // 序列化
dm.deserialize(json); // 反序列化
如上例中的3D场景,我们对其序列化后得到的JSON字符串如下:
{
"v": "7.7.1",
"p": {
"autoAdjustIndex": true,
"hierarchicalRendering": false,
"postProcessingData": {
"huesaturation": {
"hue": [0, 0, 0, 0, 0, 0, 0],
"saturation": [0, 0, 0, 0, 0, 0, 0],
"lightness": [0, 0, 0, 0, 0, 0, 0]
},
"bloom": {},
"glitch": {}
}
},
"d": [{
"c": "ht.Node",
"i": 6
}]
}
这里的JSON数据格式是Hightopo自定义格式。为了节省空间,其每个属性都使用了简写形式。我们一般不需要对其进行修改。
总结
本章主要介绍了HT for Web中的一些基本概念,包括:基础数据ht.Data、数据模型ht.DataModel和选择模型ht.SelectionModel、视图组件以及序列化和反序列化。这些概念是HT for Web中最基础的概念,几乎在每次开发过程中都会用到。掌握它们的功能以及其互相之间的逻辑之后,对于后续的开发以及理解HT for Web的各个组件操作逻辑都有着非常重要的作用。