jmgraph 3.2.22 → 3.2.24
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/README.md +1 -0
- package/dist/jmgraph.core.min.js +1 -1
- package/dist/jmgraph.core.min.js.map +1 -1
- package/dist/jmgraph.js +631 -290
- package/dist/jmgraph.min.js +1 -1
- package/index.js +5 -1
- package/package.json +1 -1
- package/src/core/jmGradient.js +4 -2
- package/src/core/jmGraph.js +0 -2
- package/src/lib/webgl/base.js +109 -90
- package/src/lib/webgl/gradient.js +99 -142
- package/src/lib/webgl/index.js +9 -10
- package/src/lib/webgl/path.js +294 -24
- package/src/shapes/jmHArc.js +2 -2
package/index.js
CHANGED
|
@@ -55,10 +55,14 @@ class jmGraphImpl extends jmGraphCore {
|
|
|
55
55
|
if(typeof option == 'function') {
|
|
56
56
|
callback = option;
|
|
57
57
|
option = {};
|
|
58
|
-
|
|
58
|
+
}
|
|
59
59
|
|
|
60
60
|
super(canvas, option, callback);
|
|
61
61
|
}
|
|
62
|
+
|
|
63
|
+
static create(...args) {
|
|
64
|
+
return new jmGraphImpl(...args);
|
|
65
|
+
}
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
//创建实例,支持不加 new 直接调用
|
package/package.json
CHANGED
package/src/core/jmGradient.js
CHANGED
|
@@ -90,7 +90,8 @@ export default class jmGradient {
|
|
|
90
90
|
let sy2 = Number(y2) + bounds.top;
|
|
91
91
|
if(this.type === 'linear') {
|
|
92
92
|
if(control.mode === 'webgl' && control.webglControl) {
|
|
93
|
-
|
|
93
|
+
// WebGL 着色器中 v_text_coord 是绝对坐标,需要传递绝对坐标
|
|
94
|
+
gradient = control.webglControl.createLinearGradient(sx1, sy1, sx2, sy2, bounds);
|
|
94
95
|
gradient.key = this.toString();
|
|
95
96
|
}
|
|
96
97
|
else {
|
|
@@ -109,7 +110,8 @@ export default class jmGradient {
|
|
|
109
110
|
r2 = d * r2;
|
|
110
111
|
}
|
|
111
112
|
if(control.mode === 'webgl' && control.webglControl) {
|
|
112
|
-
|
|
113
|
+
// WebGL 着色器中 v_text_coord 是绝对坐标,需要传递绝对坐标
|
|
114
|
+
gradient = control.webglControl.createRadialGradient(sx1, sy1, r1, sx2, sy2, r2, bounds);
|
|
113
115
|
gradient.key = this.toString();
|
|
114
116
|
}
|
|
115
117
|
//offsetLine = Math.abs(r2 - r1);//二圆半径差
|
package/src/core/jmGraph.js
CHANGED
package/src/lib/webgl/base.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import earcut from '../earcut.js';
|
|
3
|
-
import webglGradient from './gradient.js';
|
|
3
|
+
import webglGradient, { MAX_STOPS } from './gradient.js';
|
|
4
4
|
import {
|
|
5
5
|
createProgram,
|
|
6
6
|
useProgram,
|
|
@@ -56,8 +56,8 @@ const pathVertexSource = `
|
|
|
56
56
|
vec4 pos = translatePosition(a_position, a_center_point.x, a_center_point.y);
|
|
57
57
|
gl_Position = pos;
|
|
58
58
|
v_color = a_color;
|
|
59
|
-
if(a_type == 2) {
|
|
60
|
-
v_text_coord =
|
|
59
|
+
if(a_type == 2 || a_type == 5) {
|
|
60
|
+
v_text_coord = a_position.xy;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
`;
|
|
@@ -67,21 +67,73 @@ const pathFragmentSource = `
|
|
|
67
67
|
uniform sampler2D u_sample;
|
|
68
68
|
uniform vec4 v_texture_bounds; // 纹理的左上坐标和大小 x,y,z,w
|
|
69
69
|
uniform vec4 v_single_color;
|
|
70
|
+
// GLSL 渐变 uniforms
|
|
71
|
+
uniform int u_gradient_type; // 0=无 1=线性 2=径向
|
|
72
|
+
uniform vec4 u_gradient_start; // 线性:{x1,y1,0,0} 径向:{cx,cy,r1,0}
|
|
73
|
+
uniform vec4 u_gradient_end; // 线性:{x2,y2,0,0} 径向:{cx,cy,r2,0}
|
|
74
|
+
uniform int u_gradient_stop_count;
|
|
75
|
+
uniform float u_gradient_offsets[${MAX_STOPS}];
|
|
76
|
+
uniform vec4 u_gradient_colors[${MAX_STOPS}]; // {r, g, b, a} 0~1 范围
|
|
70
77
|
varying float v_type;
|
|
71
78
|
varying vec4 v_color;
|
|
72
79
|
varying vec2 v_text_coord;
|
|
73
80
|
|
|
74
81
|
${convertTexturePosition}
|
|
75
82
|
|
|
83
|
+
// 在 sorted stops 中按 t 值采样颜色
|
|
84
|
+
// 兼容 GLSL ES 1.0:循环仅与常量比较,无 break/continue
|
|
85
|
+
vec4 sampleGradient(float t) {
|
|
86
|
+
t = clamp(t, 0.0, 1.0);
|
|
87
|
+
// 正向扫描:始终遍历 MAX_STOPS-1 次,找到 t 所在段并覆盖结果
|
|
88
|
+
float localT = 0.0;
|
|
89
|
+
vec4 c0 = u_gradient_colors[0];
|
|
90
|
+
vec4 c1 = u_gradient_colors[0];
|
|
91
|
+
for(int i = 0; i < ${MAX_STOPS - 1}; i++) {
|
|
92
|
+
float s0 = u_gradient_offsets[i];
|
|
93
|
+
float s1 = u_gradient_offsets[i + 1];
|
|
94
|
+
if(t >= s0) {
|
|
95
|
+
float range = s1 - s0;
|
|
96
|
+
localT = range > 0.0001 ? clamp((t - s0) / range, 0.0, 1.0) : 0.0;
|
|
97
|
+
c0 = u_gradient_colors[i];
|
|
98
|
+
c1 = u_gradient_colors[i + 1];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return mix(c0, c1, localT);
|
|
102
|
+
}
|
|
103
|
+
|
|
76
104
|
void main() {
|
|
77
105
|
// 如果是fill,则直接填充颜色
|
|
78
106
|
if(v_type == 1.0) {
|
|
79
107
|
gl_FragColor = v_single_color;
|
|
80
108
|
}
|
|
81
|
-
// 渐变色
|
|
109
|
+
// 渐变色 (旧方式,顶点颜色插值)
|
|
82
110
|
else if(v_type == 3.0) {
|
|
83
111
|
gl_FragColor = v_color;
|
|
84
112
|
}
|
|
113
|
+
// GLSL 渐变填充 (type=5)
|
|
114
|
+
else if(v_type == 5.0) {
|
|
115
|
+
float t;
|
|
116
|
+
if(u_gradient_type == 2) {
|
|
117
|
+
// 径向渐变
|
|
118
|
+
vec2 d = v_text_coord - u_gradient_start.xy;
|
|
119
|
+
float dist = length(d);
|
|
120
|
+
float r1 = u_gradient_start.z;
|
|
121
|
+
float r2 = u_gradient_end.z;
|
|
122
|
+
float range = r2 - r1;
|
|
123
|
+
t = range > 0.001 ? (dist - r1) / range : 0.0;
|
|
124
|
+
} else {
|
|
125
|
+
// 线性渐变
|
|
126
|
+
vec2 dir = u_gradient_end.xy - u_gradient_start.xy;
|
|
127
|
+
float lenSq = dot(dir, dir);
|
|
128
|
+
if(lenSq > 0.001) {
|
|
129
|
+
vec2 pos = v_text_coord - u_gradient_start.xy;
|
|
130
|
+
t = dot(pos, dir) / lenSq;
|
|
131
|
+
} else {
|
|
132
|
+
t = 0.0;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
gl_FragColor = sampleGradient(t) * v_single_color.a;
|
|
136
|
+
}
|
|
85
137
|
else if(v_type == 2.0) {
|
|
86
138
|
vec2 pos = translateTexturePosition(v_text_coord, v_texture_bounds);
|
|
87
139
|
gl_FragColor = texture2D(u_sample, pos);
|
|
@@ -152,7 +204,7 @@ class WeblBase {
|
|
|
152
204
|
rotate(angle) {
|
|
153
205
|
const cos = Math.cos(angle);
|
|
154
206
|
const sin = Math.sin(angle);
|
|
155
|
-
const [a, b, c, d
|
|
207
|
+
const [a, b, c, d] = this.transformMatrix;
|
|
156
208
|
|
|
157
209
|
// 更新变换矩阵
|
|
158
210
|
this.transformMatrix[0] = a * cos - b * sin;
|
|
@@ -183,21 +235,20 @@ class WeblBase {
|
|
|
183
235
|
};
|
|
184
236
|
}
|
|
185
237
|
|
|
186
|
-
//
|
|
187
|
-
get
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
238
|
+
// 文本测量用的离屏 canvas context(1x1 单例缓存,不依赖 textureCanvas)
|
|
239
|
+
get _measureCtx() {
|
|
240
|
+
if(!this.__measureCtx) {
|
|
241
|
+
try {
|
|
242
|
+
if(typeof document !== 'undefined') {
|
|
243
|
+
const c = document.createElement('canvas');
|
|
244
|
+
c.width = c.height = 1;
|
|
245
|
+
this.__measureCtx = c.getContext('2d');
|
|
246
|
+
}
|
|
247
|
+
} catch(e) {
|
|
248
|
+
this.__measureCtx = null;
|
|
249
|
+
}
|
|
192
250
|
}
|
|
193
|
-
return
|
|
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;
|
|
251
|
+
return this.__measureCtx;
|
|
201
252
|
}
|
|
202
253
|
|
|
203
254
|
// i当前程序
|
|
@@ -243,23 +294,37 @@ class WeblBase {
|
|
|
243
294
|
// 把传统颜色转为webgl识别的
|
|
244
295
|
convertColor(color) {
|
|
245
296
|
if(this.isGradient(color)) return color;
|
|
246
|
-
if(typeof color === 'string')
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if(['fillStyle', 'strokeStyle', 'shadowColor'].indexOf(style) > -1) {
|
|
254
|
-
value = this.graph.utils.toColor(value);
|
|
297
|
+
if(typeof color === 'string') {
|
|
298
|
+
// 先尝试 hexToRGBA 解析
|
|
299
|
+
color = this.graph.utils.hexToRGBA(color);
|
|
300
|
+
// hexToRGBA 对无法识别的格式(如 hsl)会原样返回字符串
|
|
301
|
+
// 利用离屏 canvas 将任意 CSS 颜色转为 rgba
|
|
302
|
+
if(typeof color === 'string') {
|
|
303
|
+
color = this.__parseCSSColor(color);
|
|
255
304
|
}
|
|
256
|
-
this.textureContext[style] = value;
|
|
257
305
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
306
|
+
if(typeof color === 'object' && color.r !== undefined) {
|
|
307
|
+
return this.graph.utils.rgbToDecimal(color);
|
|
308
|
+
}
|
|
309
|
+
return color;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// 利用离屏 canvas 解析任意 CSS 颜色(hsl/hsla/命名颜色等)
|
|
313
|
+
__parseCSSColor(colorStr) {
|
|
314
|
+
const ctx = this._measureCtx;
|
|
315
|
+
if(!ctx) return { r: 0, g: 0, b: 0, a: 0 };
|
|
316
|
+
try {
|
|
317
|
+
ctx.clearRect(0, 0, 1, 1);
|
|
318
|
+
ctx.fillStyle = '#000000';
|
|
319
|
+
ctx.fillStyle = colorStr;
|
|
320
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
321
|
+
const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data;
|
|
322
|
+
if(ctx.fillStyle === '#000000' && colorStr !== '#000000' && colorStr !== 'black') {
|
|
323
|
+
return { r: 0, g: 0, b: 0, a: 0 };
|
|
262
324
|
}
|
|
325
|
+
return { r, g, b, a: a / 255 };
|
|
326
|
+
} catch(e) {
|
|
327
|
+
return { r: 0, g: 0, b: 0, a: 0 };
|
|
263
328
|
}
|
|
264
329
|
}
|
|
265
330
|
|
|
@@ -434,70 +499,24 @@ class WeblBase {
|
|
|
434
499
|
return obj && obj instanceof webglGradient;
|
|
435
500
|
}
|
|
436
501
|
|
|
437
|
-
|
|
502
|
+
/**
|
|
438
503
|
* 测试获取文本所占大小
|
|
439
504
|
*
|
|
440
505
|
* @method testSize
|
|
441
506
|
* @return {object} 含文本大小的对象
|
|
442
507
|
*/
|
|
443
508
|
testSize(text, style=this.style) {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
{width:15};
|
|
453
|
-
this.textureContext.restore &&this.textureContext.restore();
|
|
454
|
-
size.height = this.style.fontSize? this.style.fontSize: 15;
|
|
509
|
+
const ctx = this._measureCtx;
|
|
510
|
+
if(!ctx) return { width: 15, height: style.fontSize || 15 };
|
|
511
|
+
|
|
512
|
+
ctx.save && ctx.save();
|
|
513
|
+
if(style.font || style.fontSize) ctx.font = style.font || (style.fontSize + 'px ' + style.fontFamily);
|
|
514
|
+
const size = ctx.measureText ? ctx.measureText(text) : { width: 15 };
|
|
515
|
+
ctx.restore && ctx.restore();
|
|
516
|
+
size.height = style.fontSize ? parseInt(style.fontSize) : 15;
|
|
455
517
|
return size;
|
|
456
518
|
}
|
|
457
|
-
|
|
458
|
-
// 使用纹理canvas生成图,
|
|
459
|
-
// 填充可以是颜色或渐变对象
|
|
460
|
-
// 如果指定了points,则表明要绘制不规则的图形
|
|
461
|
-
toFillTexture(fillStyle, bounds, points=null) {
|
|
462
|
-
const canvas = this.textureCanvas;
|
|
463
|
-
if(!canvas) {
|
|
464
|
-
return fillStyle;
|
|
465
|
-
}
|
|
466
|
-
canvas.width = bounds.width;
|
|
467
|
-
canvas.height = bounds.height;
|
|
468
|
-
|
|
469
|
-
if(!canvas.width || !canvas.height) {
|
|
470
|
-
return fillStyle;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
this.textureContext.clearRect(0, 0, canvas.width, canvas.height);
|
|
474
|
-
|
|
475
|
-
this.textureContext.fillStyle = fillStyle;
|
|
476
|
-
|
|
477
|
-
// 规则图形用 fillRect,比 beginPath/lineTo/fill 快
|
|
478
|
-
if(!points || !points.length) {
|
|
479
|
-
this.textureContext.fillRect(0, 0, bounds.width, bounds.height);
|
|
480
|
-
} else {
|
|
481
|
-
this.textureContext.beginPath();
|
|
482
|
-
for(const p of points) {
|
|
483
|
-
//移至当前坐标
|
|
484
|
-
if(p.m) {
|
|
485
|
-
this.textureContext.moveTo(p.x - bounds.left, p.y - bounds.top);
|
|
486
|
-
}
|
|
487
|
-
else {
|
|
488
|
-
this.textureContext.lineTo(p.x - bounds.left, p.y - bounds.top);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
this.textureContext.closePath();
|
|
492
|
-
this.textureContext.fill();
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
const data = this.textureContext.getImageData(0, 0, canvas.width, canvas.height);
|
|
496
|
-
return {
|
|
497
|
-
data,
|
|
498
|
-
points
|
|
499
|
-
};
|
|
500
|
-
}
|
|
501
519
|
}
|
|
502
520
|
|
|
503
|
-
export default WeblBase;
|
|
521
|
+
export default WeblBase;
|
|
522
|
+
export { pathVertexSource, pathFragmentSource, MAX_STOPS };
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
1
|
+
const MAX_STOPS = 16;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* WebGL 渐变对象
|
|
5
|
+
* 支持 GLSL 着色器直接计算渐变色,无需 textureCanvas
|
|
6
|
+
*/
|
|
3
7
|
class WebglGradient {
|
|
4
|
-
|
|
5
|
-
constructor(type='linear', params={}) {
|
|
8
|
+
constructor(type = 'linear', params = {}) {
|
|
6
9
|
this.type = type || 'linear';
|
|
7
10
|
|
|
8
11
|
this.x1 = params.x1 || 0;
|
|
@@ -17,166 +20,120 @@ class WebglGradient {
|
|
|
17
20
|
top: 0,
|
|
18
21
|
width: 0,
|
|
19
22
|
height: 0
|
|
20
|
-
}
|
|
23
|
+
};
|
|
21
24
|
|
|
22
25
|
this.control = params.control;
|
|
23
26
|
|
|
24
27
|
this.stops = [];
|
|
25
|
-
this.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
init() {
|
|
29
|
-
const dx = this.x2 - this.x1;
|
|
30
|
-
const dy = this.y2 - this.y1;
|
|
31
|
-
|
|
32
|
-
if(this.type === 'radial') {
|
|
33
|
-
this.length = this.r2 - this.r1;
|
|
34
|
-
}
|
|
35
|
-
else if(dx === 0 && dy === 0) {
|
|
36
|
-
this.length = 0;
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
// 渐变中心的距离
|
|
40
|
-
this.length = Math.sqrt(Math.pow(dx, 2), Math.pow(dy, 2));
|
|
41
|
-
this.sin = dy / this.length;
|
|
42
|
-
this.cos = dx / this.length;
|
|
43
|
-
}
|
|
28
|
+
this._sortedStops = null;
|
|
29
|
+
this._paramsHash = null;
|
|
44
30
|
}
|
|
45
31
|
|
|
46
|
-
|
|
32
|
+
/**
|
|
33
|
+
* 添加颜色断点
|
|
34
|
+
*/
|
|
47
35
|
addColorStop(offset, color) {
|
|
48
36
|
this.stops.push({
|
|
49
|
-
offset,
|
|
37
|
+
offset: Math.max(0, Math.min(1, offset)),
|
|
50
38
|
color
|
|
51
39
|
});
|
|
40
|
+
this._sortedStops = null;
|
|
41
|
+
this._paramsHash = null;
|
|
52
42
|
}
|
|
53
43
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if(this.
|
|
59
|
-
this.__cachedData.data && this.__cachedData.data.width === Math.ceil(bounds.width) &&
|
|
60
|
-
this.__cachedData.data.data && this.__cachedData.data.data.height === Math.ceil(bounds.height)) {
|
|
61
|
-
return this.__cachedData;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if(!control.textureContext) {
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
let gradient = null;
|
|
68
|
-
if(this.type === 'linear') {
|
|
69
|
-
gradient = control.textureContext.createLinearGradient(this.x1, this.y1, this.x2, this.y2);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
gradient = control.textureContext.createRadialGradient(this.x1, this.y1, this.r1, this.x2, this.y2, this.r2);
|
|
73
|
-
}
|
|
74
|
-
this.stops.forEach(function(s, i) {
|
|
75
|
-
const c = control.graph.utils.toColor(s.color);
|
|
76
|
-
gradient && gradient.addColorStop(s.offset, c);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
const data = control.toFillTexture(gradient, bounds, points);
|
|
44
|
+
/**
|
|
45
|
+
* 获取排序后的 stops(带解析后的颜色)
|
|
46
|
+
*/
|
|
47
|
+
_getSortedStops() {
|
|
48
|
+
if (this._sortedStops) return this._sortedStops;
|
|
80
49
|
|
|
81
|
-
this.
|
|
82
|
-
this.
|
|
50
|
+
const utils = this.control && this.control.graph && this.control.graph.utils;
|
|
51
|
+
this._sortedStops = this.stops
|
|
52
|
+
.map(s => {
|
|
53
|
+
let c = s.color;
|
|
54
|
+
if (utils && typeof c === 'string') {
|
|
55
|
+
c = utils.hexToRGBA(c);
|
|
56
|
+
}
|
|
57
|
+
if (typeof c === 'object' && c !== null) {
|
|
58
|
+
// hexToRGBA 返回 r/g/b 为 0~255,a 为 0~1
|
|
59
|
+
// 但如果已经是 0~1 范围(由 rgbToDecimal 处理过),需要检测
|
|
60
|
+
const needNormalize = (c.r > 1 || c.g > 1 || c.b > 1) ? 255 : 1;
|
|
61
|
+
return {
|
|
62
|
+
offset: s.offset,
|
|
63
|
+
r: (c.r !== undefined ? c.r : 0) / needNormalize,
|
|
64
|
+
g: (c.g !== undefined ? c.g : 0) / needNormalize,
|
|
65
|
+
b: (c.b !== undefined ? c.b : 0) / needNormalize,
|
|
66
|
+
a: c.a !== undefined ? c.a : 1
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return { offset: s.offset, r: 0, g: 0, b: 0, a: 1 };
|
|
70
|
+
})
|
|
71
|
+
.sort((a, b) => a.offset - b.offset);
|
|
83
72
|
|
|
84
|
-
return
|
|
73
|
+
return this._sortedStops;
|
|
85
74
|
}
|
|
86
75
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
/**
|
|
77
|
+
* 将渐变参数以 uniform 形式传递给着色器
|
|
78
|
+
* 返回 { type, start, end, stopCount, stops } 供着色器使用
|
|
79
|
+
*/
|
|
80
|
+
toUniformParams() {
|
|
81
|
+
const stops = this._getSortedStops();
|
|
82
|
+
const count = Math.min(stops.length, MAX_STOPS);
|
|
92
83
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
if(this.type === 'radial') {
|
|
104
|
-
const dx = p.x - this.x1;
|
|
105
|
-
const dy = p.y - this.y1;
|
|
106
|
-
const len = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
|
107
|
-
const rang = this.getStopRange(len, stops);
|
|
108
|
-
if(!rang.start && rang.end) {
|
|
109
|
-
colors.push(rang.end.color);
|
|
110
|
-
}
|
|
111
|
-
else if(!rang.end && rang.start) {
|
|
112
|
-
colors.push(rang.start.color);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
const rangLength = rang.end.length - rang.start.length;
|
|
116
|
-
const offlen = len - rang.start.length;
|
|
117
|
-
const per = offlen / rangLength;
|
|
118
|
-
const color = {
|
|
119
|
-
r: rang.start.color.r + (rang.end.color.r - rang.start.color.r) * per,
|
|
120
|
-
g: rang.start.color.g + (rang.end.color.g - rang.start.color.g) * per,
|
|
121
|
-
b: rang.start.color.b + (rang.end.color.b - rang.start.color.b) * per,
|
|
122
|
-
a: rang.start.color.a + (rang.end.color.a - rang.start.color.a) * per,
|
|
123
|
-
};
|
|
124
|
-
colors.push(color);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
84
|
+
// 展平为 Float32Array: [offset, r, g, b, a, ...]
|
|
85
|
+
const flatStops = new Float32Array(count * 5);
|
|
86
|
+
for (let i = 0; i < count; i++) {
|
|
87
|
+
const s = stops[i];
|
|
88
|
+
flatStops[i * 5 + 0] = s.offset;
|
|
89
|
+
flatStops[i * 5 + 1] = s.r;
|
|
90
|
+
flatStops[i * 5 + 2] = s.g;
|
|
91
|
+
flatStops[i * 5 + 3] = s.b;
|
|
92
|
+
flatStops[i * 5 + 4] = s.a;
|
|
127
93
|
}
|
|
128
|
-
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
gradientType: this.type === 'radial' ? 2 : 1,
|
|
97
|
+
gradientStart: new Float32Array([
|
|
98
|
+
this.x1, this.y1,
|
|
99
|
+
this.type === 'radial' ? Math.max(0, this.r1) : 0,
|
|
100
|
+
0
|
|
101
|
+
]),
|
|
102
|
+
gradientEnd: new Float32Array([
|
|
103
|
+
this.x2, this.y2,
|
|
104
|
+
this.type === 'radial' ? Math.max(0, this.r2) : 0,
|
|
105
|
+
0
|
|
106
|
+
]),
|
|
107
|
+
stopCount: count,
|
|
108
|
+
stops: flatStops
|
|
109
|
+
};
|
|
129
110
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
res.start = s;
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
res.end = s;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return res;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 使缓存失效
|
|
114
|
+
*/
|
|
115
|
+
invalidateCache() {
|
|
116
|
+
this._sortedStops = null;
|
|
117
|
+
this._paramsHash = null;
|
|
144
118
|
}
|
|
145
119
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
s.color = this.control.graph.utils.rgbToDecimal(color);
|
|
154
|
-
s.length = s.offset * this.length;
|
|
120
|
+
/**
|
|
121
|
+
* 转换为渐变的字符串表达
|
|
122
|
+
*/
|
|
123
|
+
toString() {
|
|
124
|
+
let str = this.type + '-gradient(';
|
|
125
|
+
if (this.type == 'linear') {
|
|
126
|
+
str += this.x1 + ' ' + this.y1 + ' ' + this.x2 + ' ' + this.y2;
|
|
155
127
|
}
|
|
156
|
-
|
|
128
|
+
else {
|
|
129
|
+
str += this.x1 + ' ' + this.y1 + ' ' + this.r1 + ' ' + this.x2 + ' ' + this.y2 + ' ' + this.r2;
|
|
130
|
+
}
|
|
131
|
+
this.stops.forEach(function(s) {
|
|
132
|
+
str += ',' + s.color + ' ' + s.offset;
|
|
133
|
+
});
|
|
134
|
+
return str + ')';
|
|
157
135
|
}
|
|
158
|
-
*/
|
|
159
|
-
/**
|
|
160
|
-
* 转换为渐变的字符串表达
|
|
161
|
-
*
|
|
162
|
-
* @method toString
|
|
163
|
-
* @for jmGradient
|
|
164
|
-
* @return {string} linear-gradient(x1 y1 x2 y2, color1 step, color2 step, ...); //radial-gradient(x1 y1 r1 x2 y2 r2, color1 step,color2 step, ...);
|
|
165
|
-
*/
|
|
166
|
-
toString() {
|
|
167
|
-
let str = this.type + '-gradient(';
|
|
168
|
-
if(this.type == 'linear') {
|
|
169
|
-
str += this.x1 + ' ' + this.y1 + ' ' + this.x2 + ' ' + this.y2;
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
str += this.x1 + ' ' + this.y1 + ' ' + this.r1 + ' ' + this.x2 + ' ' + this.y2 + ' ' + this.r2;
|
|
173
|
-
}
|
|
174
|
-
//颜色渐变
|
|
175
|
-
this.stops.forEach(function(s) {
|
|
176
|
-
str += ',' + s.color + ' ' + s.offset;
|
|
177
|
-
});
|
|
178
|
-
return str + ')';
|
|
179
|
-
}
|
|
180
136
|
}
|
|
181
137
|
|
|
182
|
-
export default WebglGradient;
|
|
138
|
+
export default WebglGradient;
|
|
139
|
+
export { MAX_STOPS };
|
package/src/lib/webgl/index.js
CHANGED
|
@@ -105,23 +105,22 @@ class webgl {
|
|
|
105
105
|
// 由具体的绘制方法处理
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
//
|
|
108
|
+
// 测量文本宽度
|
|
109
109
|
measureText(text) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return ctx2.measureText(text);
|
|
110
|
+
if(this.base && this.base._measureCtx) {
|
|
111
|
+
return this.base._measureCtx.measureText(text);
|
|
112
|
+
}
|
|
113
|
+
return { width: 15 };
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
// 创建线性渐变
|
|
118
|
-
createLinearGradient(x1, y1, x2, y2) {
|
|
119
|
-
return this.base.createLinearGradient(x1, y1, x2, y2);
|
|
117
|
+
createLinearGradient(x1, y1, x2, y2, bounds) {
|
|
118
|
+
return this.base.createLinearGradient(x1, y1, x2, y2, bounds);
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
// 创建径向渐变
|
|
123
|
-
createRadialGradient(x1, y1, r1, x2, y2, r2) {
|
|
124
|
-
return this.base.createRadialGradient(x1, y1, r1, x2, y2, r2);
|
|
122
|
+
createRadialGradient(x1, y1, r1, x2, y2, r2, bounds) {
|
|
123
|
+
return this.base.createRadialGradient(x1, y1, r1, x2, y2, r2, bounds);
|
|
125
124
|
}
|
|
126
125
|
|
|
127
126
|
// 绘制图像
|