jmgraph 3.2.17 → 3.2.19
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 -2
- package/dist/jmgraph.core.min.js +1 -1
- package/dist/jmgraph.core.min.js.map +1 -1
- package/dist/jmgraph.js +170 -33
- package/dist/jmgraph.min.js +1 -1
- package/example/progress.html +1 -1
- package/example/pso.html +1 -1
- package/package.json +9 -6
- package/src/core/jmGraph.js +7 -1
- package/src/lib/webgl/base.js +76 -0
- package/src/lib/webgl/index.js +127 -1
- package/src/lib/webgl/path.js +17 -13
package/example/progress.html
CHANGED
package/example/pso.html
CHANGED
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"family": "jmgraph",
|
|
3
3
|
"name": "jmgraph",
|
|
4
|
-
"version": "3.2.
|
|
4
|
+
"version": "3.2.19",
|
|
5
5
|
"description": "一个简单的canvas画图库",
|
|
6
|
-
"homepage": "https://
|
|
6
|
+
"homepage": "https://surl.fit/tools/tools/jmgraph",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"canvas",
|
|
9
9
|
"html5",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
|
-
"url": "git+https://github.com/
|
|
23
|
+
"url": "git+https://github.com/fefeding/jmgraph.git"
|
|
24
24
|
},
|
|
25
25
|
"main": "./index.js",
|
|
26
26
|
"spm": {
|
|
@@ -32,21 +32,24 @@
|
|
|
32
32
|
"licenses": [
|
|
33
33
|
{
|
|
34
34
|
"type": "MIT",
|
|
35
|
-
"url": "https://github.com/
|
|
35
|
+
"url": "https://github.com/fefeding/jmgraph/blob/master/LICENSE"
|
|
36
36
|
}
|
|
37
37
|
],
|
|
38
38
|
"bugs": {
|
|
39
|
-
"url": "https://github.com/
|
|
39
|
+
"url": "https://github.com/fefeding/jmgraph/issues"
|
|
40
40
|
},
|
|
41
41
|
"directories": {
|
|
42
42
|
"example": "example"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
|
-
"build": "cd build
|
|
45
|
+
"build": "cd build && npm i --legacy-peer-deps && npx gulp && cd ..",
|
|
46
46
|
"push": "npm publish --registry=https://registry.npmjs.org",
|
|
47
47
|
"dev": "node dev"
|
|
48
48
|
},
|
|
49
49
|
"license": "MIT",
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"registry": "https://registry.npmjs.org/"
|
|
52
|
+
},
|
|
50
53
|
"config": {
|
|
51
54
|
"commitizen": {
|
|
52
55
|
"path": "./node_modules/cz-conventional-changelog"
|
package/src/core/jmGraph.js
CHANGED
|
@@ -73,7 +73,13 @@ export default class jmGraph extends jmControl {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
this.canvas = canvas;
|
|
76
|
-
|
|
76
|
+
// Create context with preserveDrawingBuffer for webgl to prevent flickering
|
|
77
|
+
if(this.mode === 'webgl') {
|
|
78
|
+
this.context = canvas.getContext(this.mode, { preserveDrawingBuffer: true });
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.context = canvas.getContext(this.mode);
|
|
82
|
+
}
|
|
77
83
|
|
|
78
84
|
this.textureCanvas = option.textureCanvas || null;
|
|
79
85
|
|
package/src/lib/webgl/base.js
CHANGED
|
@@ -107,12 +107,82 @@ class WeblBase {
|
|
|
107
107
|
this.style = {
|
|
108
108
|
globalAlpha: 1
|
|
109
109
|
};
|
|
110
|
+
this.stateStack = [];
|
|
111
|
+
this.transformMatrix = [1, 0, 0, 1, 0, 0]; // 2D 变换矩阵
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
get context() {
|
|
113
115
|
if(this.graph) return this.graph.context;
|
|
114
116
|
}
|
|
115
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
|
+
|
|
116
186
|
// 纹理绘制canvas
|
|
117
187
|
get textureCanvas() {
|
|
118
188
|
let canvas = this.graph.textureCanvas;
|
|
@@ -307,6 +377,10 @@ class WeblBase {
|
|
|
307
377
|
// 多边切割, 得到三角形顶点
|
|
308
378
|
// polygonIndices 顶点索引,
|
|
309
379
|
earCutPointsToTriangles(points) {
|
|
380
|
+
this.earCutCache = this.earCutCache || (this.earCutCache = {});
|
|
381
|
+
const key = JSON.stringify(points);
|
|
382
|
+
if (this.earCutCache[key]) return this.earCutCache[key];
|
|
383
|
+
|
|
310
384
|
const ps = this.earCutPoints(points);// 切割得到3角色顶点索引,
|
|
311
385
|
const triangles = [];
|
|
312
386
|
// 用顶点索引再组合成坐标数组
|
|
@@ -317,6 +391,8 @@ class WeblBase {
|
|
|
317
391
|
|
|
318
392
|
triangles.push([p1, p2, p3]);// 每三个顶点构成一个三角
|
|
319
393
|
}
|
|
394
|
+
|
|
395
|
+
this.earCutCache[key] = triangles;
|
|
320
396
|
return triangles;
|
|
321
397
|
}
|
|
322
398
|
|
package/src/lib/webgl/index.js
CHANGED
|
@@ -3,9 +3,135 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* 采用webgl基础绘图
|
|
5
5
|
*/
|
|
6
|
+
import WebglBase from './base.js';
|
|
7
|
+
import WebglPath from './path.js';
|
|
8
|
+
|
|
6
9
|
class webgl {
|
|
7
10
|
constructor(context, option) {
|
|
8
11
|
this.option = option || {};
|
|
12
|
+
this.context = context;
|
|
13
|
+
this.base = new WebglBase(null, option);
|
|
14
|
+
this.base.context = context;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 保存当前状态
|
|
18
|
+
save() {
|
|
19
|
+
this.base.save();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 恢复上一个状态
|
|
23
|
+
restore() {
|
|
24
|
+
this.base.restore();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 平移变换
|
|
28
|
+
translate(x, y) {
|
|
29
|
+
this.base.translate(x, y);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 缩放变换
|
|
33
|
+
scale(sx, sy) {
|
|
34
|
+
this.base.scale(sx, sy);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 旋转变换
|
|
38
|
+
rotate(angle) {
|
|
39
|
+
this.base.rotate(angle);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 矩阵变换
|
|
43
|
+
transform(a, b, c, d, e, f) {
|
|
44
|
+
this.base.transform(a, b, c, d, e, f);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 开始路径
|
|
48
|
+
beginPath() {
|
|
49
|
+
// WebGL 中不需要 beginPath,由具体的绘制方法处理
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 关闭路径
|
|
53
|
+
closePath() {
|
|
54
|
+
// WebGL 中不需要 closePath,由具体的绘制方法处理
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 移动到指定点
|
|
58
|
+
moveTo(x, y) {
|
|
59
|
+
// WebGL 中不需要 moveTo,由具体的绘制方法处理
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 绘制直线
|
|
63
|
+
lineTo(x, y) {
|
|
64
|
+
// WebGL 中不需要 lineTo,由具体的绘制方法处理
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 填充路径
|
|
68
|
+
fill() {
|
|
69
|
+
// WebGL 中不需要 fill,由具体的绘制方法处理
|
|
70
|
+
}
|
|
9
71
|
|
|
72
|
+
// 描边路径
|
|
73
|
+
stroke() {
|
|
74
|
+
// WebGL 中不需要 stroke,由具体的绘制方法处理
|
|
10
75
|
}
|
|
11
|
-
|
|
76
|
+
|
|
77
|
+
// 清除矩形区域
|
|
78
|
+
clearRect(x, y, width, height) {
|
|
79
|
+
this.context.clearColor(0, 0, 0, 0);
|
|
80
|
+
this.context.clear(this.context.COLOR_BUFFER_BIT);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 设置线条宽度
|
|
84
|
+
lineWidth(width) {
|
|
85
|
+
// 由具体的绘制方法处理
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 设置填充样式
|
|
89
|
+
fillStyle(style) {
|
|
90
|
+
// 由具体的绘制方法处理
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 设置描边样式
|
|
94
|
+
strokeStyle(style) {
|
|
95
|
+
// 由具体的绘制方法处理
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 绘制文本
|
|
99
|
+
fillText(text, x, y, maxWidth) {
|
|
100
|
+
// 由具体的绘制方法处理
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 描边文本
|
|
104
|
+
strokeText(text, x, y, maxWidth) {
|
|
105
|
+
// 由具体的绘制方法处理
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 测量文本宽度
|
|
109
|
+
measureText(text) {
|
|
110
|
+
// 使用 2D canvas 测量
|
|
111
|
+
const canvas = document.createElement('canvas');
|
|
112
|
+
const ctx = canvas.getContext('2d');
|
|
113
|
+
return ctx.measureText(text);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 创建线性渐变
|
|
117
|
+
createLinearGradient(x1, y1, x2, y2) {
|
|
118
|
+
return this.base.createLinearGradient(x1, y1, x2, y2);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 创建径向渐变
|
|
122
|
+
createRadialGradient(x1, y1, r1, x2, y2, r2) {
|
|
123
|
+
return this.base.createRadialGradient(x1, y1, r1, x2, y2, r2);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 绘制图像
|
|
127
|
+
drawImage(img, dx, dy, dWidth, dHeight) {
|
|
128
|
+
// 由具体的绘制方法处理
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 创建 WebglPath 实例
|
|
132
|
+
createPath(option) {
|
|
133
|
+
return new WebglPath(null, option);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default webgl;
|
package/src/lib/webgl/path.js
CHANGED
|
@@ -11,6 +11,11 @@ class WebglPath extends WebglBase {
|
|
|
11
11
|
this.points = [];
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
// 应用变换到点
|
|
15
|
+
applyTransform(point) {
|
|
16
|
+
return super.applyTransform(point);
|
|
17
|
+
}
|
|
18
|
+
|
|
14
19
|
setParentBounds(parentBounds = this.parentAbsoluteBounds) {
|
|
15
20
|
|
|
16
21
|
//this.useProgram();
|
|
@@ -74,9 +79,11 @@ class WebglPath extends WebglBase {
|
|
|
74
79
|
|
|
75
80
|
const fixedPoints = [];
|
|
76
81
|
for(const p of points) {
|
|
82
|
+
// 应用变换矩阵
|
|
83
|
+
const transformedPoint = this.applyTransform(p);
|
|
77
84
|
fixedPoints.push(
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
transformedPoint.x + this.parentAbsoluteBounds.left,
|
|
86
|
+
transformedPoint.y + this.parentAbsoluteBounds.top
|
|
80
87
|
);
|
|
81
88
|
}
|
|
82
89
|
const vertexBuffer = this.createFloat32Buffer(fixedPoints);
|
|
@@ -364,9 +371,9 @@ class WebglPath extends WebglBase {
|
|
|
364
371
|
// 分割成一个个规则的三角形,不规则的多边形不全割的话纹理就会没法正确覆盖
|
|
365
372
|
getTriangles(points) {
|
|
366
373
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
374
|
+
this.trianglesCache = this.trianglesCache||(this.trianglesCache={});
|
|
375
|
+
const key = JSON.stringify(points);
|
|
376
|
+
if(this.trianglesCache[key]) return this.trianglesCache[key];
|
|
370
377
|
|
|
371
378
|
const res = [];
|
|
372
379
|
const polygons = this.getPolygon(points);
|
|
@@ -377,7 +384,7 @@ class WebglPath extends WebglBase {
|
|
|
377
384
|
res.push(...triangles);
|
|
378
385
|
}
|
|
379
386
|
}
|
|
380
|
-
|
|
387
|
+
this.trianglesCache[key] = res;
|
|
381
388
|
return res;
|
|
382
389
|
}
|
|
383
390
|
|
|
@@ -479,18 +486,15 @@ class WebglPath extends WebglBase {
|
|
|
479
486
|
|
|
480
487
|
// 进行多边形填充
|
|
481
488
|
fillPolygons(points, isTexture = false) {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
//this.deleteBuffer(indexBuffer);
|
|
485
|
-
/*if(points.length > 3 && (!regular || this.needCut)) {
|
|
486
|
-
const triangles = regular && this.needCut? this.earCutPointsToTriangles(points): this.getTriangles(points);
|
|
489
|
+
if(points.length > 3) {
|
|
490
|
+
const triangles = this.needCut? this.earCutPointsToTriangles(points): this.getTriangles(points);
|
|
487
491
|
if(triangles.length) {
|
|
488
492
|
for(const triangle of triangles) {
|
|
489
493
|
this.fillPolygons(triangle, isTexture);// 这里就变成了规则的图形了
|
|
490
494
|
}
|
|
491
495
|
}
|
|
492
496
|
}
|
|
493
|
-
else {
|
|
497
|
+
else {
|
|
494
498
|
const buffer = this.writePoints(points);
|
|
495
499
|
// 纹理坐标
|
|
496
500
|
const coordBuffer = isTexture? this.writePoints(points, this.program.attrs.a_text_coord): null;
|
|
@@ -498,7 +502,7 @@ class WebglPath extends WebglBase {
|
|
|
498
502
|
this.context.drawArrays(this.context.TRIANGLE_FAN, 0, points.length);
|
|
499
503
|
this.deleteBuffer(buffer);
|
|
500
504
|
coordBuffer && this.deleteBuffer(coordBuffer);
|
|
501
|
-
|
|
505
|
+
}
|
|
502
506
|
}
|
|
503
507
|
|
|
504
508
|
// 填充图形
|