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.
@@ -15,7 +15,7 @@
15
15
  var g = jmGraph.create('mycanvas', {
16
16
  width: 800,
17
17
  height: 600,
18
- mode: '2d'
18
+ mode: 'webgl'
19
19
  });
20
20
 
21
21
  //实时更新画布
package/example/pso.html CHANGED
@@ -31,7 +31,7 @@
31
31
  width: window.innerWidth,
32
32
  height: window.innerHeight,
33
33
  autoRefresh: true,
34
- mode: '2d'
34
+ mode: 'webgl'
35
35
  });
36
36
 
37
37
  function createItems(count) {
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "family": "jmgraph",
3
3
  "name": "jmgraph",
4
- "version": "3.2.17",
4
+ "version": "3.2.19",
5
5
  "description": "一个简单的canvas画图库",
6
- "homepage": "https://fefeding.github.io/jmgraph/",
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/jiamao/jmgraph.git"
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/jiamao/jmgraph/blob/master/LICENSE"
35
+ "url": "https://github.com/fefeding/jmgraph/blob/master/LICENSE"
36
36
  }
37
37
  ],
38
38
  "bugs": {
39
- "url": "https://github.com/jiamao/jmgraph/issues"
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 & npm i & gulp & cd ..",
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"
@@ -73,7 +73,13 @@ export default class jmGraph extends jmControl {
73
73
  }
74
74
  }
75
75
  this.canvas = canvas;
76
- this.context = canvas.getContext(this.mode);
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
 
@@ -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
 
@@ -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;
@@ -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
- p.x + this.parentAbsoluteBounds.left,
79
- p.y + this.parentAbsoluteBounds.top
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
- //this.trianglesCache = this.trianglesCache||(this.trianglesCache={});
368
- //const key = JSON.stringify(points);
369
- //if(this.trianglesCache[key]) return this.trianglesCache[key];
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
- //this.trianglesCache[key] = res;
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
- //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);
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
  // 填充图形