jmgraph 3.2.16 → 3.2.18
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/LICENSE +21 -21
- package/README.md +251 -428
- package/build/gulpfile.js +142 -142
- package/build/package-lock.json +10666 -0
- package/build/package.json +71 -71
- package/dev.js +9 -9
- package/dist/jmgraph.core.min.js +1 -1
- package/dist/jmgraph.core.min.js.map +1 -1
- package/dist/jmgraph.js +3500 -2668
- package/dist/jmgraph.min.js +1 -1
- package/example/ball.html +216 -216
- package/example/base.html +111 -111
- package/example/canvas.html +53 -53
- package/example/cell.html +283 -283
- package/example/controls/arc.html +128 -128
- package/example/controls/arrowline.html +77 -77
- package/example/controls/bezier.html +298 -298
- package/example/controls/img.html +96 -96
- package/example/controls/label.html +86 -86
- package/example/controls/line.html +172 -172
- package/example/controls/prismatic.html +62 -62
- package/example/controls/rect.html +63 -63
- package/example/controls/resize.html +111 -111
- package/example/controls/test.html +359 -359
- package/example/es.html +69 -69
- package/example/es5module.html +62 -63
- package/example/heartarc.html +115 -115
- package/example/index.html +46 -46
- package/example/js/require.js +4 -4
- package/example/love/img/bling/bling.tps +265 -265
- package/example/love/img/bling.json +87 -87
- package/example/love/img/bling.tps +295 -295
- package/example/love/img/love.json +95 -95
- package/example/love/img/love.tps +315 -315
- package/example/love/img/qq/qq.tps +399 -399
- package/example/love/img/qq.json +242 -242
- package/example/love/index.html +40 -40
- package/example/love/js/game.js +558 -558
- package/example/music.html +210 -210
- package/example/node/test.js +137 -137
- package/example/pdf.html +186 -186
- package/example/progress.html +172 -172
- package/example/pso.html +147 -147
- package/example/sort.html +804 -815
- package/example/tweenjs.html +83 -83
- package/example/webgl.html +278 -278
- package/example/xfj/index.html +331 -331
- package/example/xfj/shake.js +48 -48
- package/example/xfj/testori.html +75 -75
- package/index.js +99 -99
- package/package.json +58 -56
- package/src/core/jmControl.js +1376 -1531
- package/src/core/jmEvents.js +240 -281
- package/src/core/jmGradient.js +231 -231
- package/src/core/jmGraph.js +569 -569
- package/src/core/jmList.js +92 -157
- package/src/core/jmObject.js +83 -103
- package/src/core/jmPath.js +35 -35
- package/src/core/jmProperty.js +71 -110
- package/src/core/jmShadow.js +65 -65
- package/src/core/jmUtils.js +906 -919
- package/src/lib/earcut.js +680 -680
- package/src/lib/earcut.md +73 -73
- package/src/lib/webgl/base.js +522 -452
- package/src/lib/webgl/core/buffer.js +48 -48
- package/src/lib/webgl/core/mapSize.js +40 -40
- package/src/lib/webgl/core/mapType.js +43 -43
- package/src/lib/webgl/core/program.js +138 -138
- package/src/lib/webgl/core/shader.js +13 -13
- package/src/lib/webgl/core/texture.js +60 -60
- package/src/lib/webgl/gradient.js +168 -168
- package/src/lib/webgl/index.js +137 -11
- package/src/lib/webgl/path.js +568 -561
- package/src/shapes/jmArrowLine.js +36 -36
- package/src/shapes/jmImage.js +244 -244
- package/src/shapes/jmLabel.js +271 -271
- package/src/shapes/jmResize.js +332 -330
package/src/lib/webgl/base.js
CHANGED
|
@@ -1,453 +1,523 @@
|
|
|
1
|
-
|
|
2
|
-
import earcut from '../earcut.js';
|
|
3
|
-
import webglGradient from './gradient.js';
|
|
4
|
-
import {
|
|
5
|
-
createProgram,
|
|
6
|
-
useProgram,
|
|
7
|
-
writeVertexAttrib,
|
|
8
|
-
disableVertexAttribArray
|
|
9
|
-
} from './core/program.js';
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
createFloat32Buffer,
|
|
13
|
-
createUint16Buffer,
|
|
14
|
-
deleteBuffer,
|
|
15
|
-
} from './core/buffer.js';
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
create2DTexture,
|
|
19
|
-
createImgTexture,
|
|
20
|
-
createDataTexture,
|
|
21
|
-
deleteTexture
|
|
22
|
-
} from './core/texture.js';
|
|
23
|
-
|
|
24
|
-
// 把canvas坐标转为webgl坐标系
|
|
25
|
-
const convertPointSource = `
|
|
26
|
-
vec4 translatePosition(vec4 point, float x, float y) {
|
|
27
|
-
point.x = (point.x-x)/x;
|
|
28
|
-
point.y = (y-point.y)/y;
|
|
29
|
-
return point;
|
|
30
|
-
}`;
|
|
31
|
-
// 把纹理的canvas坐标转为纹理的坐标系
|
|
32
|
-
const convertTexturePosition = `
|
|
33
|
-
vec2 translateTexturePosition(in vec2 point, vec4 bounds) {
|
|
34
|
-
point.x = (point.x-bounds.x)/bounds.z; // 离左上角位置的X长比上纹理宽 0-1
|
|
35
|
-
point.y = 1.0-(point.y-bounds.y)/bounds.w; // 离左上角位置的Y长比上高,因为纹理坐标是左下角起,所以要用1-
|
|
36
|
-
return point;
|
|
37
|
-
}`;
|
|
38
|
-
|
|
39
|
-
// path顶点着色器源码
|
|
40
|
-
const pathVertexSource = `
|
|
41
|
-
attribute vec4 a_position;
|
|
42
|
-
attribute vec4 a_color;
|
|
43
|
-
attribute vec2 a_text_coord;
|
|
44
|
-
uniform vec2 a_center_point; // 当前canvas的中心位置
|
|
45
|
-
uniform float a_point_size; // 点的大小
|
|
46
|
-
uniform int a_type;
|
|
47
|
-
varying vec4 v_color;
|
|
48
|
-
varying vec2 v_text_coord;
|
|
49
|
-
varying float v_type;
|
|
50
|
-
|
|
51
|
-
${convertPointSource}
|
|
52
|
-
|
|
53
|
-
void main() {
|
|
54
|
-
gl_PointSize = a_point_size == 0.0? 1.0 : a_point_size;
|
|
55
|
-
v_type = float(a_type);
|
|
56
|
-
vec4 pos = translatePosition(a_position, a_center_point.x, a_center_point.y);
|
|
57
|
-
gl_Position = pos;
|
|
58
|
-
v_color = a_color;
|
|
59
|
-
if(a_type == 2) {
|
|
60
|
-
v_text_coord = a_text_coord;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
`;
|
|
64
|
-
// path 片段着色器源码
|
|
65
|
-
const pathFragmentSource = `
|
|
66
|
-
precision mediump float;
|
|
67
|
-
uniform sampler2D u_sample;
|
|
68
|
-
uniform vec4 v_texture_bounds; // 纹理的左上坐标和大小 x,y,z,w
|
|
69
|
-
uniform vec4 v_single_color;
|
|
70
|
-
varying float v_type;
|
|
71
|
-
varying vec4 v_color;
|
|
72
|
-
varying vec2 v_text_coord;
|
|
73
|
-
|
|
74
|
-
${convertTexturePosition}
|
|
75
|
-
|
|
76
|
-
void main() {
|
|
77
|
-
// 如果是fill,则直接填充颜色
|
|
78
|
-
if(v_type == 1.0) {
|
|
79
|
-
gl_FragColor = v_single_color;
|
|
80
|
-
}
|
|
81
|
-
// 渐变色
|
|
82
|
-
else if(v_type == 3.0) {
|
|
83
|
-
gl_FragColor = v_color;
|
|
84
|
-
}
|
|
85
|
-
else if(v_type == 2.0) {
|
|
86
|
-
vec2 pos = translateTexturePosition(v_text_coord, v_texture_bounds);
|
|
87
|
-
gl_FragColor = texture2D(u_sample, pos);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
float r = distance(gl_PointCoord, vec2(0.5, 0.5));
|
|
91
|
-
//根据距离设置片元
|
|
92
|
-
if(r <= 0.5){
|
|
93
|
-
// 方形区域片元距离几何中心半径小于0.5,像素颜色设置红色
|
|
94
|
-
gl_FragColor = v_single_color;
|
|
95
|
-
}else {
|
|
96
|
-
// 方形区域距离几何中心半径不小于0.5的片元剪裁舍弃掉:
|
|
97
|
-
discard;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
`;
|
|
102
|
-
|
|
103
|
-
class WeblBase {
|
|
104
|
-
constructor(graph, option) {
|
|
105
|
-
this.graph = graph;
|
|
106
|
-
this.option = option || {};
|
|
107
|
-
this.style = {
|
|
108
|
-
globalAlpha: 1
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
//
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
1
|
+
|
|
2
|
+
import earcut from '../earcut.js';
|
|
3
|
+
import webglGradient from './gradient.js';
|
|
4
|
+
import {
|
|
5
|
+
createProgram,
|
|
6
|
+
useProgram,
|
|
7
|
+
writeVertexAttrib,
|
|
8
|
+
disableVertexAttribArray
|
|
9
|
+
} from './core/program.js';
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
createFloat32Buffer,
|
|
13
|
+
createUint16Buffer,
|
|
14
|
+
deleteBuffer,
|
|
15
|
+
} from './core/buffer.js';
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
create2DTexture,
|
|
19
|
+
createImgTexture,
|
|
20
|
+
createDataTexture,
|
|
21
|
+
deleteTexture
|
|
22
|
+
} from './core/texture.js';
|
|
23
|
+
|
|
24
|
+
// 把canvas坐标转为webgl坐标系
|
|
25
|
+
const convertPointSource = `
|
|
26
|
+
vec4 translatePosition(vec4 point, float x, float y) {
|
|
27
|
+
point.x = (point.x-x)/x;
|
|
28
|
+
point.y = (y-point.y)/y;
|
|
29
|
+
return point;
|
|
30
|
+
}`;
|
|
31
|
+
// 把纹理的canvas坐标转为纹理的坐标系
|
|
32
|
+
const convertTexturePosition = `
|
|
33
|
+
vec2 translateTexturePosition(in vec2 point, vec4 bounds) {
|
|
34
|
+
point.x = (point.x-bounds.x)/bounds.z; // 离左上角位置的X长比上纹理宽 0-1
|
|
35
|
+
point.y = 1.0-(point.y-bounds.y)/bounds.w; // 离左上角位置的Y长比上高,因为纹理坐标是左下角起,所以要用1-
|
|
36
|
+
return point;
|
|
37
|
+
}`;
|
|
38
|
+
|
|
39
|
+
// path顶点着色器源码
|
|
40
|
+
const pathVertexSource = `
|
|
41
|
+
attribute vec4 a_position;
|
|
42
|
+
attribute vec4 a_color;
|
|
43
|
+
attribute vec2 a_text_coord;
|
|
44
|
+
uniform vec2 a_center_point; // 当前canvas的中心位置
|
|
45
|
+
uniform float a_point_size; // 点的大小
|
|
46
|
+
uniform int a_type;
|
|
47
|
+
varying vec4 v_color;
|
|
48
|
+
varying vec2 v_text_coord;
|
|
49
|
+
varying float v_type;
|
|
50
|
+
|
|
51
|
+
${convertPointSource}
|
|
52
|
+
|
|
53
|
+
void main() {
|
|
54
|
+
gl_PointSize = a_point_size == 0.0? 1.0 : a_point_size;
|
|
55
|
+
v_type = float(a_type);
|
|
56
|
+
vec4 pos = translatePosition(a_position, a_center_point.x, a_center_point.y);
|
|
57
|
+
gl_Position = pos;
|
|
58
|
+
v_color = a_color;
|
|
59
|
+
if(a_type == 2) {
|
|
60
|
+
v_text_coord = a_text_coord;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
64
|
+
// path 片段着色器源码
|
|
65
|
+
const pathFragmentSource = `
|
|
66
|
+
precision mediump float;
|
|
67
|
+
uniform sampler2D u_sample;
|
|
68
|
+
uniform vec4 v_texture_bounds; // 纹理的左上坐标和大小 x,y,z,w
|
|
69
|
+
uniform vec4 v_single_color;
|
|
70
|
+
varying float v_type;
|
|
71
|
+
varying vec4 v_color;
|
|
72
|
+
varying vec2 v_text_coord;
|
|
73
|
+
|
|
74
|
+
${convertTexturePosition}
|
|
75
|
+
|
|
76
|
+
void main() {
|
|
77
|
+
// 如果是fill,则直接填充颜色
|
|
78
|
+
if(v_type == 1.0) {
|
|
79
|
+
gl_FragColor = v_single_color;
|
|
80
|
+
}
|
|
81
|
+
// 渐变色
|
|
82
|
+
else if(v_type == 3.0) {
|
|
83
|
+
gl_FragColor = v_color;
|
|
84
|
+
}
|
|
85
|
+
else if(v_type == 2.0) {
|
|
86
|
+
vec2 pos = translateTexturePosition(v_text_coord, v_texture_bounds);
|
|
87
|
+
gl_FragColor = texture2D(u_sample, pos);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
float r = distance(gl_PointCoord, vec2(0.5, 0.5));
|
|
91
|
+
//根据距离设置片元
|
|
92
|
+
if(r <= 0.5){
|
|
93
|
+
// 方形区域片元距离几何中心半径小于0.5,像素颜色设置红色
|
|
94
|
+
gl_FragColor = v_single_color;
|
|
95
|
+
}else {
|
|
96
|
+
// 方形区域距离几何中心半径不小于0.5的片元剪裁舍弃掉:
|
|
97
|
+
discard;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
|
|
103
|
+
class WeblBase {
|
|
104
|
+
constructor(graph, option) {
|
|
105
|
+
this.graph = graph;
|
|
106
|
+
this.option = option || {};
|
|
107
|
+
this.style = {
|
|
108
|
+
globalAlpha: 1
|
|
109
|
+
};
|
|
110
|
+
this.stateStack = [];
|
|
111
|
+
this.transformMatrix = [1, 0, 0, 1, 0, 0]; // 2D 变换矩阵
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get context() {
|
|
115
|
+
if(this.graph) return this.graph.context;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 保存当前状态
|
|
119
|
+
save() {
|
|
120
|
+
this.stateStack.push({
|
|
121
|
+
transformMatrix: [...this.transformMatrix],
|
|
122
|
+
style: { ...this.style }
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 恢复上一个状态
|
|
127
|
+
restore() {
|
|
128
|
+
if (this.stateStack.length > 0) {
|
|
129
|
+
const state = this.stateStack.pop();
|
|
130
|
+
this.transformMatrix = state.transformMatrix;
|
|
131
|
+
this.style = state.style;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// 平移变换
|
|
136
|
+
translate(x, y) {
|
|
137
|
+
// 更新变换矩阵
|
|
138
|
+
this.transformMatrix[4] += x * this.transformMatrix[0] + y * this.transformMatrix[2];
|
|
139
|
+
this.transformMatrix[5] += x * this.transformMatrix[1] + y * this.transformMatrix[3];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// 缩放变换
|
|
143
|
+
scale(sx, sy) {
|
|
144
|
+
// 更新变换矩阵
|
|
145
|
+
this.transformMatrix[0] *= sx;
|
|
146
|
+
this.transformMatrix[1] *= sx;
|
|
147
|
+
this.transformMatrix[2] *= sy;
|
|
148
|
+
this.transformMatrix[3] *= sy;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 旋转变换
|
|
152
|
+
rotate(angle) {
|
|
153
|
+
const cos = Math.cos(angle);
|
|
154
|
+
const sin = Math.sin(angle);
|
|
155
|
+
const [a, b, c, d, tx, ty] = this.transformMatrix;
|
|
156
|
+
|
|
157
|
+
// 更新变换矩阵
|
|
158
|
+
this.transformMatrix[0] = a * cos - b * sin;
|
|
159
|
+
this.transformMatrix[1] = a * sin + b * cos;
|
|
160
|
+
this.transformMatrix[2] = c * cos - d * sin;
|
|
161
|
+
this.transformMatrix[3] = c * sin + d * cos;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 矩阵变换
|
|
165
|
+
transform(a, b, c, d, e, f) {
|
|
166
|
+
const [currentA, currentB, currentC, currentD, currentE, currentF] = this.transformMatrix;
|
|
167
|
+
|
|
168
|
+
// 矩阵乘法
|
|
169
|
+
this.transformMatrix[0] = a * currentA + b * currentC;
|
|
170
|
+
this.transformMatrix[1] = a * currentB + b * currentD;
|
|
171
|
+
this.transformMatrix[2] = c * currentA + d * currentC;
|
|
172
|
+
this.transformMatrix[3] = c * currentB + d * currentD;
|
|
173
|
+
this.transformMatrix[4] = e * currentA + f * currentC + currentE;
|
|
174
|
+
this.transformMatrix[5] = e * currentB + f * currentD + currentF;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 应用变换到点
|
|
178
|
+
applyTransform(point) {
|
|
179
|
+
const [a, b, c, d, tx, ty] = this.transformMatrix;
|
|
180
|
+
return {
|
|
181
|
+
x: a * point.x + c * point.y + tx,
|
|
182
|
+
y: b * point.x + d * point.y + ty
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// 纹理绘制canvas
|
|
187
|
+
get textureCanvas() {
|
|
188
|
+
let canvas = this.graph.textureCanvas;
|
|
189
|
+
if(!canvas) {
|
|
190
|
+
if(typeof document === 'undefined') return null;
|
|
191
|
+
canvas = this.graph.textureCanvas = document.createElement('canvas');
|
|
192
|
+
}
|
|
193
|
+
return canvas;
|
|
194
|
+
}
|
|
195
|
+
// 纹理绘制canvas ctx
|
|
196
|
+
get textureContext() {
|
|
197
|
+
const ctx = this.textureCanvas.ctx || (this.textureCanvas.ctx = this.textureCanvas.getContext('2d', {
|
|
198
|
+
willReadFrequently: true
|
|
199
|
+
}));
|
|
200
|
+
return ctx;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// i当前程序
|
|
204
|
+
get program() {
|
|
205
|
+
// 默认所有path用同一个编译好的program
|
|
206
|
+
return this.graph.context.pathProgram || (this.graph.context.pathProgram=this.createProgram(pathVertexSource, pathFragmentSource));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// 设置样式
|
|
210
|
+
setStyle(style = this.style, value = '') {
|
|
211
|
+
|
|
212
|
+
if(typeof style === 'string') {
|
|
213
|
+
const obj = {};
|
|
214
|
+
obj[style] = value;
|
|
215
|
+
style = obj;
|
|
216
|
+
}
|
|
217
|
+
/*
|
|
218
|
+
// 设置线条颜色或填充色
|
|
219
|
+
if(style.strokeStyle) {
|
|
220
|
+
let color = style.strokeStyle;
|
|
221
|
+
if(typeof color === 'string') color = this.graph.utils.hexToRGBA(color);
|
|
222
|
+
this.style.strokeStyle = this.graph.utils.rgbToDecimal(color);
|
|
223
|
+
delete style.strokeStyle;
|
|
224
|
+
}
|
|
225
|
+
else if(style.fillStyle) {
|
|
226
|
+
let color = style.fillStyle;
|
|
227
|
+
if(this.isGradient(color)) {
|
|
228
|
+
this.style.fillStyle = color;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
if(typeof color === 'string') color = this.graph.utils.hexToRGBA(color);
|
|
232
|
+
this.style.fillStyle = this.graph.utils.rgbToDecimal(color);
|
|
233
|
+
}
|
|
234
|
+
delete style.fillStyle;
|
|
235
|
+
} */
|
|
236
|
+
|
|
237
|
+
this.style = {
|
|
238
|
+
...this.style,
|
|
239
|
+
...style
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// 把传统颜色转为webgl识别的
|
|
244
|
+
convertColor(color) {
|
|
245
|
+
if(this.isGradient(color)) return color;
|
|
246
|
+
if(typeof color === 'string') color = this.graph.utils.hexToRGBA(color);
|
|
247
|
+
return this.graph.utils.rgbToDecimal(color);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
setTextureStyle(style, value='') {
|
|
251
|
+
|
|
252
|
+
if(typeof style === 'string') {
|
|
253
|
+
if(['fillStyle', 'strokeStyle', 'shadowColor'].indexOf(style) > -1) {
|
|
254
|
+
value = this.graph.utils.toColor(value);
|
|
255
|
+
}
|
|
256
|
+
this.textureContext[style] = value;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
for(const name in style) {
|
|
260
|
+
if(name === 'constructor') continue;
|
|
261
|
+
this.setTextureStyle(name, style[name]);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// 创建程序
|
|
267
|
+
createProgram(vertexSrc, fragmentSrc) {
|
|
268
|
+
this.context.lineWidth(1);
|
|
269
|
+
return createProgram(this.context, vertexSrc, fragmentSrc);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// 指定使用某个程序
|
|
273
|
+
useProgram(program=this.program) {
|
|
274
|
+
program = program.program || program;
|
|
275
|
+
if(this.context.__curent_program === program) return program;
|
|
276
|
+
useProgram(this.context, program.program || program);
|
|
277
|
+
this.context.__curent_program = program;
|
|
278
|
+
return program;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
getAttribLocation(name) {
|
|
282
|
+
return this.context.getAttribLocation(this.program.program, name);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
getUniformLocation(name) {
|
|
286
|
+
return this.context.getUniformLocation(this.program.program, name);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// 把缓冲区的值写入变量
|
|
290
|
+
// buffer: 缓冲区
|
|
291
|
+
// size: 组成数量,必须是1,2,3或4. 每个单元由多少个数组成
|
|
292
|
+
// strip: 步长 数组中一行长度,0 表示数据是紧密的没有空隙,让OpenGL决定具体步长
|
|
293
|
+
// offset: 字节偏移量,必须是类型的字节长度的倍数。
|
|
294
|
+
// dataType: 每个元素的数据类型
|
|
295
|
+
writeVertexAttrib(buffer, attr, size=2, strip=0, offset=0, dataType=this.context.FLOAT) {
|
|
296
|
+
buffer.attr = attr;
|
|
297
|
+
return writeVertexAttrib(this.context, buffer, attr, size, strip, offset, dataType);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// 禁用attri
|
|
301
|
+
disableVertexAttribArray(attr) {
|
|
302
|
+
try{
|
|
303
|
+
if(!attr) return attr;
|
|
304
|
+
return disableVertexAttribArray(this.context, attr);
|
|
305
|
+
}
|
|
306
|
+
catch(e) {
|
|
307
|
+
console.error(e);
|
|
308
|
+
}
|
|
309
|
+
return attr;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// 创建float32的buffer
|
|
313
|
+
createFloat32Buffer(data, type=this.context.ARRAY_BUFFER, drawType=this.context.STATIC_DRAW) {
|
|
314
|
+
const buffer = createFloat32Buffer(this.context, data, type, drawType);
|
|
315
|
+
return {
|
|
316
|
+
data,
|
|
317
|
+
...buffer
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
createUint16Buffer(data, type=this.context.ARRAY_BUFFER, drawType=this.context.STATIC_DRAW) {
|
|
322
|
+
const buffer = createUint16Buffer(this.context, data, type, drawType);
|
|
323
|
+
return {
|
|
324
|
+
data,
|
|
325
|
+
...buffer
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// 释放
|
|
330
|
+
deleteBuffer(buffer) {
|
|
331
|
+
try {
|
|
332
|
+
if(!buffer) return;
|
|
333
|
+
const bufferHandler = buffer.buffer || buffer;
|
|
334
|
+
if(bufferHandler) return deleteBuffer(this.context, bufferHandler);
|
|
335
|
+
}
|
|
336
|
+
catch(e) {
|
|
337
|
+
console.log(buffer);
|
|
338
|
+
console.error(e);
|
|
339
|
+
}
|
|
340
|
+
return buffer;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// 生成纹理
|
|
344
|
+
create2DTexture() {
|
|
345
|
+
return create2DTexture(this.context);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// 创建图片纹理
|
|
349
|
+
createImgTexture(img) {
|
|
350
|
+
return createImgTexture(this.context, img);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// 根根像素值生成纹理
|
|
354
|
+
createDataTexture(data) {
|
|
355
|
+
return createDataTexture(this.context, data);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// 删除纹理
|
|
359
|
+
deleteTexture(texture) {
|
|
360
|
+
try {
|
|
361
|
+
return deleteTexture(this.context, texture.texture || texture);
|
|
362
|
+
}
|
|
363
|
+
catch(e) {
|
|
364
|
+
console.error(e);
|
|
365
|
+
}
|
|
366
|
+
return texture;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// 多边切割, 得到三角形顶点索引数组
|
|
370
|
+
// polygonIndices 顶点索引,
|
|
371
|
+
earCutPoints(points) {
|
|
372
|
+
const arr = this.pointsToArray(points);
|
|
373
|
+
const ps = earcut(arr);// 切割得到3角色顶点索引,
|
|
374
|
+
return ps;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// 多边切割, 得到三角形顶点
|
|
378
|
+
// polygonIndices 顶点索引,
|
|
379
|
+
earCutPointsToTriangles(points) {
|
|
380
|
+
const ps = this.earCutPoints(points);// 切割得到3角色顶点索引,
|
|
381
|
+
const triangles = [];
|
|
382
|
+
// 用顶点索引再组合成坐标数组
|
|
383
|
+
for(let i=0;i<ps.length; i+=3) {
|
|
384
|
+
const p1 = points[ps[i]];
|
|
385
|
+
const p2 = points[ps[i+1]];
|
|
386
|
+
const p3 = points[ps[i+2]];
|
|
387
|
+
|
|
388
|
+
triangles.push([p1, p2, p3]);// 每三个顶点构成一个三角
|
|
389
|
+
}
|
|
390
|
+
return triangles;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// 点坐标数组转为一维数组
|
|
394
|
+
pointsToArray(points) {
|
|
395
|
+
return [].concat(...points.map(p=>[p.x,p.y]));// 把x,y转为数组元素
|
|
396
|
+
}
|
|
397
|
+
// 每2位表示坐标x,y转为坐标点对象
|
|
398
|
+
arrayToPoints(arr) {
|
|
399
|
+
const points = [];
|
|
400
|
+
for(let i=0;i<arr.length; i+=2) {
|
|
401
|
+
points.push({
|
|
402
|
+
x: arr[i],
|
|
403
|
+
y: arr[i+1]
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
return points;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// 创建线性渐变
|
|
410
|
+
createLinearGradient(x1, y1, x2, y2, bounds) {
|
|
411
|
+
return new webglGradient('linear', {
|
|
412
|
+
x1, y1, x2, y2, bounds,
|
|
413
|
+
control: this
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
// 创建放射性渐变
|
|
417
|
+
createRadialGradient(x1, y1, r1, x2, y2, r2, bounds) {
|
|
418
|
+
return new webglGradient('radial', {
|
|
419
|
+
x1, y1, r1,
|
|
420
|
+
x2, y2, r2,
|
|
421
|
+
bounds,
|
|
422
|
+
control: this
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
// 判断是否是一个渐变对象
|
|
426
|
+
isGradient(obj) {
|
|
427
|
+
return obj && obj instanceof webglGradient;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* 测试获取文本所占大小
|
|
432
|
+
*
|
|
433
|
+
* @method testSize
|
|
434
|
+
* @return {object} 含文本大小的对象
|
|
435
|
+
*/
|
|
436
|
+
testSize(text, style=this.style) {
|
|
437
|
+
|
|
438
|
+
this.textureContext.save && this.textureContext.save();
|
|
439
|
+
// 修改字体,用来计算
|
|
440
|
+
if(style.font || style.fontSize) this.textureContext.font = style.font || (style.fontSize + 'px ' + style.fontFamily);
|
|
441
|
+
|
|
442
|
+
//计算宽度
|
|
443
|
+
const size = this.textureContext.measureText?
|
|
444
|
+
this.textureContext.measureText(text):
|
|
445
|
+
{width:15};
|
|
446
|
+
this.textureContext.restore &&this.textureContext.restore();
|
|
447
|
+
size.height = this.style.fontSize? this.style.fontSize: 15;
|
|
448
|
+
return size;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// 使用纹理canvas生成图,
|
|
452
|
+
// 填充可以是颜色或渐变对象
|
|
453
|
+
// 如果指定了points,则表明要绘制不规则的图形
|
|
454
|
+
toFillTexture(fillStyle, bounds, points=null) {
|
|
455
|
+
const canvas = this.textureCanvas;
|
|
456
|
+
if(!canvas) {
|
|
457
|
+
return fillStyle;
|
|
458
|
+
}
|
|
459
|
+
canvas.width = bounds.width;
|
|
460
|
+
canvas.height = bounds.height;
|
|
461
|
+
|
|
462
|
+
if(!canvas.width || !canvas.height) {
|
|
463
|
+
return fillStyle;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
this.textureContext.clearRect(0, 0, canvas.width, canvas.height);
|
|
467
|
+
|
|
468
|
+
this.textureContext.fillStyle = fillStyle;
|
|
469
|
+
|
|
470
|
+
this.textureContext.beginPath();
|
|
471
|
+
if(!points || !points.length) {
|
|
472
|
+
points = [];
|
|
473
|
+
points.push({
|
|
474
|
+
x: bounds.left,
|
|
475
|
+
y: bounds.top
|
|
476
|
+
});
|
|
477
|
+
points.push({
|
|
478
|
+
x: bounds.left + bounds.width,
|
|
479
|
+
y: bounds.top
|
|
480
|
+
});
|
|
481
|
+
points.push({
|
|
482
|
+
x: bounds.left + bounds.width,
|
|
483
|
+
y: bounds.top + bounds.height
|
|
484
|
+
});
|
|
485
|
+
points.push({
|
|
486
|
+
x: bounds.left,
|
|
487
|
+
y: bounds.top + bounds.height
|
|
488
|
+
});
|
|
489
|
+
points.push({
|
|
490
|
+
x: bounds.left,
|
|
491
|
+
y: bounds.top
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
if(points && points.length) {
|
|
495
|
+
for(const p of points) {
|
|
496
|
+
//移至当前坐标
|
|
497
|
+
if(p.m) {
|
|
498
|
+
this.textureContext.moveTo(p.x - bounds.left, p.y - bounds.top);
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
this.textureContext.lineTo(p.x - bounds.left, p.y - bounds.top);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
this.textureContext.moveTo(0, 0);
|
|
507
|
+
this.textureContext.lineTo(bounds.width, 0);
|
|
508
|
+
this.textureContext.lineTo(bounds.width, bounds.height);
|
|
509
|
+
this.textureContext.lineTo(0, bounds.height);
|
|
510
|
+
this.textureContext.lineTo(0, 0);
|
|
511
|
+
}
|
|
512
|
+
this.textureContext.closePath();
|
|
513
|
+
this.textureContext.fill();
|
|
514
|
+
|
|
515
|
+
const data = this.textureContext.getImageData(0, 0, canvas.width, canvas.height);
|
|
516
|
+
return {
|
|
517
|
+
data,
|
|
518
|
+
points
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
453
523
|
export default WeblBase;
|