Hightopo 公司 3D 可视化产品有对应的官方手册。但是这些手册内容比较多。对于想学习的新同学来说可能相对比较繁琐。这里本人根据个人使用经验做了一些总结。希望对读者有所帮助。
本文会提到一些前端开发的概念,如 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%的国产前端可视化引擎。经过10多年不断地迭代优化,其无论是在学习曲线,开发效率,还是渲染效果,运行性能方面都可圈可点。
该引擎的缺点是目前并不开源,需要商业授权才能使用。但是感兴趣的开发者可以从其官网申请免费的试用包。该试用包除了包括核心引擎文件,还包括使用手册及大量插件。试用包的有效期通常为3个月,但是到期后我们还可以继续申请,不影响后面的使用。下面是我的试用包里面包含的插件:
本章的主要内容是先帮大家把 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中
视图组件
视图组件是显示给用户,可用于交互的 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 的各个组件操作逻辑都有着非常重要的作用。