DEV Community

Cover image for [Learning Notes] Hightopo’s HT for Web (1) - Basic Conceptions
Lalo Salamanca
Lalo Salamanca

Posted on

[Learning Notes] Hightopo’s HT for Web (1) - Basic Conceptions

HT for Web, typically abbreviated as HT, is a WebGL engine developed using JavaScript. It can be used for 2D/3D visualization development. The engine consists of only one core file, "ht.js", which can be directly imported in the index.html using the script tag. The file size is approximately 1MB.

<body>
    <script src="lib/core/ht.js"></script>
</body>
Enter fullscreen mode Exit fullscreen mode

Due to its strong scalability, it also provides a series of plugins. For example: edges, animation, obj, right-click menu, etc. These can be imported as needed during development.

This engine is independently developed by Hightopo company. After more than 10 years of continuous iteration and optimization, it has excellent performance in terms of learning curve, development efficiency, rendering effect, and operational performance.

Hightopo official website demo cases

demos
One disadvantage of this engine is that it is not open source and requires a commercial license to use. However, interested developers can apply for a free trial package from its official website. This trial package includes not only the core engine files, but also user manuals and a large number of plugins. The trial period is usually three months, but we can continue to apply for it after it expires. The following are the plugins included in my trial package:

Apply for trial: https://www.hightopo.com/en-request.html

plugins
The main content of this chapter is to help everyone clarify the basic concepts in HT for Web, which will facilitate understanding in subsequent chapters.

Basic Data - ht.Data

ht.Data, also called Data for short, is the most basic data type (or data element) in HT for Web. For example, if a table has 3 rows, each row can be represented using one Data.

table
In Data, we can store and configure custom data. For example, in the first row of the table above, we can use a Data to store its row data:

let row1 = new `ht.Data`(); // Create a new `ht.Data` to storage row data

// Assign a value to `Data` (row data). 
// The "key" is before the colon, and the displayed value is after the colon.
// As for how the key is bound to the table column data, 
// this will be described in the table chapter later.
row1.a({
  "empNo": "ht424",
  "name": "Donnie",
  "sex": "Male",
  "job": "CEO"
});

let table = new ht.ui.TableView(); // create the table
table.dm().add(row1); // add the row data to the table. table.dm() is the DataModel
Enter fullscreen mode Exit fullscreen mode

In the above code, row1.a() is a shorthand for row.setAttr(). It is used to store custom attributes in the Data object.

After storing data in a Table, if we want to know the total number of rows in the current Table or want to listen to operations such as adding, deleting, selecting, and deselecting for each row and perform further processing, we need to use data models and selection models.

Data Model (Container) - ht.DataModel

ht.DataModel, also known as DataModel or dm, is a container used to store and manage ht.Data. DataModel is also a fundamental concept in HT for Web. Tables, lists, 2D displays, 3D scenes, and other components in HT all use DataModel to manage their data. Therefore, once you have a clear understanding of the relationship and roles of ht.Data and ht.DataModel, using various HT components will become much easier.

DataModel is a container that different view components of HT (such as tables, lists, 2D drawings, 3D scenes, etc.) will use to manage the Data underneath. The only difference is that each Data has a different representation in different view components.

Each view component has the getDataModel() and setDataModel() methods, which are used to get and set the DataModel used by the component. For example:

let table = new ht.ui.TableView(); // create the table
const dm = table.getDataModel(); // get the `DataModel` of the table
// const dm = table.dm(); // same as table.getDataModel()

// Set the `DataModel` of the table
const newDM = new ht.DataModel();
table.setDataModel(newDM); // set the `DataModel` of the table
// table.dm(newDM); // same as table.setDataModel(newDM)
Enter fullscreen mode Exit fullscreen mode

For the convenience of writing code, you can use dm() instead of getDataModel() and setDataModel() methods. If there are no parameters, it executes getDataModel(), and if there are parameters, it executes the setDataModel() method.

Selection Model - ht.SelectionModel

Using the List as an example, during interaction, users may need to select one or more rows in the list. How should these operations be handled?

list
Here we use HT's selection model ht.SelectionModel (referred to as sm).

ht.SelectionModel manages the selection state of Data objects in the DataModel. Each DataModel object has a built-in SelectionModel. Controlling this SelectionModel you’ll controls the selection state of all objects bound to the DataModel.

You can obtain the selection model 'sm' of a list by using either dataModel.getSelectionModel() or listView.getSelectionModel(). Once you have obtained the selection model, you can use sm.getSelection() and sm.setSelection(datas) to respectively retrieve and set the selected state of the Data. For example:

const sm = dataModel.getSelectionModel(); // get the selection model of the DataModel
sm.setSelection(data); // select one Data. The premise is that the `Data` has been created and added to the DataModel
Enter fullscreen mode Exit fullscreen mode

View Component

View components are HTML elements that are displayed to users and can be used for interaction. For example, tables, 2D displays, and 3D scenes that mentioned earlier. As HT encapsulates native HTML elements and binds each view component to DataModel and Data, we only need to modify the properties of Data through JavaScript code to drive the changes of view components. This logic is basically the same in various view components in HT, so it will be very easy in development after familiarizing with this coding logic.

Using 3D scene as an example. The following code will add a 3D scene under the body tag and display the grid lines. After adding the scene, we’ll then add a new HT node.

const g3d = new ht.graph3d.Graph3dView(); // create a 3D scene
g3d.setGridVisible(true); // show grid on the ground
g3d.addToDOM(); // add the 3D scene to DOM

const dm = g3d.dm(); // get the `DataModel` of the 3D scene

const dataModel = dm;
const sm = dataModel.getSelectionModel(); // get the selection model of the DataModel

let node = new ht.Node(); // create a `HT` node, ht.Node is extended from `ht.Data`
dm.add(node); // add the node to 3D scene
sm.setSelection(node); // select a the node

const p3 = node.getPosition3d(); //default position in 3D scene:[0, 0, 0]
Enter fullscreen mode Exit fullscreen mode

3d scene

The HT node (ht.Node) is actually a class extended from ht.Data. On the HT Node, it has richer attribute definitions, such as setting size, scaling, rotation angle, position, and textures. In a 3D scene, each HT node can be used to represent a 3D model or other objects. For example, here we did not configure its attributes, so it defaults to displaying a hexahedron.

In the above example, we created a 3D scene view component. Each 3D scene corresponds to a DataModel. After obtaining the DataModel of the scene, we then added one ht.Node. Since no position was specified, the system placed it at the default position of [0, 0, 0];

After following the steps above and creating our own 3D scene with multiple models, we may want to save all the data in the scene for future use. This is where serialization and deserialization come into play.

Serialization and deserialization

Serialization and deserialization are very important concepts in HT. Serialization allows us to convert data in DataModel into strings and save them as files. Deserialization can help us restore files to DataModel. Since DataModel corresponds to view components, this enables us to save and restore our view data.

In HT, we can use the serialize() and deserialize() methods of the DataModel to perform serialization and deserialization operations. After serialization, the DataModel data will be converted into a JSON string.

const json = dm.serialize(); // serialization 

dm.deserialize(json); // deserialization 
Enter fullscreen mode Exit fullscreen mode

As shown in the example above, the JSON string we obtained after serializing the 3D scene is as follows:

{
  "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
  }]
}
Enter fullscreen mode Exit fullscreen mode

The JSON data format used here is a custom format of Hightopo. To save storage space, each property uses an abbreviated form. We generally do not need to modify it.

Summary

This chapter introduces some basic concepts of HT for Web, including: the basic data type ht.Data, the data model ht.DataModel, the selection model ht.SelectionModel, view components, and serialization and deserialization. These concepts are fundamental to HT for Web and are used throughout the development process. Understanding their functions and the logic between them is crucial for subsequent development and understanding of the operation logic of various components in HT for Web.

Top comments (0)