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.
Files changed (63) hide show
  1. package/README.md +311 -6
  2. package/dist/jmgraph.core.min.js +1 -1
  3. package/dist/jmgraph.core.min.js.map +1 -1
  4. package/dist/jmgraph.js +2022 -368
  5. package/dist/jmgraph.min.js +1 -1
  6. package/index.js +23 -25
  7. package/package.json +1 -1
  8. package/src/core/jmControl.js +199 -30
  9. package/src/core/jmFilter.js +150 -0
  10. package/src/core/jmGraph.js +207 -7
  11. package/src/core/jmLayer.js +142 -0
  12. package/src/core/jmPath.js +55 -0
  13. package/src/core/jmUtils.js +46 -37
  14. package/src/lib/webgl/base.js +10 -36
  15. package/src/lib/webgl/gradient.js +16 -3
  16. package/src/lib/webgl/index.js +5 -4
  17. package/src/lib/webgl/path.js +156 -33
  18. package/src/shapes/jmEllipse.js +91 -0
  19. package/src/shapes/jmLabel.js +126 -75
  20. package/src/shapes/jmPolygon.js +129 -0
  21. package/src/shapes/jmRect.js +107 -29
  22. package/src/shapes/jmStar.js +160 -0
  23. package/example/ball.html +0 -217
  24. package/example/base.html +0 -112
  25. package/example/canvas.html +0 -54
  26. package/example/cell.html +0 -284
  27. package/example/controls/arc.html +0 -129
  28. package/example/controls/arrowline.html +0 -78
  29. package/example/controls/bezier.html +0 -299
  30. package/example/controls/img.html +0 -97
  31. package/example/controls/label.html +0 -87
  32. package/example/controls/line.html +0 -173
  33. package/example/controls/prismatic.html +0 -63
  34. package/example/controls/rect.html +0 -64
  35. package/example/controls/resize.html +0 -112
  36. package/example/controls/test.html +0 -360
  37. package/example/es.html +0 -70
  38. package/example/es5module.html +0 -63
  39. package/example/heartarc.html +0 -116
  40. package/example/index.html +0 -47
  41. package/example/js/require.js +0 -5
  42. package/example/love/img/bling/bling.tps +0 -265
  43. package/example/love/img/bling.json +0 -87
  44. package/example/love/img/bling.tps +0 -295
  45. package/example/love/img/doc/bling.gif +0 -0
  46. package/example/love/img/love.json +0 -95
  47. package/example/love/img/love.tps +0 -315
  48. package/example/love/img/qq/qq.tps +0 -399
  49. package/example/love/img/qq.json +0 -242
  50. package/example/love/index.html +0 -40
  51. package/example/love/js/game.js +0 -558
  52. package/example/music.html +0 -211
  53. package/example/node/test.js +0 -138
  54. package/example/pdf.html +0 -187
  55. package/example/progress.html +0 -173
  56. package/example/pso.html +0 -148
  57. package/example/sort.html +0 -805
  58. package/example/tweenjs.html +0 -84
  59. package/example/webgl.html +0 -278
  60. package/example/xfj/img/dr_die.gif +0 -0
  61. package/example/xfj/index.html +0 -332
  62. package/example/xfj/shake.js +0 -49
  63. 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 = new jmGraph(container, {
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(rect);
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: 'Hello World',
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
  ### 构建