vislite 0.7.0-alpha.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +8 -3
- package/README.md +20 -1
- package/lib/Buffer/index.umd.js +2 -2
- package/lib/Buffer/index.umd.min.js +2 -2
- package/lib/Canvas/index.umd.js +4 -4
- package/lib/Canvas/index.umd.min.js +3 -3
- package/lib/Cardinal/index.umd.js +2 -2
- package/lib/Cardinal/index.umd.min.js +2 -2
- package/lib/Eoap/index.umd.js +2 -2
- package/lib/Eoap/index.umd.min.js +2 -2
- package/lib/Geometry/index.umd.js +69 -8
- package/lib/Geometry/index.umd.min.js +3 -3
- package/lib/Hermite/index.umd.js +2 -2
- package/lib/Hermite/index.umd.min.js +2 -2
- package/lib/Matrix4/index.umd.js +2 -2
- package/lib/Matrix4/index.umd.min.js +2 -2
- package/lib/Mercator/index.umd.js +2 -2
- package/lib/Mercator/index.umd.min.js +2 -2
- package/lib/OralCanvas/index.es.js +3 -3
- package/lib/OralCanvas/index.es.min.js +3 -3
- package/lib/OralWebGL/index.es.js +21 -18
- package/lib/OralWebGL/index.es.min.js +3 -3
- package/lib/SVG/index.umd.js +2 -2
- package/lib/SVG/index.umd.min.js +2 -2
- package/lib/Shader/index.umd.js +3 -2
- package/lib/Shader/index.umd.min.js +3 -3
- package/lib/Texture/index.umd.js +2 -2
- package/lib/Texture/index.umd.min.js +2 -2
- package/lib/TreeLayout/index.umd.js +13 -11
- package/lib/TreeLayout/index.umd.min.js +3 -3
- package/lib/WebGL/index.umd.js +22 -19
- package/lib/WebGL/index.umd.min.js +3 -3
- package/lib/animation/index.umd.js +2 -2
- package/lib/animation/index.umd.min.js +2 -2
- package/lib/formatColor/index.umd.js +2 -2
- package/lib/formatColor/index.umd.min.js +2 -2
- package/lib/getLoopColors/index.umd.js +2 -2
- package/lib/getLoopColors/index.umd.min.js +2 -2
- package/lib/getWebGLContext/index.umd.js +4 -4
- package/lib/getWebGLContext/index.umd.min.js +3 -3
- package/lib/index.umd.js +104 -38
- package/lib/index.umd.min.js +3 -3
- package/lib/move/index.umd.js +2 -2
- package/lib/move/index.umd.min.js +2 -2
- package/lib/resizeObserver/index.umd.js +2 -2
- package/lib/resizeObserver/index.umd.min.js +2 -2
- package/lib/rotate/index.umd.js +2 -2
- package/lib/rotate/index.umd.min.js +2 -2
- package/lib/ruler/index.umd.js +4 -4
- package/lib/ruler/index.umd.min.js +3 -3
- package/lib/scale/index.umd.js +2 -2
- package/lib/scale/index.umd.min.js +2 -2
- package/lib/throttle/index.umd.js +2 -2
- package/lib/throttle/index.umd.min.js +2 -2
- package/lib/viewHandler/index.umd.js +2 -2
- package/lib/viewHandler/index.umd.min.js +2 -2
- package/package.json +1 -1
- package/src/Canvas.ts +70 -70
- package/src/Geometry.ts +126 -82
- package/src/Matrix4/rotate.ts +15 -15
- package/src/Matrix4/transform.ts +64 -64
- package/src/WebGL.ts +66 -66
- package/src/common/assemble.ts +22 -22
- package/src/common/canvas/index.ts +177 -177
- package/src/common/canvas/painter.ts +419 -417
- package/src/common/geometry/prism-vertical.ts +40 -40
- package/src/common/geometry/tool/rotateLine.ts +36 -0
- package/src/common/setStyle.ts +5 -5
- package/src/common/svg/config.ts +190 -186
- package/src/common/svg/tool.ts +44 -44
- package/src/common/tree/toInnerTree.ts +59 -57
- package/src/common/tree/toPlainTree.ts +132 -132
- package/src/common/webgl/buffer.ts +79 -79
- package/src/common/webgl/doDraw.ts +108 -108
- package/src/common/webgl/getWebGLContext.ts +28 -28
- package/src/common/webgl/index.ts +226 -224
- package/src/common/webgl/shader.ts +75 -75
- package/src/common/webgl/texture.ts +97 -97
- package/src/layout/TreeLayout.ts +188 -186
- package/src/resizeObserver.ts +37 -37
- package/src/ruler.ts +209 -209
- package/src/viewHandler.ts +160 -158
- package/types/Canvas.d.ts +308 -308
- package/types/Geometry.d.ts +65 -40
- package/types/TreeConfig.d.ts +36 -24
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
// 初始化一个纹理对象
|
|
2
|
-
// type = gl.TEXTURE_2D 二维纹理
|
|
3
|
-
// type = gl.TEXTURE_CUBE_MAP 立方体纹理
|
|
4
|
-
// unit表示开启的纹理单元编号
|
|
5
|
-
const initTexture = (painter: WebGLRenderingContext, type: number, unit: number) => {
|
|
6
|
-
|
|
7
|
-
// 创建纹理对象
|
|
8
|
-
const texture = painter.createTexture()
|
|
9
|
-
|
|
10
|
-
// 开启纹理单元,unit表示开启的编号
|
|
11
|
-
painter.activeTexture(painter['TEXTURE' + unit])
|
|
12
|
-
|
|
13
|
-
// 绑定纹理对象到目标上
|
|
14
|
-
painter.bindTexture(type, texture)
|
|
15
|
-
|
|
16
|
-
return texture
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// 链接资源图片
|
|
20
|
-
// level默认传入0即可,和金字塔纹理有关
|
|
21
|
-
// format表示图像的内部格式:
|
|
22
|
-
// gl.RGB(红绿蓝)
|
|
23
|
-
// gl.RGBA(红绿蓝透明度)
|
|
24
|
-
// gl.ALPHA(0.0,0.0,0.0,透明度)
|
|
25
|
-
// gl.LUMINANCE(L、L、L、1L:流明)
|
|
26
|
-
// gl.LUMINANCE_ALPHA(L、L、L,透明度)
|
|
27
|
-
// textureType表示纹理数据的格式:
|
|
28
|
-
// gl.UNSIGNED_BYTE: 表示无符号整形,每一个颜色分量占据1字节
|
|
29
|
-
// gl.UNSIGNED_SHORT_5_6_5: 表示RGB,每一个分量分别占据占据5, 6, 5比特
|
|
30
|
-
// gl.UNSIGNED_SHORT_4_4_4_4: 表示RGBA,每一个分量分别占据占据4, 4, 4, 4比特
|
|
31
|
-
// gl.UNSIGNED_SHORT_5_5_5_1: 表示RGBA,每一个分量分别占据占据5比特,A分量占据1比特
|
|
32
|
-
const linkImage = (painter: WebGLRenderingContext, type: number, level: number, format: number, textureType: number, image: TexImageSource) => {
|
|
33
|
-
painter.texImage2D(type, level, format, format, textureType, image)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const linkCube = (painter: WebGLRenderingContext, type: number, level: number, format: number, textureType: number, images: TexImageSource[], width: number, height: number, texture: WebGLTexture) => {
|
|
37
|
-
|
|
38
|
-
const types = [
|
|
39
|
-
painter.TEXTURE_CUBE_MAP_POSITIVE_X, // 右
|
|
40
|
-
painter.TEXTURE_CUBE_MAP_NEGATIVE_X, // 左
|
|
41
|
-
painter.TEXTURE_CUBE_MAP_POSITIVE_Y, // 上
|
|
42
|
-
painter.TEXTURE_CUBE_MAP_NEGATIVE_Y, // 下
|
|
43
|
-
painter.TEXTURE_CUBE_MAP_POSITIVE_Z, // 后
|
|
44
|
-
painter.TEXTURE_CUBE_MAP_NEGATIVE_Z // 前
|
|
45
|
-
]
|
|
46
|
-
let target: number
|
|
47
|
-
|
|
48
|
-
for (let i = 0; i < types.length; i++) {
|
|
49
|
-
if (images[i]) {
|
|
50
|
-
target = types[i]
|
|
51
|
-
painter.texImage2D(target, level, format, width, height, 0, format, textureType, null)
|
|
52
|
-
painter.bindTexture(type, texture)
|
|
53
|
-
painter.texImage2D(target, level, format, format, textureType, images[i])
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
painter.generateMipmap(type)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
class TextureObject {
|
|
61
|
-
|
|
62
|
-
private __painter: WebGLRenderingContext
|
|
63
|
-
private __type: number
|
|
64
|
-
|
|
65
|
-
private __texture: WebGLTexture
|
|
66
|
-
|
|
67
|
-
constructor(painter: WebGLRenderingContext, type: string, unit = 0) {
|
|
68
|
-
this.__painter = painter
|
|
69
|
-
this.__type = {
|
|
70
|
-
"2d": painter.TEXTURE_2D,
|
|
71
|
-
"cube": painter.TEXTURE_CUBE_MAP
|
|
72
|
-
}[type]
|
|
73
|
-
|
|
74
|
-
// 创建纹理
|
|
75
|
-
this.__texture = initTexture(painter, this.__type, unit)
|
|
76
|
-
|
|
77
|
-
// 配置纹理
|
|
78
|
-
painter.texParameteri(this.__type, painter.TEXTURE_MIN_FILTER, painter.NEAREST)
|
|
79
|
-
painter.texParameteri(this.__type, painter.TEXTURE_MAG_FILTER, painter.NEAREST)
|
|
80
|
-
painter.texParameteri(this.__type, painter.TEXTURE_WRAP_S, painter.CLAMP_TO_EDGE)
|
|
81
|
-
painter.texParameteri(this.__type, painter.TEXTURE_WRAP_T, painter.CLAMP_TO_EDGE)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// 链接图片资源(单一)
|
|
85
|
-
useImage(image: TexImageSource) {
|
|
86
|
-
linkImage(this.__painter, this.__type, 0, this.__painter.RGBA, this.__painter.UNSIGNED_BYTE, image)
|
|
87
|
-
return this
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// 链接图片资源(多张)
|
|
91
|
-
useCube(images: TexImageSource[], width: number, height: number) {
|
|
92
|
-
linkCube(this.__painter, this.__type, 0, this.__painter.RGBA, this.__painter.UNSIGNED_BYTE, images, width, height, this.__texture)
|
|
93
|
-
return this
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
1
|
+
// 初始化一个纹理对象
|
|
2
|
+
// type = gl.TEXTURE_2D 二维纹理
|
|
3
|
+
// type = gl.TEXTURE_CUBE_MAP 立方体纹理
|
|
4
|
+
// unit表示开启的纹理单元编号
|
|
5
|
+
const initTexture = (painter: WebGLRenderingContext, type: number, unit: number) => {
|
|
6
|
+
|
|
7
|
+
// 创建纹理对象
|
|
8
|
+
const texture = painter.createTexture()
|
|
9
|
+
|
|
10
|
+
// 开启纹理单元,unit表示开启的编号
|
|
11
|
+
painter.activeTexture(painter['TEXTURE' + unit])
|
|
12
|
+
|
|
13
|
+
// 绑定纹理对象到目标上
|
|
14
|
+
painter.bindTexture(type, texture)
|
|
15
|
+
|
|
16
|
+
return texture
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 链接资源图片
|
|
20
|
+
// level默认传入0即可,和金字塔纹理有关
|
|
21
|
+
// format表示图像的内部格式:
|
|
22
|
+
// gl.RGB(红绿蓝)
|
|
23
|
+
// gl.RGBA(红绿蓝透明度)
|
|
24
|
+
// gl.ALPHA(0.0,0.0,0.0,透明度)
|
|
25
|
+
// gl.LUMINANCE(L、L、L、1L:流明)
|
|
26
|
+
// gl.LUMINANCE_ALPHA(L、L、L,透明度)
|
|
27
|
+
// textureType表示纹理数据的格式:
|
|
28
|
+
// gl.UNSIGNED_BYTE: 表示无符号整形,每一个颜色分量占据1字节
|
|
29
|
+
// gl.UNSIGNED_SHORT_5_6_5: 表示RGB,每一个分量分别占据占据5, 6, 5比特
|
|
30
|
+
// gl.UNSIGNED_SHORT_4_4_4_4: 表示RGBA,每一个分量分别占据占据4, 4, 4, 4比特
|
|
31
|
+
// gl.UNSIGNED_SHORT_5_5_5_1: 表示RGBA,每一个分量分别占据占据5比特,A分量占据1比特
|
|
32
|
+
const linkImage = (painter: WebGLRenderingContext, type: number, level: number, format: number, textureType: number, image: TexImageSource) => {
|
|
33
|
+
painter.texImage2D(type, level, format, format, textureType, image)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const linkCube = (painter: WebGLRenderingContext, type: number, level: number, format: number, textureType: number, images: TexImageSource[], width: number, height: number, texture: WebGLTexture) => {
|
|
37
|
+
|
|
38
|
+
const types = [
|
|
39
|
+
painter.TEXTURE_CUBE_MAP_POSITIVE_X, // 右
|
|
40
|
+
painter.TEXTURE_CUBE_MAP_NEGATIVE_X, // 左
|
|
41
|
+
painter.TEXTURE_CUBE_MAP_POSITIVE_Y, // 上
|
|
42
|
+
painter.TEXTURE_CUBE_MAP_NEGATIVE_Y, // 下
|
|
43
|
+
painter.TEXTURE_CUBE_MAP_POSITIVE_Z, // 后
|
|
44
|
+
painter.TEXTURE_CUBE_MAP_NEGATIVE_Z // 前
|
|
45
|
+
]
|
|
46
|
+
let target: number
|
|
47
|
+
|
|
48
|
+
for (let i = 0; i < types.length; i++) {
|
|
49
|
+
if (images[i]) {
|
|
50
|
+
target = types[i]
|
|
51
|
+
painter.texImage2D(target, level, format, width, height, 0, format, textureType, null)
|
|
52
|
+
painter.bindTexture(type, texture)
|
|
53
|
+
painter.texImage2D(target, level, format, format, textureType, images[i])
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
painter.generateMipmap(type)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
class TextureObject {
|
|
61
|
+
|
|
62
|
+
private __painter: WebGLRenderingContext
|
|
63
|
+
private __type: number
|
|
64
|
+
|
|
65
|
+
private __texture: WebGLTexture
|
|
66
|
+
|
|
67
|
+
constructor(painter: WebGLRenderingContext, type: string, unit = 0) {
|
|
68
|
+
this.__painter = painter
|
|
69
|
+
this.__type = {
|
|
70
|
+
"2d": painter.TEXTURE_2D,
|
|
71
|
+
"cube": painter.TEXTURE_CUBE_MAP
|
|
72
|
+
}[type] as number
|
|
73
|
+
|
|
74
|
+
// 创建纹理
|
|
75
|
+
this.__texture = initTexture(painter, this.__type, unit) as WebGLTexture
|
|
76
|
+
|
|
77
|
+
// 配置纹理
|
|
78
|
+
painter.texParameteri(this.__type, painter.TEXTURE_MIN_FILTER, painter.NEAREST)
|
|
79
|
+
painter.texParameteri(this.__type, painter.TEXTURE_MAG_FILTER, painter.NEAREST)
|
|
80
|
+
painter.texParameteri(this.__type, painter.TEXTURE_WRAP_S, painter.CLAMP_TO_EDGE)
|
|
81
|
+
painter.texParameteri(this.__type, painter.TEXTURE_WRAP_T, painter.CLAMP_TO_EDGE)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 链接图片资源(单一)
|
|
85
|
+
useImage(image: TexImageSource) {
|
|
86
|
+
linkImage(this.__painter, this.__type, 0, this.__painter.RGBA, this.__painter.UNSIGNED_BYTE, image)
|
|
87
|
+
return this
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 链接图片资源(多张)
|
|
91
|
+
useCube(images: TexImageSource[], width: number, height: number) {
|
|
92
|
+
linkCube(this.__painter, this.__type, 0, this.__painter.RGBA, this.__painter.UNSIGNED_BYTE, images, width, height, this.__texture)
|
|
93
|
+
return this
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
98
|
export default TextureObject
|
package/src/layout/TreeLayout.ts
CHANGED
|
@@ -1,187 +1,189 @@
|
|
|
1
|
-
import type TreeLayoutType from '../../types/TreeLayout'
|
|
2
|
-
import type { TreeResultType } from '../../types/Tree'
|
|
3
|
-
import type TreeOptionType from '../../types/TreeOption'
|
|
4
|
-
|
|
5
|
-
import Tree from '../common/tree/index'
|
|
6
|
-
import mergeOption from '../common/mergeOption'
|
|
7
|
-
import animation from '../animation'
|
|
8
|
-
import rotate from '../rotate'
|
|
9
|
-
|
|
10
|
-
class TreeLayout extends Tree implements TreeLayoutType {
|
|
11
|
-
readonly name: string = 'TreeLayout'
|
|
12
|
-
|
|
13
|
-
private __option
|
|
14
|
-
offsetX: 0,
|
|
15
|
-
offsetY: 0,
|
|
16
|
-
duration: 500,
|
|
17
|
-
type: "plain",
|
|
18
|
-
direction: "LR",
|
|
19
|
-
x: 100,
|
|
20
|
-
y: 100,
|
|
21
|
-
width: 100,
|
|
22
|
-
height: 100,
|
|
23
|
-
radius: 100
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
private __rback: (tree: TreeResultType) => void
|
|
27
|
-
private __oralTree: any
|
|
28
|
-
private __preTree: TreeResultType
|
|
29
|
-
|
|
30
|
-
private __noOpens = {}
|
|
31
|
-
|
|
32
|
-
setOption(option: TreeOptionType) {
|
|
33
|
-
mergeOption(option, this.__option)
|
|
34
|
-
return this
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
use(initTree: any, noOpens = {}) {
|
|
38
|
-
const tree = super.use(initTree, noOpens)
|
|
39
|
-
|
|
40
|
-
// 校对偏差
|
|
41
|
-
if (this.__option.offsetX != 0 || this.__option.offsetY != 0) {
|
|
42
|
-
for (const key in tree.node) {
|
|
43
|
-
if (!tree.node[key].show) {
|
|
44
|
-
|
|
45
|
-
let deep = 0, pid = key
|
|
46
|
-
do {
|
|
47
|
-
pid = tree.node[pid].pid
|
|
48
|
-
deep++
|
|
49
|
-
} while (!tree.node[pid].show)
|
|
50
|
-
|
|
51
|
-
tree.node[key].left += this.__option.offsetX * deep
|
|
52
|
-
tree.node[key].top += this.__option.offsetY * deep
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (this.__option.type == 'rect') {
|
|
58
|
-
if (this.__option.direction == 'LR' || this.__option.direction == "RL") {
|
|
59
|
-
|
|
60
|
-
const perW = this.__option.height / tree.size
|
|
61
|
-
const perD = this.__option.width / (tree.deep - 1)
|
|
62
|
-
|
|
63
|
-
const balanceW = this.__option.y - this.__option.height * 0.5
|
|
64
|
-
const flag = this.__option.direction == 'LR' ? 1 : -1
|
|
65
|
-
|
|
66
|
-
for (const key in tree.node) {
|
|
67
|
-
if (tree.deep == 1) {
|
|
68
|
-
tree.node[key].left = this.__option.x + this.__option.width * 0.5 * flag
|
|
69
|
-
tree.node[key].top = this.__option.y
|
|
70
|
-
} else {
|
|
71
|
-
tree.node[key].left = this.__option.x + (tree.node[key].left - 0.5) * perD * flag
|
|
72
|
-
tree.node[key].top = tree.node[key].top * perW + balanceW
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
} else if (this.__option.direction == 'TB' || this.__option.direction == "BT") {
|
|
76
|
-
|
|
77
|
-
const perW = this.__option.width / tree.size
|
|
78
|
-
const perD = this.__option.height / (tree.deep - 1)
|
|
79
|
-
|
|
80
|
-
const balanceW = this.__option.x - this.__option.width * 0.5
|
|
81
|
-
const flag = this.__option.direction == 'TB' ? 1 : -1
|
|
82
|
-
|
|
83
|
-
for (const key in tree.node) {
|
|
84
|
-
if (tree.deep == 1) {
|
|
85
|
-
tree.node[key].left = this.__option.x
|
|
86
|
-
tree.node[key].top = this.__option.y + this.__option.height * 0.5 * flag
|
|
87
|
-
} else {
|
|
88
|
-
const left = tree.node[key].left
|
|
89
|
-
|
|
90
|
-
tree.node[key].left = tree.node[key].top * perW + balanceW
|
|
91
|
-
tree.node[key].top = this.__option.y + (left - 0.5) * perD * flag
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
} else if (this.__option.type == 'circle') {
|
|
98
|
-
const cx = this.__option.x, cy = this.__option.y
|
|
99
|
-
const deg = Math.PI * 2 / tree.size
|
|
100
|
-
const per = this.__option.radius / (tree.deep - 1)
|
|
101
|
-
|
|
102
|
-
for (const key in tree.node) {
|
|
103
|
-
if (tree.node[key].left == 0.5) {
|
|
104
|
-
tree.node[key].left = cx
|
|
105
|
-
tree.node[key].top = cy
|
|
106
|
-
} else {
|
|
107
|
-
const position = rotate(cx, cy, deg * tree.node[key].top, cx + (tree.node[key].left - 0.5) * per, cy)
|
|
108
|
-
|
|
109
|
-
tree.node[key].left = position[0]
|
|
110
|
-
tree.node[key].top = position[1]
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return tree
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
bind(initTree: any, renderBack: (tree: TreeResultType) => void, noOpens = {}) {
|
|
119
|
-
this.__rback = renderBack
|
|
120
|
-
this.__oralTree = initTree
|
|
121
|
-
this.__noOpens = noOpens
|
|
122
|
-
|
|
123
|
-
this.__preTree = this.use(this.__oralTree, this.__noOpens)
|
|
124
|
-
this.__rback(this.__preTree)
|
|
125
|
-
|
|
126
|
-
return this
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
unbind() {
|
|
130
|
-
this.__rback = null
|
|
131
|
-
this.__oralTree = null
|
|
132
|
-
this.__preTree = null
|
|
133
|
-
this.__noOpens = {}
|
|
134
|
-
return this
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
private doUpdate() {
|
|
138
|
-
const newTree = this.use(this.__oralTree, this.__noOpens)
|
|
139
|
-
|
|
140
|
-
const cacheTree = JSON.parse(JSON.stringify(newTree))
|
|
141
|
-
|
|
142
|
-
animation((deep) => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
this.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
this.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
1
|
+
import type TreeLayoutType from '../../types/TreeLayout'
|
|
2
|
+
import type { TreeResultType } from '../../types/Tree'
|
|
3
|
+
import type TreeOptionType from '../../types/TreeOption'
|
|
4
|
+
|
|
5
|
+
import Tree from '../common/tree/index'
|
|
6
|
+
import mergeOption from '../common/mergeOption'
|
|
7
|
+
import animation from '../animation'
|
|
8
|
+
import rotate from '../rotate'
|
|
9
|
+
|
|
10
|
+
class TreeLayout extends Tree implements TreeLayoutType {
|
|
11
|
+
readonly name: string = 'TreeLayout'
|
|
12
|
+
|
|
13
|
+
private __option = {
|
|
14
|
+
offsetX: 0,
|
|
15
|
+
offsetY: 0,
|
|
16
|
+
duration: 500,
|
|
17
|
+
type: "plain",
|
|
18
|
+
direction: "LR",
|
|
19
|
+
x: 100,
|
|
20
|
+
y: 100,
|
|
21
|
+
width: 100,
|
|
22
|
+
height: 100,
|
|
23
|
+
radius: 100
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private __rback: (tree: TreeResultType) => void
|
|
27
|
+
private __oralTree: any
|
|
28
|
+
private __preTree: TreeResultType | null
|
|
29
|
+
|
|
30
|
+
private __noOpens = {}
|
|
31
|
+
|
|
32
|
+
setOption(option: TreeOptionType) {
|
|
33
|
+
mergeOption(option, this.__option)
|
|
34
|
+
return this
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
use(initTree: any, noOpens = {}) {
|
|
38
|
+
const tree = super.use(initTree, noOpens)
|
|
39
|
+
|
|
40
|
+
// 校对偏差
|
|
41
|
+
if (this.__option.offsetX != 0 || this.__option.offsetY != 0) {
|
|
42
|
+
for (const key in tree.node) {
|
|
43
|
+
if (!tree.node[key].show) {
|
|
44
|
+
|
|
45
|
+
let deep = 0, pid = key
|
|
46
|
+
do {
|
|
47
|
+
pid = tree.node[pid].pid
|
|
48
|
+
deep++
|
|
49
|
+
} while (!tree.node[pid].show)
|
|
50
|
+
|
|
51
|
+
tree.node[key].left += this.__option.offsetX * deep
|
|
52
|
+
tree.node[key].top += this.__option.offsetY * deep
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (this.__option.type == 'rect') {
|
|
58
|
+
if (this.__option.direction == 'LR' || this.__option.direction == "RL") {
|
|
59
|
+
|
|
60
|
+
const perW = this.__option.height / tree.size
|
|
61
|
+
const perD = this.__option.width / (tree.deep - 1)
|
|
62
|
+
|
|
63
|
+
const balanceW = this.__option.y - this.__option.height * 0.5
|
|
64
|
+
const flag = this.__option.direction == 'LR' ? 1 : -1
|
|
65
|
+
|
|
66
|
+
for (const key in tree.node) {
|
|
67
|
+
if (tree.deep == 1) {
|
|
68
|
+
tree.node[key].left = this.__option.x + this.__option.width * 0.5 * flag
|
|
69
|
+
tree.node[key].top = this.__option.y
|
|
70
|
+
} else {
|
|
71
|
+
tree.node[key].left = this.__option.x + (tree.node[key].left - 0.5) * perD * flag
|
|
72
|
+
tree.node[key].top = tree.node[key].top * perW + balanceW
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} else if (this.__option.direction == 'TB' || this.__option.direction == "BT") {
|
|
76
|
+
|
|
77
|
+
const perW = this.__option.width / tree.size
|
|
78
|
+
const perD = this.__option.height / (tree.deep - 1)
|
|
79
|
+
|
|
80
|
+
const balanceW = this.__option.x - this.__option.width * 0.5
|
|
81
|
+
const flag = this.__option.direction == 'TB' ? 1 : -1
|
|
82
|
+
|
|
83
|
+
for (const key in tree.node) {
|
|
84
|
+
if (tree.deep == 1) {
|
|
85
|
+
tree.node[key].left = this.__option.x
|
|
86
|
+
tree.node[key].top = this.__option.y + this.__option.height * 0.5 * flag
|
|
87
|
+
} else {
|
|
88
|
+
const left = tree.node[key].left
|
|
89
|
+
|
|
90
|
+
tree.node[key].left = tree.node[key].top * perW + balanceW
|
|
91
|
+
tree.node[key].top = this.__option.y + (left - 0.5) * perD * flag
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
} else if (this.__option.type == 'circle') {
|
|
98
|
+
const cx = this.__option.x, cy = this.__option.y
|
|
99
|
+
const deg = Math.PI * 2 / tree.size
|
|
100
|
+
const per = this.__option.radius / (tree.deep - 1)
|
|
101
|
+
|
|
102
|
+
for (const key in tree.node) {
|
|
103
|
+
if (tree.node[key].left == 0.5) {
|
|
104
|
+
tree.node[key].left = cx
|
|
105
|
+
tree.node[key].top = cy
|
|
106
|
+
} else {
|
|
107
|
+
const position = rotate(cx, cy, deg * tree.node[key].top, cx + (tree.node[key].left - 0.5) * per, cy)
|
|
108
|
+
|
|
109
|
+
tree.node[key].left = position[0]
|
|
110
|
+
tree.node[key].top = position[1]
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return tree
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
bind(initTree: any, renderBack: (tree: TreeResultType) => void, noOpens = {}) {
|
|
119
|
+
this.__rback = renderBack
|
|
120
|
+
this.__oralTree = initTree
|
|
121
|
+
this.__noOpens = noOpens
|
|
122
|
+
|
|
123
|
+
this.__preTree = this.use(this.__oralTree, this.__noOpens)
|
|
124
|
+
this.__rback(this.__preTree)
|
|
125
|
+
|
|
126
|
+
return this
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
unbind() {
|
|
130
|
+
this.__rback = () => null
|
|
131
|
+
this.__oralTree = null
|
|
132
|
+
this.__preTree = null
|
|
133
|
+
this.__noOpens = {}
|
|
134
|
+
return this
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private doUpdate() {
|
|
138
|
+
const newTree = this.use(this.__oralTree, this.__noOpens)
|
|
139
|
+
|
|
140
|
+
const cacheTree = JSON.parse(JSON.stringify(newTree))
|
|
141
|
+
|
|
142
|
+
animation((deep) => {
|
|
143
|
+
|
|
144
|
+
if (this.__preTree) {
|
|
145
|
+
for (const key in cacheTree.node) {
|
|
146
|
+
if (newTree.node[key].show || this.__preTree.node[key].show) {
|
|
147
|
+
cacheTree.node[key].show = true
|
|
148
|
+
|
|
149
|
+
cacheTree.node[key].left = this.__preTree.node[key].left + (newTree.node[key].left - this.__preTree.node[key].left) * deep
|
|
150
|
+
cacheTree.node[key].top = this.__preTree.node[key].top + (newTree.node[key].top - this.__preTree.node[key].top) * deep
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
this.__rback(cacheTree)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
}, this.__option.duration, () => {
|
|
158
|
+
this.__preTree = newTree
|
|
159
|
+
this.__rback(this.__preTree)
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
closeNode(id: string) {
|
|
164
|
+
if (!this.__preTree) return this
|
|
165
|
+
this.__noOpens[id] = true
|
|
166
|
+
|
|
167
|
+
this.doUpdate()
|
|
168
|
+
return this
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
openNode(id: string) {
|
|
172
|
+
if (!this.__preTree) return this
|
|
173
|
+
this.__noOpens[id] = false
|
|
174
|
+
|
|
175
|
+
this.doUpdate()
|
|
176
|
+
return this
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
toggleNode(id: string) {
|
|
180
|
+
if (!this.__preTree) return this
|
|
181
|
+
this.__noOpens[id] = !this.__noOpens[id]
|
|
182
|
+
|
|
183
|
+
this.doUpdate()
|
|
184
|
+
return this
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
}
|
|
188
|
+
|
|
187
189
|
export default TreeLayout
|
package/src/resizeObserver.ts
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
let observer: ResizeObserver
|
|
2
|
-
|
|
3
|
-
const attrValueToCallback = {}
|
|
4
|
-
let uniqueid = 0
|
|
5
|
-
|
|
6
|
-
export default function (el: HTMLElement | null, callback: Function) {
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
|
|
10
|
-
if (!observer) {
|
|
11
|
-
observer = new ResizeObserver(entries => {
|
|
12
|
-
for (const entry of entries) {
|
|
13
|
-
attrValueToCallback[(entry.target as any)._resize_observer_]()
|
|
14
|
-
}
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
uniqueid++
|
|
19
|
-
|
|
20
|
-
(el as any)._resize_observer_ = uniqueid
|
|
21
|
-
attrValueToCallback[uniqueid] = callback
|
|
22
|
-
|
|
23
|
-
observer.observe(el)
|
|
24
|
-
|
|
25
|
-
return function () {
|
|
26
|
-
if (observer) {
|
|
27
|
-
observer.unobserve(el)
|
|
28
|
-
delete attrValueToCallback[(el as any)._resize_observer_]
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
} catch (e) {
|
|
33
|
-
callback()
|
|
34
|
-
|
|
35
|
-
// 如果浏览器不支持此接口
|
|
36
|
-
console.error('ResizeObserver undefined!')
|
|
37
|
-
}
|
|
1
|
+
let observer: ResizeObserver
|
|
2
|
+
|
|
3
|
+
const attrValueToCallback = {}
|
|
4
|
+
let uniqueid = 0
|
|
5
|
+
|
|
6
|
+
export default function (el: HTMLElement | null, callback: Function) {
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
|
|
10
|
+
if (!observer) {
|
|
11
|
+
observer = new ResizeObserver(entries => {
|
|
12
|
+
for (const entry of entries) {
|
|
13
|
+
attrValueToCallback[(entry.target as any)._resize_observer_]()
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
uniqueid++
|
|
19
|
+
|
|
20
|
+
(el as any)._resize_observer_ = uniqueid
|
|
21
|
+
attrValueToCallback[uniqueid] = callback
|
|
22
|
+
|
|
23
|
+
observer.observe(el as HTMLElement)
|
|
24
|
+
|
|
25
|
+
return function () {
|
|
26
|
+
if (observer) {
|
|
27
|
+
observer.unobserve(el as HTMLElement)
|
|
28
|
+
delete attrValueToCallback[(el as any)._resize_observer_]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
} catch (e) {
|
|
33
|
+
callback()
|
|
34
|
+
|
|
35
|
+
// 如果浏览器不支持此接口
|
|
36
|
+
console.error('ResizeObserver undefined!')
|
|
37
|
+
}
|
|
38
38
|
}
|