jmgraph 3.2.19 → 3.2.21
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 +311 -6
- package/dist/jmgraph.core.min.js +1 -1
- package/dist/jmgraph.core.min.js.map +1 -1
- package/dist/jmgraph.js +2022 -368
- package/dist/jmgraph.min.js +1 -1
- package/index.js +23 -25
- package/package.json +1 -1
- package/src/core/jmControl.js +199 -30
- package/src/core/jmFilter.js +150 -0
- package/src/core/jmGraph.js +207 -7
- package/src/core/jmLayer.js +142 -0
- package/src/core/jmPath.js +55 -0
- package/src/core/jmUtils.js +46 -37
- package/src/lib/webgl/base.js +10 -36
- package/src/lib/webgl/gradient.js +16 -3
- package/src/lib/webgl/index.js +5 -4
- package/src/lib/webgl/path.js +156 -33
- package/src/shapes/jmEllipse.js +91 -0
- package/src/shapes/jmLabel.js +126 -75
- package/src/shapes/jmPolygon.js +129 -0
- package/src/shapes/jmRect.js +107 -29
- package/src/shapes/jmStar.js +160 -0
- package/example/ball.html +0 -217
- package/example/base.html +0 -112
- package/example/canvas.html +0 -54
- package/example/cell.html +0 -284
- package/example/controls/arc.html +0 -129
- package/example/controls/arrowline.html +0 -78
- package/example/controls/bezier.html +0 -299
- package/example/controls/img.html +0 -97
- package/example/controls/label.html +0 -87
- package/example/controls/line.html +0 -173
- package/example/controls/prismatic.html +0 -63
- package/example/controls/rect.html +0 -64
- package/example/controls/resize.html +0 -112
- package/example/controls/test.html +0 -360
- package/example/es.html +0 -70
- package/example/es5module.html +0 -63
- package/example/heartarc.html +0 -116
- package/example/index.html +0 -47
- package/example/js/require.js +0 -5
- package/example/love/img/bling/bling.tps +0 -265
- package/example/love/img/bling.json +0 -87
- package/example/love/img/bling.tps +0 -295
- package/example/love/img/doc/bling.gif +0 -0
- package/example/love/img/love.json +0 -95
- package/example/love/img/love.tps +0 -315
- package/example/love/img/qq/qq.tps +0 -399
- package/example/love/img/qq.json +0 -242
- package/example/love/index.html +0 -40
- package/example/love/js/game.js +0 -558
- package/example/music.html +0 -211
- package/example/node/test.js +0 -138
- package/example/pdf.html +0 -187
- package/example/progress.html +0 -173
- package/example/pso.html +0 -148
- package/example/sort.html +0 -805
- package/example/tweenjs.html +0 -84
- package/example/webgl.html +0 -278
- package/example/xfj/img/dr_die.gif +0 -0
- package/example/xfj/index.html +0 -332
- package/example/xfj/shake.js +0 -49
- package/example/xfj/testori.html +0 -76
package/README.md
CHANGED
|
@@ -15,7 +15,13 @@
|
|
|
15
15
|
- 🎯 **丰富图形** - 内置矩形、圆形、线条、箭头、贝塞尔曲线等常用图形
|
|
16
16
|
- 🎭 **事件系统** - 完整的鼠标和触摸事件支持
|
|
17
17
|
- 🔧 **可扩展** - 支持自定义图形控件
|
|
18
|
-
- 🌈 **样式丰富** -
|
|
18
|
+
- 🌈 **样式丰富** - 支持渐变、阴影、透明度、滤镜、虚线、混合模式等样式
|
|
19
|
+
- 🖼️ **边框系统** - 完整的 border 支持(宽度/样式/颜色),四角独立圆角
|
|
20
|
+
- ✂️ **裁剪遮罩** - 支持 clipPath 裁剪路径和 mask 遮罩效果
|
|
21
|
+
- 📐 **图层管理** - 支持多图层操作,包括创建、切换、删除图层
|
|
22
|
+
- 🔍 **缩放平移** - 支持画布缩放和平移操作
|
|
23
|
+
- 📤 **导出功能** - 支持导出为 PNG、JPEG 和 SVG 格式
|
|
24
|
+
- 📝 **文本换行** - 支持文本自动换行显示
|
|
19
25
|
|
|
20
26
|
## 📦 安装
|
|
21
27
|
|
|
@@ -41,6 +47,8 @@ yarn add jmgraph
|
|
|
41
47
|
|
|
42
48
|
## 🚀 快速开始
|
|
43
49
|
|
|
50
|
+
> **注意**:`g.createShape()` 创建图形后会**自动添加到当前活动图层**,无需手动调用 `g.children.add()`。若设置了 `autoRefresh: true`(默认值),画布会自动刷新,也无需手动调用 `g.redraw()`。
|
|
51
|
+
|
|
44
52
|
### ES6 模块方式
|
|
45
53
|
|
|
46
54
|
```html
|
|
@@ -48,7 +56,7 @@ yarn add jmgraph
|
|
|
48
56
|
import jmGraph from "jmgraph";
|
|
49
57
|
|
|
50
58
|
const container = document.getElementById('mycanvas_container');
|
|
51
|
-
const g =
|
|
59
|
+
const g = jmGraph(container, {
|
|
52
60
|
width: 800,
|
|
53
61
|
height: 600,
|
|
54
62
|
autoRefresh: true,
|
|
@@ -89,13 +97,15 @@ const rect = g.createShape('rect', {
|
|
|
89
97
|
height: 100
|
|
90
98
|
});
|
|
91
99
|
|
|
92
|
-
g.children.add(
|
|
93
|
-
g.redraw()
|
|
100
|
+
// createShape 会自动将图形添加到当前活动图层,无需手动 g.children.add()
|
|
101
|
+
// 如果 autoRefresh 为 true(默认),也不需要手动调用 g.redraw()
|
|
94
102
|
```
|
|
95
103
|
|
|
96
104
|
## 📚 文档
|
|
97
105
|
|
|
98
106
|
- [在线示例](https://fefeding.github.io/jmgraph/example/index.html)
|
|
107
|
+
- [新特性示例](https://fefeding.github.io/jmgraph/example/new-features.html)
|
|
108
|
+
- [样式扩展特性](https://fefeding.github.io/jmgraph/example/style-extension-demo.html)
|
|
99
109
|
- [基于 jmGraph 的图表库](https://github.com/fefeding/jmchart)
|
|
100
110
|
|
|
101
111
|
## 🎨 样式说明
|
|
@@ -121,6 +131,117 @@ jmGraph 支持简化的样式名称和原生 Canvas 样式:
|
|
|
121
131
|
| textBaseline | textBaseline | 文本垂直对齐 |
|
|
122
132
|
| lineJoin | lineJoin | 线条连接样式 |
|
|
123
133
|
| lineCap | lineCap | 线条端点样式 |
|
|
134
|
+
| maxWidth | maxWidth | 文本最大宽度(用于自动换行) |
|
|
135
|
+
| lineDash | - | 自定义虚线模式,数组或字符串格式,如 `[10, 5]` 或 `'10,5'` |
|
|
136
|
+
| lineDashOffset | lineDashOffset | 虚线偏移量 |
|
|
137
|
+
| filter | filter | CSS 滤镜效果,如 `'blur(3px) grayscale(50%)'` 或对象 `{ blur: 3, brightness: 1.2 }` |
|
|
138
|
+
| globalCompositeOperation | globalCompositeOperation | 混合模式,如 `multiply`、`screen`、`overlay` |
|
|
139
|
+
| border | - | 边框系统,对象 `{ width, style, color }` 或字符串 `'2px solid #ff0000'` |
|
|
140
|
+
| clipPath | - | 裁剪路径,传入图形控件实例 |
|
|
141
|
+
| mask | - | 遮罩效果,传入图形控件实例 |
|
|
142
|
+
|
|
143
|
+
### filter 滤镜
|
|
144
|
+
|
|
145
|
+
支持 CSS 标准滤镜,可用值包括:
|
|
146
|
+
|
|
147
|
+
| 滤镜 | 说明 | 示例 |
|
|
148
|
+
| :- | :- | :- |
|
|
149
|
+
| blur | 模糊 | `'blur(3px)'` |
|
|
150
|
+
| grayscale | 灰度 (0-1) | `'grayscale(100%)'` |
|
|
151
|
+
| sepia | 怀旧 (0-1) | `'sepia(80%)'` |
|
|
152
|
+
| brightness | 亮度 (数值) | `'brightness(1.5)'` |
|
|
153
|
+
| contrast | 对比度 (数值) | `'contrast(2)'` |
|
|
154
|
+
| saturate | 饱和度 (数值) | `'saturate(1.5)'` |
|
|
155
|
+
| hue-rotate | 色相旋转 (deg) | `'hue-rotate(90deg)'` |
|
|
156
|
+
| invert | 反转 (0-1) | `'invert(100%)'` |
|
|
157
|
+
| opacity | 不透明度 (0-1) | `'opacity(0.5)'` |
|
|
158
|
+
|
|
159
|
+
支持字符串格式、对象格式或 `jmFilter` 实例:
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
// 字符串格式(多个滤镜组合)
|
|
163
|
+
style: { fill: '#e94560', filter: 'blur(1px) brightness(1.2) saturate(1.5)' }
|
|
164
|
+
|
|
165
|
+
// 对象格式
|
|
166
|
+
style: { fill: '#00d4ff', filter: { blur: 3, grayscale: 0.5 } }
|
|
167
|
+
|
|
168
|
+
// 使用 jmFilter 类
|
|
169
|
+
import { jmFilter } from 'jmgraph';
|
|
170
|
+
const f = new jmFilter({ blur: 2, brightness: 1.3 });
|
|
171
|
+
style: { fill: '#ffd93d', filter: f }
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### lineDash 自定义虚线
|
|
175
|
+
|
|
176
|
+
通过 `lineDash` 定义自定义虚线模式,替代原有的 `lineType: 'dotted'`:
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
// 等间距虚线
|
|
180
|
+
style: { stroke: '#00d4ff', lineWidth: 2, lineDash: [10, 5] }
|
|
181
|
+
|
|
182
|
+
// 字符串格式
|
|
183
|
+
style: { stroke: '#ff6b6b', lineWidth: 2, lineDash: '10, 5, 2, 5' }
|
|
184
|
+
|
|
185
|
+
// 带偏移量
|
|
186
|
+
style: { stroke: '#ffd93d', lineWidth: 2, lineDash: [10, 10], lineDashOffset: 5 }
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
### borderRadius 四角独立圆角
|
|
191
|
+
|
|
192
|
+
`radius` 属性支持数字(四角相同)和对象格式(四角独立):
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
// 统一圆角(向后兼容)
|
|
196
|
+
g.createShape('rect', { position: {x: 20, y: 20}, width: 200, height: 80, radius: 20,
|
|
197
|
+
style: { fill: '#e94560' }
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// 四角独立圆角
|
|
201
|
+
g.createShape('rect', { position: {x: 20, y: 130}, width: 200, height: 80,
|
|
202
|
+
radius: { topLeft: 30, topRight: 5, bottomRight: 30, bottomLeft: 5 },
|
|
203
|
+
style: { fill: '#00d4ff' }
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// 通过 style.borderRadius 设置
|
|
207
|
+
g.createShape('rect', { position: {x: 20, y: 240}, width: 200, height: 80,
|
|
208
|
+
style: { fill: '#00ff88', borderRadius: { topLeft: 40, topRight: 0, bottomRight: 0, bottomLeft: 40 } }
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### globalCompositeOperation 混合模式
|
|
213
|
+
|
|
214
|
+
支持 Canvas 标准混合模式:
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
// multiply 混合
|
|
218
|
+
g.createShape('circle', { center: {x: 120, y: 120}, radius: 60, style: { fill: '#e94560' } });
|
|
219
|
+
g.createShape('circle', { center: {x: 170, y: 120}, radius: 60,
|
|
220
|
+
style: { fill: '#00d4ff', globalCompositeOperation: 'multiply' }
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### clipPath 裁剪路径
|
|
225
|
+
|
|
226
|
+
传入一个图形控件实例作为裁剪区域:
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
// 创建裁剪区域(圆形)
|
|
230
|
+
const clipCircle = g.createShape('circle', {
|
|
231
|
+
center: {x: 300, y: 200}, radius: 80,
|
|
232
|
+
style: { close: true }
|
|
233
|
+
});
|
|
234
|
+
clipCircle.initPoints();
|
|
235
|
+
|
|
236
|
+
// 被裁剪的矩形,只在圆形区域内可见
|
|
237
|
+
g.createShape('rect', {
|
|
238
|
+
position: {x: 180, y: 120}, width: 240, height: 160, radius: 12,
|
|
239
|
+
style: {
|
|
240
|
+
fill: 'linear-gradient(0 0 240 160, #e94560 0, #00d4ff 1)',
|
|
241
|
+
clipPath: clipCircle
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
```
|
|
124
245
|
|
|
125
246
|
## 🎯 内置图形
|
|
126
247
|
|
|
@@ -195,15 +316,50 @@ const label = g.createShape('label', {
|
|
|
195
316
|
textAlign: 'center',
|
|
196
317
|
textBaseline: 'middle',
|
|
197
318
|
fontSize: 24,
|
|
198
|
-
fontFamily: 'Arial'
|
|
319
|
+
fontFamily: 'Arial',
|
|
320
|
+
maxWidth: 200 // 文本最大宽度,超过会自动换行
|
|
199
321
|
},
|
|
200
322
|
position: {x: 200, y: 150},
|
|
201
|
-
text: '
|
|
323
|
+
text: '这是一段测试文本,展示文本换行功能',
|
|
324
|
+
width: 200,
|
|
325
|
+
height: 100
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### 椭圆 (Ellipse)
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
const ellipse = g.createShape('ellipse', {
|
|
333
|
+
style: style,
|
|
334
|
+
center: {x: 100, y: 150},
|
|
202
335
|
width: 120,
|
|
203
336
|
height: 80
|
|
204
337
|
});
|
|
205
338
|
```
|
|
206
339
|
|
|
340
|
+
### 多边形 (Polygon)
|
|
341
|
+
|
|
342
|
+
```javascript
|
|
343
|
+
const polygon = g.createShape('polygon', {
|
|
344
|
+
style: style,
|
|
345
|
+
center: {x: 100, y: 150},
|
|
346
|
+
sides: 6, // 边数
|
|
347
|
+
radius: 50 // 半径
|
|
348
|
+
});
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### 星形 (Star)
|
|
352
|
+
|
|
353
|
+
```javascript
|
|
354
|
+
const star = g.createShape('star', {
|
|
355
|
+
style: style,
|
|
356
|
+
center: {x: 100, y: 150},
|
|
357
|
+
points: 5, // 顶点数
|
|
358
|
+
radius: 50, // 外半径
|
|
359
|
+
innerRadius: 25 // 内半径
|
|
360
|
+
});
|
|
361
|
+
```
|
|
362
|
+
|
|
207
363
|
## 🎮 事件系统
|
|
208
364
|
|
|
209
365
|
### 事件绑定
|
|
@@ -287,6 +443,155 @@ this.canvastouchend = function (...arg) {
|
|
|
287
443
|
}
|
|
288
444
|
```
|
|
289
445
|
|
|
446
|
+
## 🔍 缩放平移功能
|
|
447
|
+
|
|
448
|
+
### 设置缩放
|
|
449
|
+
|
|
450
|
+
```javascript
|
|
451
|
+
// 设置缩放因子,以指定点为中心
|
|
452
|
+
// 缩放因子,1为原始大小
|
|
453
|
+
// x, y 缩放中心坐标
|
|
454
|
+
g.setZoom(1.5, 400, 300);
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### 平移画布
|
|
458
|
+
|
|
459
|
+
```javascript
|
|
460
|
+
// 平移画布
|
|
461
|
+
// dx, dy 平移距离
|
|
462
|
+
g.pan(100, 50);
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### 重置视图
|
|
466
|
+
|
|
467
|
+
```javascript
|
|
468
|
+
// 重置缩放和平移
|
|
469
|
+
g.resetTransform();
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## 📐 图层管理
|
|
473
|
+
|
|
474
|
+
### 创建图层
|
|
475
|
+
|
|
476
|
+
```javascript
|
|
477
|
+
// 创建新图层
|
|
478
|
+
// name 图层名称
|
|
479
|
+
// options 图层选项
|
|
480
|
+
const layer = g.createLayer('My Layer', {
|
|
481
|
+
visible: true,
|
|
482
|
+
locked: false
|
|
483
|
+
});
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### 切换图层
|
|
487
|
+
|
|
488
|
+
```javascript
|
|
489
|
+
// 切换到指定图层
|
|
490
|
+
// layer 图层名称或图层对象
|
|
491
|
+
g.setActiveLayer('My Layer');
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### 获取图层
|
|
495
|
+
|
|
496
|
+
```javascript
|
|
497
|
+
// 获取所有图层
|
|
498
|
+
const layers = g.getLayers();
|
|
499
|
+
|
|
500
|
+
// 获取指定名称的图层
|
|
501
|
+
const layer = g.getLayer('My Layer');
|
|
502
|
+
|
|
503
|
+
// 获取当前活动图层
|
|
504
|
+
const activeLayer = g.getActiveLayer();
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### 移除图层
|
|
508
|
+
|
|
509
|
+
```javascript
|
|
510
|
+
// 移除指定图层
|
|
511
|
+
// layer 图层名称或图层对象
|
|
512
|
+
const success = g.removeLayer('My Layer');
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### 图层操作
|
|
516
|
+
|
|
517
|
+
```javascript
|
|
518
|
+
// 将形状添加到指定图层
|
|
519
|
+
// shape 形状对象
|
|
520
|
+
// layer 图层名称或图层对象,默认为当前活动图层
|
|
521
|
+
g.addShapeToLayer(shape, 'My Layer');
|
|
522
|
+
|
|
523
|
+
// 从图层中移除形状
|
|
524
|
+
// shape 形状对象
|
|
525
|
+
g.removeShapeFromLayer(shape);
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## 📤 导出功能
|
|
529
|
+
|
|
530
|
+
### 导出为 PNG
|
|
531
|
+
|
|
532
|
+
```javascript
|
|
533
|
+
// 导出为 PNG 图片
|
|
534
|
+
// fileName 文件名
|
|
535
|
+
// format 图片格式,默认为 image/png
|
|
536
|
+
// quality 图片质量,0-1之间
|
|
537
|
+
g.exportToPNG('my-graph', 'image/png', 0.9);
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### 导出为 JPEG
|
|
541
|
+
|
|
542
|
+
```javascript
|
|
543
|
+
// 导出为 JPEG 图片
|
|
544
|
+
// fileName 文件名
|
|
545
|
+
// quality 图片质量,0-1之间
|
|
546
|
+
g.exportToJPEG('my-graph', 0.8);
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### 导出为 SVG
|
|
550
|
+
|
|
551
|
+
```javascript
|
|
552
|
+
// 导出为 SVG
|
|
553
|
+
// fileName 文件名
|
|
554
|
+
g.exportToSVG('my-graph');
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
## 🗑️ 销毁实例
|
|
558
|
+
|
|
559
|
+
当不再需要 jmGraph 实例时,调用 `destroy()` 释放资源(如事件监听、动画帧等):
|
|
560
|
+
|
|
561
|
+
```javascript
|
|
562
|
+
const g = jmGraph('mycanvas', { ... });
|
|
563
|
+
|
|
564
|
+
// 使用完毕后销毁
|
|
565
|
+
g.destroy();
|
|
566
|
+
|
|
567
|
+
// 销毁后可通过 destroyed 标志判断状态
|
|
568
|
+
if (g.destroyed) {
|
|
569
|
+
console.log('实例已销毁');
|
|
570
|
+
}
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
> `destroy()` 会内部调用 `eventHandler.destroy()` 清除所有事件绑定,并设置 `destroyed = true` 标记。调用后不应再使用该实例。
|
|
574
|
+
|
|
575
|
+
## 📝 文本换行
|
|
576
|
+
|
|
577
|
+
当文本长度超过 `maxWidth` 时,会自动换行显示:
|
|
578
|
+
|
|
579
|
+
```javascript
|
|
580
|
+
const label = g.createShape('label', {
|
|
581
|
+
style: {
|
|
582
|
+
fill: '#333',
|
|
583
|
+
fontSize: 14,
|
|
584
|
+
fontFamily: 'Arial',
|
|
585
|
+
textAlign: 'center',
|
|
586
|
+
maxWidth: 200 // 文本最大宽度,超过会自动换行
|
|
587
|
+
},
|
|
588
|
+
position: {x: 200, y: 150},
|
|
589
|
+
text: '这是一段测试文本,当文本长度超过最大宽度时,会自动换行显示。',
|
|
590
|
+
width: 200,
|
|
591
|
+
height: 100
|
|
592
|
+
});
|
|
593
|
+
```
|
|
594
|
+
|
|
290
595
|
## 🛠️ 开发
|
|
291
596
|
|
|
292
597
|
### 构建
|