jmgraph 3.2.6 → 3.2.8
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 +0 -1
- package/build/gulpfile.js +143 -0
- package/build/package-lock.json +19282 -0
- package/build/package.json +71 -0
- package/dist/jmgraph.core.min.js +1 -1
- package/dist/jmgraph.core.min.js.map +1 -1
- package/dist/jmgraph.js +2865 -331
- package/dist/jmgraph.min.js +1 -1
- package/example/ball.html +217 -0
- package/example/base.html +112 -0
- package/example/canvas.html +54 -0
- package/example/cell.html +284 -0
- package/example/controls/arc.html +129 -0
- package/example/controls/arrowline.html +78 -0
- package/example/controls/bezier.html +223 -0
- package/example/controls/img.html +97 -0
- package/example/controls/label.html +87 -0
- package/example/controls/line.html +173 -0
- package/example/controls/prismatic.html +63 -0
- package/example/controls/rect.html +64 -0
- package/example/controls/resize.html +112 -0
- package/example/controls/test.html +136 -0
- package/example/es.html +70 -0
- package/example/es5module.html +64 -0
- package/example/heartarc.html +116 -0
- package/example/index.html +47 -0
- package/example/js/require.js +5 -0
- package/example/love/img/bling/bling.tps +265 -0
- package/example/love/img/bling.json +87 -0
- package/example/love/img/bling.tps +295 -0
- package/example/love/img/doc/bling.gif +0 -0
- package/example/love/img/love.json +95 -0
- package/example/love/img/love.tps +315 -0
- package/example/love/img/qq/qq.tps +399 -0
- package/example/love/img/qq.json +242 -0
- package/example/love/index.html +40 -0
- package/example/love/js/game.js +558 -0
- package/example/music.html +211 -0
- package/example/node/test.js +138 -0
- package/example/pdf.html +187 -0
- package/example/progress.html +173 -0
- package/example/pso.html +148 -0
- package/example/sort.html +816 -0
- package/example/tweenjs.html +84 -0
- package/example/webgl.html +278 -0
- package/example/xfj/img/dr_die.gif +0 -0
- package/example/xfj/index.html +332 -0
- package/example/xfj/shake.js +49 -0
- package/example/xfj/testori.html +76 -0
- package/package.json +56 -56
- package/src/core/jmControl.js +127 -97
- package/src/core/jmEvents.js +2 -2
- package/src/core/jmGradient.js +9 -3
- package/src/core/jmGraph.js +16 -24
- package/src/core/jmPath.js +1 -17
- package/src/core/jmUtils.js +6 -0
- package/src/lib/webgl/base.js +253 -1
- package/src/lib/webgl/core/buffer.js +2 -1
- package/src/lib/webgl/core/program.js +2 -2
- package/src/lib/webgl/core/texture.js +8 -8
- package/src/lib/webgl/gradient.js +11 -38
- package/src/lib/webgl/path.js +118 -235
- package/src/shapes/jmImage.js +18 -3
- package/src/shapes/jmLabel.js +84 -38
- package/src/shapes/jmRect.js +5 -2
package/src/lib/webgl/path.js
CHANGED
|
@@ -1,84 +1,5 @@
|
|
|
1
1
|
import WebglBase from './base.js';
|
|
2
2
|
|
|
3
|
-
// 把canvas坐标转为webgl坐标系
|
|
4
|
-
const convertPointSource = `
|
|
5
|
-
vec4 translatePosition(vec4 point, float x, float y) {
|
|
6
|
-
point.x = (point.x-x)/x;
|
|
7
|
-
point.y = (y-point.y)/y;
|
|
8
|
-
return point;
|
|
9
|
-
}`;
|
|
10
|
-
// 把纹理的canvas坐标转为纹理的坐标系
|
|
11
|
-
const convertTexturePosition = `
|
|
12
|
-
vec2 translateTexturePosition(in vec2 point, vec4 bounds) {
|
|
13
|
-
point.x = (point.x-bounds.x)/bounds.z; // 离左上角位置的X长比上纹理宽 0-1
|
|
14
|
-
point.y = 1.0-(point.y-bounds.y)/bounds.w; // 离左上角位置的Y长比上高,因为纹理坐标是左下角起,所以要用1-
|
|
15
|
-
return point;
|
|
16
|
-
}`;
|
|
17
|
-
|
|
18
|
-
// path顶点着色器源码
|
|
19
|
-
const pathVertexSource = `
|
|
20
|
-
attribute vec4 a_position;
|
|
21
|
-
attribute vec4 a_color;
|
|
22
|
-
attribute vec2 a_text_coord;
|
|
23
|
-
uniform vec2 a_center_point; // 当前canvas的中心位置
|
|
24
|
-
uniform float a_point_size; // 点的大小
|
|
25
|
-
uniform int a_type;
|
|
26
|
-
varying vec4 v_color;
|
|
27
|
-
varying vec2 v_text_coord;
|
|
28
|
-
varying float v_type;
|
|
29
|
-
|
|
30
|
-
${convertPointSource}
|
|
31
|
-
|
|
32
|
-
void main() {
|
|
33
|
-
gl_PointSize = a_point_size == 0.0? 1.0 : a_point_size;
|
|
34
|
-
v_type = float(a_type);
|
|
35
|
-
vec4 pos = translatePosition(a_position, a_center_point.x, a_center_point.y);
|
|
36
|
-
gl_Position = pos;
|
|
37
|
-
v_color = a_color;
|
|
38
|
-
if(a_type == 2) {
|
|
39
|
-
v_text_coord = a_text_coord;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
`;
|
|
43
|
-
// path 片段着色器源码
|
|
44
|
-
const pathFragmentSource = `
|
|
45
|
-
precision highp float;
|
|
46
|
-
uniform sampler2D u_sample;
|
|
47
|
-
uniform vec4 v_texture_bounds; // 纹理的左上坐标和大小 x,y,z,w
|
|
48
|
-
uniform vec4 v_single_color;
|
|
49
|
-
varying float v_type;
|
|
50
|
-
varying vec4 v_color;
|
|
51
|
-
varying vec2 v_text_coord;
|
|
52
|
-
|
|
53
|
-
${convertTexturePosition}
|
|
54
|
-
|
|
55
|
-
void main() {
|
|
56
|
-
// 如果是fill,则直接填充颜色
|
|
57
|
-
if(v_type == 1.0) {
|
|
58
|
-
gl_FragColor = v_single_color;
|
|
59
|
-
}
|
|
60
|
-
// 渐变色
|
|
61
|
-
else if(v_type == 3.0) {
|
|
62
|
-
gl_FragColor = v_color;
|
|
63
|
-
}
|
|
64
|
-
else if(v_type == 2.0) {
|
|
65
|
-
vec2 pos = translateTexturePosition(v_text_coord, v_texture_bounds);
|
|
66
|
-
gl_FragColor = texture2D(u_sample, pos);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
float r = distance(gl_PointCoord, vec2(0.5, 0.5));
|
|
70
|
-
//根据距离设置片元
|
|
71
|
-
if(r <= 0.5){
|
|
72
|
-
// 方形区域片元距离几何中心半径小于0.5,像素颜色设置红色
|
|
73
|
-
gl_FragColor = v_single_color;
|
|
74
|
-
}else {
|
|
75
|
-
// 方形区域距离几何中心半径不小于0.5的片元剪裁舍弃掉:
|
|
76
|
-
discard;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
`;
|
|
81
|
-
|
|
82
3
|
// path 绘制类
|
|
83
4
|
class WebglPath extends WebglBase {
|
|
84
5
|
constructor(graph, option) {
|
|
@@ -86,51 +7,10 @@ class WebglPath extends WebglBase {
|
|
|
86
7
|
// 是否是规则的,不规则的处理方式更为复杂和耗性能
|
|
87
8
|
this.isRegular = option.isRegular || false;
|
|
88
9
|
this.needCut = option.needCut || false;
|
|
89
|
-
|
|
10
|
+
this.control = option.control;
|
|
90
11
|
this.points = [];
|
|
91
12
|
}
|
|
92
13
|
|
|
93
|
-
// i当前程序
|
|
94
|
-
get program() {
|
|
95
|
-
// 默认所有path用同一个编译好的program
|
|
96
|
-
return this.graph.context.pathProgram || (this.graph.context.pathProgram=this.createProgram(pathVertexSource, pathFragmentSource));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// 设置样式
|
|
100
|
-
setStyle(style = this.style, value = '') {
|
|
101
|
-
this.useProgram();
|
|
102
|
-
|
|
103
|
-
if(typeof style === 'string') {
|
|
104
|
-
const obj = {};
|
|
105
|
-
obj[style] = value;
|
|
106
|
-
style = obj;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// 设置线条颜色或填充色
|
|
110
|
-
if(style.strokeStyle) {
|
|
111
|
-
let color = style.strokeStyle;
|
|
112
|
-
if(typeof color === 'string') color = this.graph.utils.hexToRGBA(color);
|
|
113
|
-
this.style.strokeStyle = this.graph.utils.rgbToDecimal(color);
|
|
114
|
-
delete style.strokeStyle;
|
|
115
|
-
}
|
|
116
|
-
else if(style.fillStyle) {
|
|
117
|
-
let color = style.fillStyle;
|
|
118
|
-
if(this.isGradient(color)) {
|
|
119
|
-
this.style.fillStyle = color;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
if(typeof color === 'string') color = this.graph.utils.hexToRGBA(color);
|
|
123
|
-
this.style.fillStyle = this.graph.utils.rgbToDecimal(color);
|
|
124
|
-
}
|
|
125
|
-
delete style.fillStyle;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
this.style = {
|
|
129
|
-
...this.style,
|
|
130
|
-
...style
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
14
|
setParentBounds(parentBounds = this.parentAbsoluteBounds) {
|
|
135
15
|
|
|
136
16
|
//this.useProgram();
|
|
@@ -143,7 +23,7 @@ class WebglPath extends WebglBase {
|
|
|
143
23
|
setFragColor(color) {
|
|
144
24
|
|
|
145
25
|
if(!Array.isArray(color)) {
|
|
146
|
-
|
|
26
|
+
color = this.convertColor(color);
|
|
147
27
|
if(typeof color.a === 'undefined') color.a = 1;
|
|
148
28
|
this.context.uniform4f(this.program.uniforms.v_single_color.location, color.r, color.g, color.b, color.a * this.style.globalAlpha);
|
|
149
29
|
return null;
|
|
@@ -151,7 +31,7 @@ class WebglPath extends WebglBase {
|
|
|
151
31
|
|
|
152
32
|
const colorData = [];
|
|
153
33
|
for(let c of color) {
|
|
154
|
-
|
|
34
|
+
c = this.convertColor(c);
|
|
155
35
|
if(typeof c.a === 'undefined') c.a = 1;
|
|
156
36
|
colorData.push(c.r, c.g, c.b, c.a * this.style.globalAlpha);
|
|
157
37
|
}
|
|
@@ -219,8 +99,8 @@ class WebglPath extends WebglBase {
|
|
|
219
99
|
const x = start.x + cos * l;
|
|
220
100
|
const y = start.y + sin * l;
|
|
221
101
|
points.push({
|
|
222
|
-
x
|
|
223
|
-
y
|
|
102
|
+
x,
|
|
103
|
+
y
|
|
224
104
|
});
|
|
225
105
|
}
|
|
226
106
|
}
|
|
@@ -364,8 +244,8 @@ class WebglPath extends WebglBase {
|
|
|
364
244
|
const dy= t * (line1.end.y - line1.start.y);
|
|
365
245
|
|
|
366
246
|
return {
|
|
367
|
-
x:
|
|
368
|
-
y:
|
|
247
|
+
x: line1.start.x + dx,
|
|
248
|
+
y: line1.start.y + dy
|
|
369
249
|
};
|
|
370
250
|
}
|
|
371
251
|
|
|
@@ -481,6 +361,26 @@ class WebglPath extends WebglBase {
|
|
|
481
361
|
return polygons;
|
|
482
362
|
}
|
|
483
363
|
|
|
364
|
+
// 分割成一个个规则的三角形,不规则的多边形不全割的话纹理就会没法正确覆盖
|
|
365
|
+
getTriangles(points) {
|
|
366
|
+
|
|
367
|
+
//this.trianglesCache = this.trianglesCache||(this.trianglesCache={});
|
|
368
|
+
//const key = JSON.stringify(points);
|
|
369
|
+
//if(this.trianglesCache[key]) return this.trianglesCache[key];
|
|
370
|
+
|
|
371
|
+
const res = [];
|
|
372
|
+
const polygons = this.getPolygon(points);
|
|
373
|
+
if(polygons.length) {
|
|
374
|
+
for(const polygon of polygons) {
|
|
375
|
+
// 需要分割三角形,不然填充会有问题
|
|
376
|
+
const triangles = this.earCutPointsToTriangles(polygon);
|
|
377
|
+
res.push(...triangles);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
//this.trianglesCache[key] = res;
|
|
381
|
+
return res;
|
|
382
|
+
}
|
|
383
|
+
|
|
484
384
|
// 画线条
|
|
485
385
|
stroke(points = this.points, color = this.style.strokeStyle, lineWidth = this.style.lineWidth) {
|
|
486
386
|
if(!points || !points.length) return;
|
|
@@ -500,11 +400,10 @@ class WebglPath extends WebglBase {
|
|
|
500
400
|
this.context.uniform1i(this.program.uniforms.a_type.location, points.length === 1? 4 :1);
|
|
501
401
|
}
|
|
502
402
|
if(points && points.length) {
|
|
503
|
-
const regular =
|
|
403
|
+
const regular = lineWidth <= 1.2;
|
|
504
404
|
points = regular? points : this.pathToPoints(points);
|
|
505
|
-
//this.context.lineWidth(10);
|
|
506
405
|
const buffer = this.writePoints(points);
|
|
507
|
-
this.context.drawArrays(regular? this.context.
|
|
406
|
+
this.context.drawArrays(regular? this.context.LINE_LOOP: this.context.POINTS, 0, points.length);
|
|
508
407
|
this.deleteBuffer(buffer);
|
|
509
408
|
}
|
|
510
409
|
colorBuffer && this.deleteBuffer(colorBuffer);
|
|
@@ -513,91 +412,35 @@ class WebglPath extends WebglBase {
|
|
|
513
412
|
|
|
514
413
|
// 填充图形
|
|
515
414
|
fill(bounds = {left: 0, top: 0, width: 0, height: 0}, type = 1) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
if(this.points && this.points.length) {
|
|
519
|
-
|
|
415
|
+
|
|
416
|
+
if(this.points && this.points.length) {
|
|
520
417
|
// 如果是颜色rgba
|
|
521
|
-
if(this.style.fillStyle) {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
if(this.isRegular && this.needCut) {
|
|
527
|
-
// 需要分割三角形,不然填充会有问题
|
|
528
|
-
const triangles = this.earCutPointsToTriangles(this.points);// 切割得到三角形顶点二维数组
|
|
529
|
-
|
|
530
|
-
if(triangles && triangles.length) {
|
|
531
|
-
for(const triangle of triangles) {
|
|
532
|
-
this.fillColor(triangle, this.style.fillStyle, bounds, type); // 单独为每个分割的图形填充
|
|
533
|
-
|
|
534
|
-
// 如果指定的是img,则采用填充图片的方式
|
|
535
|
-
if(this.style.fillImage) {
|
|
536
|
-
this.fillImage(this.style.fillImage, triangle, bounds);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
filled = true;// 表示已填充过了
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
else if(!this.isRegular) {
|
|
543
|
-
const polygons = this.getPolygon(this.points);
|
|
544
|
-
if(polygons.length) {
|
|
545
|
-
for(const polygon of polygons) {
|
|
546
|
-
// 需要分割三角形,不然填充会有问题
|
|
547
|
-
const triangles = this.earCutPointsToTriangles(polygon);// 切割得到三角形顶点二维数组
|
|
548
|
-
|
|
549
|
-
if(triangles && triangles.length) {
|
|
550
|
-
for(const triangle of triangles) {
|
|
551
|
-
this.fillColor(triangle, this.style.fillStyle, bounds, type); // 单独为每个分割的图形填充
|
|
552
|
-
|
|
553
|
-
// 如果指定的是img,则采用填充图片的方式
|
|
554
|
-
if(this.style.fillImage) {
|
|
555
|
-
this.fillImage(this.style.fillImage, triangle, bounds);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
filled = true;// 表示已填充过了
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
// 如果前面的条件没有填充成功,则直接按正常填充
|
|
565
|
-
if(!filled) {
|
|
566
|
-
this.fillColor(this.points, this.style.fillStyle, bounds, type);// 如果指定的是img,则采用填充图片的方式
|
|
567
|
-
if(this.style.fillImage) {
|
|
568
|
-
this.fillImage(this.style.fillImage, this.points, bounds);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
|
|
418
|
+
if(this.style.fillStyle) {
|
|
419
|
+
this.fillColor(this.style.fillStyle, this.points, bounds, type);
|
|
420
|
+
}
|
|
421
|
+
if(this.style.fillImage) {
|
|
422
|
+
this.fillImage(this.style.fillImage, this.points, bounds, type);
|
|
572
423
|
}
|
|
573
424
|
}
|
|
574
425
|
}
|
|
575
426
|
|
|
576
|
-
fillColor(
|
|
427
|
+
fillColor(color, points, bounds, type=1) {
|
|
577
428
|
|
|
578
429
|
// 如果是渐变色,则需要计算偏移量的颜色
|
|
579
430
|
if(this.isGradient(color)) {
|
|
580
|
-
const imgData = color.toImageData(this, bounds);
|
|
581
|
-
return this.fillImage(imgData, points, bounds);
|
|
431
|
+
const imgData = color.toImageData(this, bounds, points);
|
|
432
|
+
return this.fillImage(imgData.data, imgData.points, bounds);
|
|
582
433
|
}
|
|
583
434
|
|
|
584
435
|
// 标注为fill
|
|
585
436
|
this.context.uniform1i(this.program.uniforms.a_type.location, type);
|
|
586
437
|
const colorBuffer = this.setFragColor(color);
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
if(buffer) {
|
|
591
|
-
this.deleteBuffer(buffer);
|
|
592
|
-
this.disableVertexAttribArray(buffer.attr);
|
|
593
|
-
}
|
|
438
|
+
|
|
439
|
+
this.fillPolygons(points);
|
|
440
|
+
|
|
594
441
|
colorBuffer && this.deleteBuffer(colorBuffer);
|
|
595
442
|
colorBuffer && this.disableVertexAttribArray(colorBuffer.attr);
|
|
596
443
|
|
|
597
|
-
// 为线段顶点绘制
|
|
598
|
-
/*for(const p of points) {
|
|
599
|
-
this.stroke([p], 'red', 10);
|
|
600
|
-
}*/
|
|
601
444
|
}
|
|
602
445
|
|
|
603
446
|
// 区域填充图片
|
|
@@ -618,32 +461,44 @@ class WebglPath extends WebglBase {
|
|
|
618
461
|
bounds.height,
|
|
619
462
|
); // 纹理单元传递给着色器
|
|
620
463
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
464
|
+
this.fillTexture(points);
|
|
465
|
+
|
|
466
|
+
this.deleteTexture(texture);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
fillTexture(points) {
|
|
470
|
+
if(points && points.length) { // 标注为纹理对象
|
|
471
|
+
this.context.uniform1i(this.program.uniforms.a_type.location, 2);
|
|
472
|
+
// 纹理坐标
|
|
473
|
+
//const coordBuffer = this.writePoints(points, this.program.attrs.a_text_coord);
|
|
474
|
+
this.fillPolygons(points, true);
|
|
475
|
+
//this.deleteBuffer(coordBuffer);
|
|
476
|
+
this.disableVertexAttribArray(this.program.attrs.a_text_coord);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// 进行多边形填充
|
|
481
|
+
fillPolygons(points, isTexture = false) {
|
|
482
|
+
//const indexBuffer = this.createUint16Buffer(triangles, this.context.ELEMENT_ARRAY_BUFFER);
|
|
483
|
+
//this.context.drawElements(this.context.TRIANGLES, triangles.length, this.context.UNSIGMED_SHORT, 0);
|
|
484
|
+
//this.deleteBuffer(indexBuffer);
|
|
485
|
+
/*if(points.length > 3 && (!regular || this.needCut)) {
|
|
486
|
+
const triangles = regular && this.needCut? this.earCutPointsToTriangles(points): this.getTriangles(points);
|
|
487
|
+
if(triangles.length) {
|
|
488
|
+
for(const triangle of triangles) {
|
|
489
|
+
this.fillPolygons(triangle, isTexture);// 这里就变成了规则的图形了
|
|
639
490
|
}
|
|
640
491
|
}
|
|
641
|
-
}
|
|
642
|
-
// 如果前面的条件没有填充成功,则直接按正常填充
|
|
643
|
-
if(!filled) {
|
|
644
|
-
this.fillTexture(points);
|
|
645
492
|
}
|
|
646
|
-
|
|
493
|
+
else {*/
|
|
494
|
+
const buffer = this.writePoints(points);
|
|
495
|
+
// 纹理坐标
|
|
496
|
+
const coordBuffer = isTexture? this.writePoints(points, this.program.attrs.a_text_coord): null;
|
|
497
|
+
|
|
498
|
+
this.context.drawArrays(this.context.TRIANGLE_FAN, 0, points.length);
|
|
499
|
+
this.deleteBuffer(buffer);
|
|
500
|
+
coordBuffer && this.deleteBuffer(coordBuffer);
|
|
501
|
+
//}
|
|
647
502
|
}
|
|
648
503
|
|
|
649
504
|
// 填充图形
|
|
@@ -651,8 +506,6 @@ class WebglPath extends WebglBase {
|
|
|
651
506
|
width = width || img.width;
|
|
652
507
|
height = height || img.height;
|
|
653
508
|
|
|
654
|
-
//this.useProgram();
|
|
655
|
-
|
|
656
509
|
this.fillImage(img, this.points, {
|
|
657
510
|
left,
|
|
658
511
|
top,
|
|
@@ -661,18 +514,48 @@ class WebglPath extends WebglBase {
|
|
|
661
514
|
});
|
|
662
515
|
}
|
|
663
516
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
517
|
+
drawText(text, x, y, bounds) {
|
|
518
|
+
let canvas = this.textureCanvas;
|
|
519
|
+
if(!canvas) {
|
|
520
|
+
return null;
|
|
521
|
+
}
|
|
522
|
+
canvas.width = bounds.width;
|
|
523
|
+
canvas.height = bounds.height;
|
|
524
|
+
|
|
525
|
+
if(!canvas.width || !canvas.height) {
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
this.textureContext.clearRect(0, 0, canvas.width, canvas.height);
|
|
530
|
+
// 修改字体
|
|
531
|
+
this.textureContext.font = this.style.font || (this.style.fontSize + 'px ' + this.style.fontFamily);
|
|
532
|
+
|
|
533
|
+
x -= bounds.left;
|
|
534
|
+
y -= bounds.top;
|
|
535
|
+
|
|
536
|
+
this.setTextureStyle(this.style);
|
|
537
|
+
|
|
538
|
+
if(this.style.fillStyle && this.textureContext.fillText) {
|
|
539
|
+
|
|
540
|
+
if(this.style.maxWidth) {
|
|
541
|
+
this.textureContext.fillText(text, x, y, this.style.maxWidth);
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
this.textureContext.fillText(text, x, y);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
if(this.textureContext.strokeText) {
|
|
548
|
+
|
|
549
|
+
if(this.style.maxWidth) {
|
|
550
|
+
this.textureContext.strokeText(text, x, y, this.style.maxWidth);
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
this.textureContext.strokeText(text, x, y);
|
|
554
|
+
}
|
|
673
555
|
}
|
|
674
|
-
|
|
675
|
-
this.
|
|
556
|
+
// 用纹理图片代替文字
|
|
557
|
+
const data = this.textureContext.getImageData(0, 0, canvas.width, canvas.height);
|
|
558
|
+
this.fillImage(data, this.points, bounds);
|
|
676
559
|
}
|
|
677
560
|
}
|
|
678
561
|
|
package/src/shapes/jmImage.js
CHANGED
|
@@ -143,7 +143,7 @@ export default class jmImage extends jmControl {
|
|
|
143
143
|
if(sp || typeof sw != 'undefined' || typeof sh != 'undefined') {
|
|
144
144
|
if(typeof sw == 'undefined') sw= p.width || img.width || 0;
|
|
145
145
|
if(typeof sh == 'undefined') sh= p.height || img.height || 0;
|
|
146
|
-
sp = sp || {x:0, y:0};
|
|
146
|
+
sp = sp || {x:0, y:0};
|
|
147
147
|
|
|
148
148
|
if(p.width && p.height) ctx.drawImage(img,sp.x,sp.y,sw,sh,p.left,p.top,p.width,p.height);
|
|
149
149
|
else if(p.width) {
|
|
@@ -171,7 +171,9 @@ export default class jmImage extends jmControl {
|
|
|
171
171
|
* @method getBounds
|
|
172
172
|
* @return {object} 边界对象(left,top,right,bottom,width,height)
|
|
173
173
|
*/
|
|
174
|
-
getBounds() {
|
|
174
|
+
getBounds(isReset) {
|
|
175
|
+
//如果当次计算过,则不重复计算
|
|
176
|
+
if(this.bounds && !isReset) return this.bounds;
|
|
175
177
|
let rect = {};
|
|
176
178
|
let img = this.getImage();
|
|
177
179
|
let p = this.getLocation();
|
|
@@ -183,7 +185,20 @@ export default class jmImage extends jmControl {
|
|
|
183
185
|
rect.bottom = p.top + h;
|
|
184
186
|
rect.width = w;
|
|
185
187
|
rect.height = h;
|
|
186
|
-
return rect;
|
|
188
|
+
return this.bounds=rect;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
getLocation() {
|
|
192
|
+
const img = this.getImage();
|
|
193
|
+
const loc = super.getLocation();
|
|
194
|
+
// 如果指定了宽度,但没有指定高宽,则等比缩放
|
|
195
|
+
if(loc.width && !loc.height) {
|
|
196
|
+
loc.height = loc.width / img.width * img.height;
|
|
197
|
+
}
|
|
198
|
+
else if(loc.height && !loc.width) {
|
|
199
|
+
loc.width = loc.height / img.height * img.width;
|
|
200
|
+
}
|
|
201
|
+
return loc;
|
|
187
202
|
}
|
|
188
203
|
|
|
189
204
|
/**
|
package/src/shapes/jmLabel.js
CHANGED
|
@@ -114,20 +114,25 @@ export default class jmLabel extends jmControl {
|
|
|
114
114
|
*/
|
|
115
115
|
testSize() {
|
|
116
116
|
if(this.__size) return this.__size;
|
|
117
|
-
|
|
118
|
-
this.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
117
|
+
|
|
118
|
+
if(this.webglControl) this.__size = this.webglControl.testSize(this.text, this.style);
|
|
119
|
+
else {
|
|
120
|
+
this.context.save && this.context.save();
|
|
121
|
+
// 修改字体,用来计算
|
|
122
|
+
this.setStyle({
|
|
123
|
+
font: this.style.font || (this.style.fontSize + 'px ' + this.style.fontFamily)
|
|
124
|
+
});
|
|
125
|
+
//计算宽度
|
|
126
|
+
this.__size = this.context.measureText?
|
|
127
|
+
this.context.measureText(this.text):
|
|
128
|
+
{width:15};
|
|
129
|
+
this.context.restore && this.context.restore();
|
|
130
|
+
this.__size.height = this.style.fontSize?this.style.fontSize:15;
|
|
131
|
+
}
|
|
132
|
+
|
|
129
133
|
if(!this.width) this.width = this.__size.width;
|
|
130
134
|
if(!this.height) this.height = this.__size.height;
|
|
135
|
+
|
|
131
136
|
return this.__size;
|
|
132
137
|
}
|
|
133
138
|
|
|
@@ -140,7 +145,7 @@ export default class jmLabel extends jmControl {
|
|
|
140
145
|
|
|
141
146
|
//获取当前控件的绝对位置
|
|
142
147
|
let bounds = this.parent && this.parent.absoluteBounds?this.parent.absoluteBounds:this.absoluteBounds;
|
|
143
|
-
|
|
148
|
+
const size = this.testSize();
|
|
144
149
|
let location = this.location;
|
|
145
150
|
let x = location.left + bounds.left;
|
|
146
151
|
let y = location.top + bounds.top;
|
|
@@ -172,9 +177,14 @@ export default class jmLabel extends jmControl {
|
|
|
172
177
|
|
|
173
178
|
let txt = this.text;
|
|
174
179
|
if(typeof txt !== 'undefined') {
|
|
175
|
-
|
|
180
|
+
// webgl方式
|
|
181
|
+
if(this.webglControl) {
|
|
182
|
+
this.webglControl.draw(this.points, bounds);
|
|
183
|
+
this.webglControl.drawText(txt, x, y, location);
|
|
184
|
+
}
|
|
185
|
+
else if(this.style.fill && this.context.fillText) {
|
|
176
186
|
if(this.style.maxWidth) {
|
|
177
|
-
this.context.fillText(txt,x,y,this.style.maxWidth);
|
|
187
|
+
this.context.fillText(txt,x,y, this.style.maxWidth);
|
|
178
188
|
}
|
|
179
189
|
else {
|
|
180
190
|
this.context.fillText(txt,x,y);
|
|
@@ -182,7 +192,7 @@ export default class jmLabel extends jmControl {
|
|
|
182
192
|
}
|
|
183
193
|
else if(this.context.strokeText) {
|
|
184
194
|
if(this.style.maxWidth) {
|
|
185
|
-
this.context.strokeText(txt,x,y,this.style.maxWidth);
|
|
195
|
+
this.context.strokeText(txt,x,y, this.style.maxWidth);
|
|
186
196
|
}
|
|
187
197
|
else {
|
|
188
198
|
this.context.strokeText(txt,x,y);
|
|
@@ -196,30 +206,66 @@ export default class jmLabel extends jmControl {
|
|
|
196
206
|
this.context.save && this.context.save();
|
|
197
207
|
this.setStyle(this.style.border.style);
|
|
198
208
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
if(this.mode === '2d') {
|
|
210
|
+
this.context.moveTo(this.points[0].x + bounds.left,this.points[0].y + bounds.top);
|
|
211
|
+
if(this.style.border.top) {
|
|
212
|
+
this.context.lineTo(this.points[1].x + bounds.left,this.points[1].y + bounds.top);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if(this.style.border.right) {
|
|
216
|
+
this.context.moveTo(this.points[1].x + bounds.left,this.points[1].y + bounds.top);
|
|
217
|
+
this.context.lineTo(this.points[2].x + bounds.left,this.points[2].y + bounds.top);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if(this.style.border.bottom) {
|
|
221
|
+
this.context.moveTo(this.points[2].x + bounds.left,this.points[2].y + bounds.top);
|
|
222
|
+
this.context.lineTo(this.points[3].x + bounds.left,this.points[3].y + bounds.top);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if(this.style.border.left) {
|
|
226
|
+
this.context.moveTo(this.points[3].x + bounds.left,this.points[3].y + bounds.top);
|
|
227
|
+
this.context.lineTo(this.points[0].x + bounds.left,this.points[0].y + bounds.top);
|
|
228
|
+
}
|
|
212
229
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
230
|
+
else {
|
|
231
|
+
const points = [];
|
|
232
|
+
if(this.style.border.top) {
|
|
233
|
+
points.push(this.points[0]);
|
|
234
|
+
points.push(this.points[1]);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if(this.style.border.right) {
|
|
238
|
+
points.push({
|
|
239
|
+
...this.points[1],
|
|
240
|
+
m: true
|
|
241
|
+
});
|
|
242
|
+
points.push(this.points[2]);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if(this.style.border.bottom) {
|
|
246
|
+
points.push({
|
|
247
|
+
...this.points[2],
|
|
248
|
+
m: true
|
|
249
|
+
});
|
|
250
|
+
points.push(this.points[3]);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if(this.style.border.left) {
|
|
254
|
+
points.push({
|
|
255
|
+
...this.points[3],
|
|
256
|
+
m: true
|
|
257
|
+
});
|
|
258
|
+
points.push(this.points[0]);
|
|
259
|
+
}
|
|
260
|
+
points.length && this.webglControl && this.webglControl.stroke(points);
|
|
217
261
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
endDraw() {
|
|
266
|
+
if(this.mode === '2d') {
|
|
267
|
+
super.endDraw();
|
|
268
|
+
}
|
|
223
269
|
}
|
|
224
270
|
}
|
|
225
271
|
|
package/src/shapes/jmRect.js
CHANGED
|
@@ -51,7 +51,9 @@ export default class jmRect extends jmPath {
|
|
|
51
51
|
* @method getBounds
|
|
52
52
|
* @return {bound} 当前控件边界
|
|
53
53
|
*/
|
|
54
|
-
getBounds() {
|
|
54
|
+
getBounds(isReset) {
|
|
55
|
+
//如果当次计算过,则不重复计算
|
|
56
|
+
if(this.bounds && !isReset) return this.bounds;
|
|
55
57
|
let rect = {};
|
|
56
58
|
this.initPoints();
|
|
57
59
|
let p = this.getLocation();
|
|
@@ -63,7 +65,8 @@ export default class jmRect extends jmPath {
|
|
|
63
65
|
|
|
64
66
|
rect.width = rect.right - rect.left;
|
|
65
67
|
rect.height = rect.bottom - rect.top;
|
|
66
|
-
|
|
68
|
+
|
|
69
|
+
return this.bounds=rect;
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
/**
|