vislite 0.1.0 → 0.2.0-alpha.7
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/AUTHORS.txt +6 -6
- package/CHANGELOG +24 -1
- package/LICENSE +20 -20
- package/README.md +53 -38
- package/lib/Canvas/index.umd.js +135 -46
- package/lib/Canvas/index.umd.min.js +7 -3
- package/lib/Cardinal/index.umd.js +6 -2
- package/lib/Cardinal/index.umd.min.js +6 -2
- package/lib/Eoap/index.umd.js +9 -5
- package/lib/Eoap/index.umd.min.js +6 -2
- package/lib/Hermite/index.umd.js +6 -2
- package/lib/Hermite/index.umd.min.js +6 -2
- package/lib/Matrix4/index.umd.js +6 -2
- package/lib/Matrix4/index.umd.min.js +6 -2
- package/lib/Mercator/index.umd.js +42 -0
- package/lib/Mercator/index.umd.min.js +15 -0
- package/lib/OralCanvas/index.es.js +124 -44
- package/lib/OralCanvas/index.es.min.js +7 -3
- package/lib/OralWebGL/index.es.js +567 -0
- package/lib/OralWebGL/index.es.min.js +15 -0
- package/lib/SVG/index.umd.js +16 -5
- package/lib/SVG/index.umd.min.js +7 -3
- package/lib/WebGL/index.umd.js +626 -0
- package/lib/WebGL/index.umd.min.js +15 -0
- package/lib/animation/index.umd.js +6 -2
- package/lib/animation/index.umd.min.js +6 -2
- package/lib/getLoopColors/index.umd.js +6 -2
- package/lib/getLoopColors/index.umd.min.js +6 -2
- package/lib/index.umd.js +1514 -863
- package/lib/index.umd.min.js +7 -3
- package/lib/rotate/index.umd.js +6 -2
- package/lib/rotate/index.umd.min.js +6 -2
- package/lib/ruler/index.umd.js +6 -2
- package/lib/ruler/index.umd.min.js +6 -2
- package/lib/viewHandler/index.umd.js +129 -0
- package/lib/viewHandler/index.umd.min.js +15 -0
- package/miniprogram/ui-canvas/index.js +18 -3
- package/miniprogram/ui-canvas/index.json +4 -4
- package/miniprogram/ui-canvas/index.wxml +4 -4
- package/miniprogram/ui-canvas/index.wxss +5 -5
- package/package/Canvas/index.ts +1 -1
- package/package/Cardinal/index.ts +2 -2
- package/package/Eoap/index.ts +2 -2
- package/package/Hermite/index.ts +2 -2
- package/package/Matrix4/index.ts +2 -2
- package/package/Mercator/index.ts +3 -0
- package/package/OralCanvas/index.ts +1 -1
- package/package/OralWebGL/index.ts +2 -0
- package/package/SVG/index.ts +2 -2
- package/package/WebGL/index.ts +2 -0
- package/package/animation/index.ts +2 -2
- package/package/getLoopColors/index.ts +2 -2
- package/package/index.ts +32 -9
- package/package/rotate/index.ts +2 -2
- package/package/ruler/index.ts +2 -2
- package/package/viewHandler/index.ts +3 -0
- package/package.json +11 -2
- package/src/Canvas.ts +10 -1
- package/src/Eoap.ts +5 -5
- package/src/Matrix4/index.ts +76 -76
- package/src/Matrix4/move.ts +12 -12
- package/src/Matrix4/rotate.ts +15 -15
- package/src/Matrix4/scale.ts +11 -11
- package/src/Matrix4/transform.ts +64 -64
- package/src/Mercator.ts +27 -0
- package/src/SVG.ts +1 -1
- package/src/WebGL.ts +53 -0
- package/src/animation.ts +99 -99
- package/src/common/assemble.ts +23 -0
- package/src/common/canvas/arc.ts +50 -50
- package/src/common/canvas/config.ts +7 -6
- package/src/common/canvas/index.ts +29 -28
- package/src/common/canvas/painter.ts +51 -8
- package/src/common/canvas/texts.ts +19 -0
- package/src/common/setStyle.ts +5 -5
- package/src/common/svg/config.ts +127 -126
- package/src/common/svg/index.ts +13 -3
- package/src/common/svg/tool.ts +43 -42
- package/src/common/webgl/buffer.ts +80 -0
- package/src/common/webgl/doDraw.ts +97 -0
- package/src/common/webgl/getColorFactory.ts +27 -0
- package/src/common/webgl/getShader.ts +62 -0
- package/src/common/webgl/getTexture.ts +12 -0
- package/src/common/webgl/getWebGLContext.ts +28 -0
- package/src/common/webgl/index.ts +212 -0
- package/src/common/webgl/shader.ts +76 -0
- package/src/common/webgl/texture.ts +99 -0
- package/src/getLoopColors.ts +42 -42
- package/src/interpolation/Cardinal.ts +91 -91
- package/src/interpolation/Hermite.ts +65 -65
- package/src/rotate.ts +7 -7
- package/src/ruler.ts +99 -99
- package/src/viewHandler.ts +140 -0
- package/types/Canvas.d.ts +220 -283
- package/types/CanvasConfig.d.ts +81 -0
- package/types/Cardinal.d.ts +13 -13
- package/types/Hermite.d.ts +18 -18
- package/types/Map.d.ts +10 -0
- package/types/Matrix4.d.ts +42 -42
- package/types/Object3D.d.ts +106 -0
- package/types/SVG.d.ts +210 -264
- package/types/SVGConfig.d.ts +59 -0
- package/types/Scene3D.d.ts +7 -0
- package/types/WebGL.d.ts +29 -0
- package/types/animation.d.ts +6 -6
- package/types/getLoopColors.d.ts +2 -2
- package/types/index.d.ts +70 -26
- package/types/rotate.d.ts +2 -2
- package/types/ruler.d.ts +2 -2
- package/types/viewHandler.d.ts +13 -0
- package/uni-app/ui-canvas.vue +94 -20
- package/types/Eoap.d.ts +0 -10
package/src/common/svg/config.ts
CHANGED
|
@@ -1,127 +1,128 @@
|
|
|
1
|
-
import { setAttribute } from "./tool"
|
|
2
|
-
import setStyle from "../setStyle"
|
|
3
|
-
import arc from '../canvas/arc'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"font-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
setAttribute(el, "
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
setAttribute(el, '
|
|
47
|
-
setAttribute(el, '
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
setAttribute(el, '
|
|
66
|
-
setAttribute(el, '
|
|
67
|
-
setAttribute(el, '
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
1
|
+
import { setAttribute } from "./tool"
|
|
2
|
+
import setStyle from "../setStyle"
|
|
3
|
+
import arc from '../canvas/arc'
|
|
4
|
+
import SVGConfigType from '../../../types/SVGConfig'
|
|
5
|
+
|
|
6
|
+
// 文字统一设置方法
|
|
7
|
+
export let initText = (el: SVGElement, config: SVGConfigType, x: number, y: number, deg: number) => {
|
|
8
|
+
if (el.nodeName.toLowerCase() !== 'text') throw new Error('Need a <text> !')
|
|
9
|
+
|
|
10
|
+
// 垂直对齐采用dy实现
|
|
11
|
+
setAttribute(el, "dy", {
|
|
12
|
+
"top": config['font-size'] * 0.5,
|
|
13
|
+
"middle": 0,
|
|
14
|
+
"bottom": -config['font-size'] * 0.5,
|
|
15
|
+
}[config.textBaseline])
|
|
16
|
+
|
|
17
|
+
setStyle(el, {
|
|
18
|
+
|
|
19
|
+
// 文字对齐方式
|
|
20
|
+
"text-anchor": {
|
|
21
|
+
"left": "start",
|
|
22
|
+
"right": "end",
|
|
23
|
+
"center": "middle"
|
|
24
|
+
}[config.textAlign],
|
|
25
|
+
"dominant-baseline": "central",
|
|
26
|
+
|
|
27
|
+
// 文字大小和字体设置
|
|
28
|
+
"font-size": config['font-size'] + "px",
|
|
29
|
+
"font-family": config['font-family']
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// 位置
|
|
33
|
+
setAttribute(el, "x", x)
|
|
34
|
+
setAttribute(el, "y", y)
|
|
35
|
+
|
|
36
|
+
// 旋转
|
|
37
|
+
if (typeof deg == "number") {
|
|
38
|
+
deg = deg % 360
|
|
39
|
+
setAttribute(el, "transform", "rotate(" + deg + "," + x + "," + y + ")")
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 画圆统一设置方法
|
|
44
|
+
export let initCircle = (el: SVGElement, cx: number, cy: number, r: number) => {
|
|
45
|
+
if (el.nodeName.toLowerCase() !== 'circle') throw new Error('Need a <circle> !')
|
|
46
|
+
setAttribute(el, 'cx', cx)
|
|
47
|
+
setAttribute(el, 'cy', cy)
|
|
48
|
+
setAttribute(el, 'r', r)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 路径统一设置方法
|
|
52
|
+
export let initPath = (el: SVGElement, path: string) => {
|
|
53
|
+
if (el.nodeName.toLowerCase() !== 'path') throw new Error('Need a <path> !')
|
|
54
|
+
setAttribute(el, 'd', path)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 画矩形统一设置方法
|
|
58
|
+
export let initRect = (el: SVGElement, x: number, y: number, width: number, height: number) => {
|
|
59
|
+
if (el.nodeName.toLowerCase() !== 'rect') throw new Error('Need a <rect> !')
|
|
60
|
+
|
|
61
|
+
// 由于高和宽不可以是负数,校对一下
|
|
62
|
+
if (height < 0) { height *= -1; y -= height }
|
|
63
|
+
if (width < 0) { width *= -1; x -= width }
|
|
64
|
+
|
|
65
|
+
setAttribute(el, 'x', x)
|
|
66
|
+
setAttribute(el, 'y', y)
|
|
67
|
+
setAttribute(el, 'width', width)
|
|
68
|
+
setAttribute(el, 'height', height)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 画弧统一设置方法
|
|
72
|
+
export let initArc = (el: SVGElement, config: SVGConfigType, cx: number, cy: number, r1: number, r2: number, beginDeg: number, deg: number) => {
|
|
73
|
+
|
|
74
|
+
if (el.nodeName.toLowerCase() !== 'path') throw new Error('Need a <path> !')
|
|
75
|
+
|
|
76
|
+
beginDeg = beginDeg % (Math.PI * 2)
|
|
77
|
+
|
|
78
|
+
if (r1 > r2) {
|
|
79
|
+
let temp = r1
|
|
80
|
+
r1 = r2
|
|
81
|
+
r2 = temp
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 当|deg|>=2π的时候都认为是一个圆环
|
|
85
|
+
if (deg >= Math.PI * 1.999999 || deg <= -Math.PI * 1.999999) {
|
|
86
|
+
deg = Math.PI * 1.999999
|
|
87
|
+
} else {
|
|
88
|
+
deg = deg % (Math.PI * 2)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
arc(beginDeg, deg, cx, cy, r1, r2, function (
|
|
92
|
+
beginA: number, endA: number,
|
|
93
|
+
begInnerX: number, begInnerY: number,
|
|
94
|
+
begOuterX: number, begOuterY: number,
|
|
95
|
+
endInnerX: number, endInnerY: number,
|
|
96
|
+
endOuterX: number, endOuterY: number,
|
|
97
|
+
r: number
|
|
98
|
+
) {
|
|
99
|
+
|
|
100
|
+
let f = (endA - beginA) > Math.PI ? 1 : 0,
|
|
101
|
+
d = "M" + begInnerX + " " + begInnerY
|
|
102
|
+
if (r < 0) r = -r
|
|
103
|
+
d +=
|
|
104
|
+
// 横半径 竖半径 x轴偏移角度 0小弧/1大弧 0逆时针/1顺时针 终点x 终点y
|
|
105
|
+
"A" + r1 + " " + r1 + " 0 " + f + " 1 " + endInnerX + " " + endInnerY
|
|
106
|
+
|
|
107
|
+
// 结尾
|
|
108
|
+
if (config["arc-end-cap"] == 'round')
|
|
109
|
+
d += "A" + r + " " + r + " " + " 0 1 0 " + endOuterX + " " + endOuterY
|
|
110
|
+
else if (config["arc-end-cap"] == '-round')
|
|
111
|
+
d += "A" + r + " " + r + " " + " 0 1 1 " + endOuterX + " " + endOuterY
|
|
112
|
+
else
|
|
113
|
+
d += "L" + endOuterX + " " + endOuterY
|
|
114
|
+
d += "A" + r2 + " " + r2 + " 0 " + f + " 0 " + begOuterX + " " + begOuterY
|
|
115
|
+
|
|
116
|
+
// 开头
|
|
117
|
+
if (config["arc-start-cap"] == 'round')
|
|
118
|
+
d += "A" + r + " " + r + " " + " 0 1 0 " + begInnerX + " " + begInnerY
|
|
119
|
+
else if (config["arc-start-cap"] == '-round')
|
|
120
|
+
d += "A" + r + " " + r + " " + " 0 1 1 " + begInnerX + " " + begInnerY
|
|
121
|
+
else
|
|
122
|
+
d += "L" + begInnerX + " " + begInnerY
|
|
123
|
+
|
|
124
|
+
if (config["arc-start-cap"] == 'butt') d += "Z"
|
|
125
|
+
|
|
126
|
+
setAttribute(el, 'd', d)
|
|
127
|
+
})
|
|
127
128
|
}
|
package/src/common/svg/index.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { initText, initCircle, initPath, initRect, initArc } from "./config"
|
|
2
2
|
import { toNode, setAttribute, getAttribute, full, fill, stroke } from "./tool"
|
|
3
3
|
import rotate from "../../rotate"
|
|
4
|
+
import SVGConfigType from '../../../types/SVGConfig'
|
|
5
|
+
|
|
6
|
+
// 属性名向下兼容
|
|
7
|
+
let oldAttrName = {
|
|
8
|
+
"font-size": "fontSize",
|
|
9
|
+
"font-family": "fontFamily",
|
|
10
|
+
"arc-start-cap": "arcStartCap",
|
|
11
|
+
"arc-end-cap": "arcEndCap"
|
|
12
|
+
}
|
|
4
13
|
|
|
5
14
|
class SVG {
|
|
6
15
|
readonly name: string = "SVG"
|
|
@@ -42,12 +51,13 @@ class SVG {
|
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
// 属性设置或获取
|
|
45
|
-
config(params:
|
|
54
|
+
config(params: SVGConfigType) {
|
|
46
55
|
if (typeof params !== 'object') {
|
|
47
|
-
return this.__config[params]
|
|
56
|
+
return this.__config[oldAttrName[params] || params]
|
|
48
57
|
} else {
|
|
49
58
|
for (let key in params) {
|
|
50
|
-
|
|
59
|
+
let _key = oldAttrName[key] || key
|
|
60
|
+
this.__config[_key] = params[key]
|
|
51
61
|
}
|
|
52
62
|
}
|
|
53
63
|
return this
|
package/src/common/svg/tool.ts
CHANGED
|
@@ -1,43 +1,44 @@
|
|
|
1
|
-
import { XLINK_ATTRIBUTE } from "./dictionary"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
_setAttribute(el, "
|
|
32
|
-
_setAttribute(el, "
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
_setAttribute(el, "
|
|
42
|
-
_setAttribute(el, "
|
|
1
|
+
import { XLINK_ATTRIBUTE } from "./dictionary"
|
|
2
|
+
import SVGConfigType from '../../../types/SVGConfig'
|
|
3
|
+
|
|
4
|
+
// 新建节点
|
|
5
|
+
export function toNode(tagname: string) {
|
|
6
|
+
return document.createElementNS('http://www.w3.org/2000/svg', tagname)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// 设置属性
|
|
10
|
+
let _setAttribute = function (el: SVGElement, key: string, value: string | number) {
|
|
11
|
+
|
|
12
|
+
// 需要使用xlink命名空间的xml属性
|
|
13
|
+
if (XLINK_ATTRIBUTE.indexOf(key) > -1) {
|
|
14
|
+
el.setAttributeNS("http://www.w3.org/1999/xlink", 'xlink:' + key, value + "")
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 否则
|
|
18
|
+
else {
|
|
19
|
+
el.setAttribute(key, value + "")
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export let setAttribute = _setAttribute
|
|
23
|
+
|
|
24
|
+
// 获取属性
|
|
25
|
+
export function getAttribute(el: SVGElement, key: string) {
|
|
26
|
+
if (XLINK_ATTRIBUTE.indexOf(key) > -1) key = 'xlink:' + key
|
|
27
|
+
return el.getAttribute(key)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function full(el: SVGElement, config: SVGConfigType) {
|
|
31
|
+
_setAttribute(el, "stroke", config.strokeStyle)
|
|
32
|
+
_setAttribute(el, "fill", config.fillStyle)
|
|
33
|
+
_setAttribute(el, "stroke-dasharray", config.lineDash.join(','))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function fill(el: SVGElement, config: SVGConfigType) {
|
|
37
|
+
_setAttribute(el, "fill", config.fillStyle)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function stroke(el: SVGElement, config: SVGConfigType) {
|
|
41
|
+
_setAttribute(el, "stroke", config.strokeStyle)
|
|
42
|
+
_setAttribute(el, "fill", "none")
|
|
43
|
+
_setAttribute(el, "stroke-dasharray", config.lineDash.join(','))
|
|
43
44
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// 缓冲区分为两种:
|
|
2
|
+
// 1.缓冲区中保存了包含顶点的数据
|
|
3
|
+
// 2.缓冲区保存了包含顶点的索引值
|
|
4
|
+
|
|
5
|
+
// 获取一个新的缓冲区
|
|
6
|
+
// isElement默认false,创建第一种缓冲区,为true创建第二种
|
|
7
|
+
let newBuffer = (painter: WebGLRenderingContext) => {
|
|
8
|
+
return painter.createBuffer()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// 数据写入缓冲区
|
|
12
|
+
// data是一个类型化数组,表示写入的数据
|
|
13
|
+
// usage表示程序如何使用存储在缓冲区的数据
|
|
14
|
+
let writeBuffer = (painter: WebGLRenderingContext, data: ArrayBuffer, isElement: boolean, usage: number) => {
|
|
15
|
+
let TYPE = isElement ? painter.ELEMENT_ARRAY_BUFFER : painter.ARRAY_BUFFER
|
|
16
|
+
painter.bufferData(TYPE, data, usage)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 使用缓冲区数据
|
|
20
|
+
// location指定待分配的attribute变量的存储位置
|
|
21
|
+
// size每个分量个数
|
|
22
|
+
// type数据类型,应该是以下的某个:
|
|
23
|
+
// gl.UNSIGNED_BYTE Uint8Array
|
|
24
|
+
// gl.SHORT Int16Array
|
|
25
|
+
// gl.UNSIGNED_SHORT Uint16Array
|
|
26
|
+
// gl.INT Int32Array
|
|
27
|
+
// gl.UNSIGNED_INT Uint32Array
|
|
28
|
+
// gl.FLOAT Float32Array
|
|
29
|
+
// stride相邻两个数据项的字节数
|
|
30
|
+
// offset数据的起点字节位置
|
|
31
|
+
// normalized是否把非浮点型的数据归一化到[0,1]或[-1,1]区间
|
|
32
|
+
let useBuffer = (painter: WebGLRenderingContext, location: number, size: number, type: number, stride: number, offset: number, normalized: boolean) => {
|
|
33
|
+
|
|
34
|
+
// 把缓冲区对象分配给目标变量
|
|
35
|
+
painter.vertexAttribPointer(location, size, type, normalized, stride, offset)
|
|
36
|
+
|
|
37
|
+
// 连接目标对象和缓冲区对象
|
|
38
|
+
painter.enableVertexAttribArray(location)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
class BufferObject {
|
|
42
|
+
|
|
43
|
+
private __painter: WebGLRenderingContext
|
|
44
|
+
private __isElement: boolean
|
|
45
|
+
|
|
46
|
+
private __buffer: WebGLBuffer
|
|
47
|
+
private __type: number
|
|
48
|
+
private __fsize: number
|
|
49
|
+
|
|
50
|
+
constructor(painter: WebGLRenderingContext, isElement: boolean = false) {
|
|
51
|
+
this.__painter = painter
|
|
52
|
+
this.__isElement = isElement
|
|
53
|
+
|
|
54
|
+
this.__buffer = newBuffer(painter)
|
|
55
|
+
this.__type = isElement ? painter.ELEMENT_ARRAY_BUFFER : painter.ARRAY_BUFFER
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 使用这个缓冲区对象
|
|
59
|
+
// (先于写入和分配)
|
|
60
|
+
use() {
|
|
61
|
+
this.__painter.bindBuffer(this.__type, this.__buffer) // 绑定到目标
|
|
62
|
+
return this
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 写入数据
|
|
66
|
+
write(data: Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array) {
|
|
67
|
+
writeBuffer(this.__painter, data, this.__isElement, this.__painter.STATIC_DRAW)
|
|
68
|
+
this.__fsize = data.BYTES_PER_ELEMENT
|
|
69
|
+
return this
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 分配使用
|
|
73
|
+
// 第2~4位参数分别表示:一个完整数据的长度、一组数据的长度、读取位置偏移
|
|
74
|
+
divide(location: number, size: number, stride: number, offset: number = 0) {
|
|
75
|
+
useBuffer(this.__painter, location, size, this.__painter.FLOAT, stride * this.__fsize, offset * this.__fsize, false)
|
|
76
|
+
return this
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default BufferObject
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import BufferObject from './buffer'
|
|
2
|
+
|
|
3
|
+
import getTexture from './getTexture'
|
|
4
|
+
import getShader from './getShader'
|
|
5
|
+
|
|
6
|
+
interface MeshWorldType {
|
|
7
|
+
matrix: number[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface GlobalWorldType {
|
|
11
|
+
matrix: number[]
|
|
12
|
+
proporion: number[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
import { meshType } from '../../../types/Object3D'
|
|
16
|
+
|
|
17
|
+
export default function (type: string, painter: WebGLRenderingContext, mesh: meshType, meshWorld: MeshWorldType, globalWorld: GlobalWorldType) {
|
|
18
|
+
let shader = getShader(type, painter, mesh)
|
|
19
|
+
|
|
20
|
+
// 点数据写入缓冲区
|
|
21
|
+
new BufferObject(painter).use()
|
|
22
|
+
.write(mesh.geometry.attributes.position.array as Float32Array)
|
|
23
|
+
.divide(painter.getAttribLocation(shader.program, "a_position"), mesh.geometry.attributes.position.itemSize, 3, 0)
|
|
24
|
+
|
|
25
|
+
// 写入矩阵
|
|
26
|
+
painter.uniformMatrix4fv(painter.getUniformLocation(shader.program, "u_matrix_world"), false, globalWorld.matrix)
|
|
27
|
+
painter.uniformMatrix4fv(painter.getUniformLocation(shader.program, "u_matrix_proporion"), false, globalWorld.proporion)
|
|
28
|
+
painter.uniformMatrix4fv(painter.getUniformLocation(shader.program, "u_matrix_mesh"), false, meshWorld.matrix)
|
|
29
|
+
|
|
30
|
+
// 如果有法向量数据
|
|
31
|
+
if (mesh.geometry.attributes.normal) {
|
|
32
|
+
new BufferObject(painter).use()
|
|
33
|
+
.write(mesh.geometry.attributes.normal.array as Float32Array)
|
|
34
|
+
.divide(painter.getAttribLocation(shader.program, "a_normal"), mesh.geometry.attributes.normal.itemSize, 3, 0)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 颜色
|
|
38
|
+
if ("color" in mesh.material) {
|
|
39
|
+
|
|
40
|
+
// 写入颜色
|
|
41
|
+
painter.uniform4f(painter.getUniformLocation(shader.program, "u_color")
|
|
42
|
+
, mesh.material.color.r
|
|
43
|
+
, mesh.material.color.g
|
|
44
|
+
, mesh.material.color.b
|
|
45
|
+
, mesh.material.color.alpha)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 立方纹理
|
|
49
|
+
else if ("cube" in mesh.material) {
|
|
50
|
+
|
|
51
|
+
let size = mesh.material.cube.right.image.value.width
|
|
52
|
+
|
|
53
|
+
getTexture(type, painter, 'cube').useCube([
|
|
54
|
+
mesh.material.cube.right.image.value,
|
|
55
|
+
mesh.material.cube.left.image.value,
|
|
56
|
+
mesh.material.cube.top.image.value,
|
|
57
|
+
mesh.material.cube.bottom.image.value,
|
|
58
|
+
mesh.material.cube.far.image.value,
|
|
59
|
+
mesh.material.cube.near.image.value
|
|
60
|
+
], size, size)
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 二维纹理
|
|
65
|
+
else if ("image" in mesh.material) {
|
|
66
|
+
|
|
67
|
+
painter.uniform1i(painter.getUniformLocation(shader.program, "u_sampler"), 0)
|
|
68
|
+
|
|
69
|
+
new BufferObject(painter).use()
|
|
70
|
+
.write(mesh.geometry.attributes.uv.array as Float32Array)
|
|
71
|
+
.divide(painter.getAttribLocation(shader.program, "a_textcoord"), mesh.geometry.attributes.uv.itemSize, 2, 0)
|
|
72
|
+
|
|
73
|
+
getTexture(type, painter, '2d').useImage(mesh.material.image.value)
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 如果使用了索引
|
|
78
|
+
if (mesh.geometry.index) {
|
|
79
|
+
|
|
80
|
+
// 索引数据
|
|
81
|
+
new BufferObject(painter, true).use()
|
|
82
|
+
.write(mesh.geometry.index.array as Uint8Array)
|
|
83
|
+
|
|
84
|
+
// 绘制
|
|
85
|
+
painter.drawElements(painter[mesh.geometry.type], mesh.geometry.index.count, painter.UNSIGNED_BYTE, 0)
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 否则
|
|
90
|
+
else {
|
|
91
|
+
|
|
92
|
+
// 绘制
|
|
93
|
+
painter.drawArrays(painter[mesh.geometry.type], 0, mesh.geometry.attributes.position.count)
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export default function (painter: WebGLRenderingContext) {
|
|
2
|
+
let width = painter.drawingBufferWidth, height = painter.drawingBufferHeight
|
|
3
|
+
|
|
4
|
+
let pixels = new Uint8Array(
|
|
5
|
+
4 * width * height
|
|
6
|
+
)
|
|
7
|
+
painter.readPixels(
|
|
8
|
+
0,
|
|
9
|
+
0,
|
|
10
|
+
width,
|
|
11
|
+
height,
|
|
12
|
+
painter.RGBA,
|
|
13
|
+
painter.UNSIGNED_BYTE,
|
|
14
|
+
pixels
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
return function (x: number, y: number): string {
|
|
18
|
+
y = height - y
|
|
19
|
+
|
|
20
|
+
let pixelR = pixels[4 * (y * width + x)]
|
|
21
|
+
let pixelG = pixels[4 * (y * width + x) + 1]
|
|
22
|
+
let pixelB = pixels[4 * (y * width + x) + 2]
|
|
23
|
+
let pixelA = pixels[4 * (y * width + x) + 3]
|
|
24
|
+
|
|
25
|
+
return "rgba(" + pixelR + "," + pixelG + "," + pixelB + "," + pixelA + ")"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import ShaderObject from './shader'
|
|
2
|
+
|
|
3
|
+
import { meshType } from '../../../types/Object3D'
|
|
4
|
+
|
|
5
|
+
let shaders = {}
|
|
6
|
+
export default function (type: string, painter: WebGLRenderingContext, mesh: meshType) {
|
|
7
|
+
|
|
8
|
+
let uniqueName = type +
|
|
9
|
+
(mesh.geometry.attributes.normal ? "1" : "0") +
|
|
10
|
+
(mesh.material.image ? "1" : "0") +
|
|
11
|
+
(mesh.material.color ? "1" : "0") +
|
|
12
|
+
(mesh.material.cube ? "1" : "0")
|
|
13
|
+
if (shaders[uniqueName]) return shaders[uniqueName].use()
|
|
14
|
+
|
|
15
|
+
// 顶点着色器
|
|
16
|
+
let vertexShader = `
|
|
17
|
+
attribute vec4 a_position;
|
|
18
|
+
|
|
19
|
+
${mesh.geometry.attributes.normal ? 'attribute vec4 a_normal;varying vec3 v_normal;' : ''}
|
|
20
|
+
|
|
21
|
+
uniform mat4 u_matrix_world;
|
|
22
|
+
uniform mat4 u_matrix_mesh;
|
|
23
|
+
uniform mat4 u_matrix_proporion;
|
|
24
|
+
|
|
25
|
+
${mesh.material.image ? 'attribute vec2 a_textcoord;varying vec2 v_textcoord;' : ''}
|
|
26
|
+
|
|
27
|
+
void main(){
|
|
28
|
+
vec4 temp = u_matrix_proporion * u_matrix_world * u_matrix_mesh * a_position;
|
|
29
|
+
|
|
30
|
+
// 表示眼睛距离vec4(0.0,0.0,1.0)的距离
|
|
31
|
+
float dist = 4.0;
|
|
32
|
+
|
|
33
|
+
// 使用投影直接计算
|
|
34
|
+
gl_Position = vec4((dist + 1.0) * temp.x, (dist + 1.0) * temp.y, dist * (dist + temp.z) + 1.0 - dist * dist, temp.w * 2.0 * (dist + temp.z));
|
|
35
|
+
|
|
36
|
+
${mesh.geometry.attributes.normal ? 'v_normal = normalize(vec3(a_normal));' : ''}
|
|
37
|
+
${mesh.material.image ? 'v_textcoord = a_textcoord;' : ''}
|
|
38
|
+
}
|
|
39
|
+
`
|
|
40
|
+
|
|
41
|
+
// 片段(元)着色器
|
|
42
|
+
let fragmentShader = `
|
|
43
|
+
precision mediump float;
|
|
44
|
+
|
|
45
|
+
${mesh.geometry.attributes.normal ? 'varying vec3 v_normal;' : ''}
|
|
46
|
+
${mesh.material.color ? 'uniform vec4 u_color;' : ''}
|
|
47
|
+
${mesh.material.cube ? 'uniform samplerCube u_texture;' : ''}
|
|
48
|
+
${mesh.material.image ? 'uniform sampler2D u_sampler;varying vec2 v_textcoord;' : ''}
|
|
49
|
+
|
|
50
|
+
void main(){
|
|
51
|
+
${mesh.material.color ? 'gl_FragColor = u_color;' : ''}
|
|
52
|
+
${mesh.material.cube ? 'gl_FragColor = textureCube(u_texture,normalize(v_normal));' : ''}
|
|
53
|
+
${mesh.material.image ? 'gl_FragColor = texture2D(u_sampler,v_textcoord);' : ''}
|
|
54
|
+
}
|
|
55
|
+
`
|
|
56
|
+
|
|
57
|
+
// 启用着色器
|
|
58
|
+
let shader = new ShaderObject(painter).compile(vertexShader, fragmentShader).use()
|
|
59
|
+
|
|
60
|
+
shaders[uniqueName] = shader
|
|
61
|
+
return shader
|
|
62
|
+
}
|