jmgraph 3.2.20 → 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 CHANGED
@@ -15,7 +15,9 @@
15
15
  - 🎯 **丰富图形** - 内置矩形、圆形、线条、箭头、贝塞尔曲线等常用图形
16
16
  - 🎭 **事件系统** - 完整的鼠标和触摸事件支持
17
17
  - 🔧 **可扩展** - 支持自定义图形控件
18
- - 🌈 **样式丰富** - 支持渐变、阴影、透明度等样式
18
+ - 🌈 **样式丰富** - 支持渐变、阴影、透明度、滤镜、虚线、混合模式等样式
19
+ - 🖼️ **边框系统** - 完整的 border 支持(宽度/样式/颜色),四角独立圆角
20
+ - ✂️ **裁剪遮罩** - 支持 clipPath 裁剪路径和 mask 遮罩效果
19
21
  - 📐 **图层管理** - 支持多图层操作,包括创建、切换、删除图层
20
22
  - 🔍 **缩放平移** - 支持画布缩放和平移操作
21
23
  - 📤 **导出功能** - 支持导出为 PNG、JPEG 和 SVG 格式
@@ -45,6 +47,8 @@ yarn add jmgraph
45
47
 
46
48
  ## 🚀 快速开始
47
49
 
50
+ > **注意**:`g.createShape()` 创建图形后会**自动添加到当前活动图层**,无需手动调用 `g.children.add()`。若设置了 `autoRefresh: true`(默认值),画布会自动刷新,也无需手动调用 `g.redraw()`。
51
+
48
52
  ### ES6 模块方式
49
53
 
50
54
  ```html
@@ -52,7 +56,7 @@ yarn add jmgraph
52
56
  import jmGraph from "jmgraph";
53
57
 
54
58
  const container = document.getElementById('mycanvas_container');
55
- const g = new jmGraph(container, {
59
+ const g = jmGraph(container, {
56
60
  width: 800,
57
61
  height: 600,
58
62
  autoRefresh: true,
@@ -93,14 +97,15 @@ const rect = g.createShape('rect', {
93
97
  height: 100
94
98
  });
95
99
 
96
- g.children.add(rect);
97
- g.redraw();
100
+ // createShape 会自动将图形添加到当前活动图层,无需手动 g.children.add()
101
+ // 如果 autoRefresh 为 true(默认),也不需要手动调用 g.redraw()
98
102
  ```
99
103
 
100
104
  ## 📚 文档
101
105
 
102
106
  - [在线示例](https://fefeding.github.io/jmgraph/example/index.html)
103
107
  - [新特性示例](https://fefeding.github.io/jmgraph/example/new-features.html)
108
+ - [样式扩展特性](https://fefeding.github.io/jmgraph/example/style-extension-demo.html)
104
109
  - [基于 jmGraph 的图表库](https://github.com/fefeding/jmchart)
105
110
 
106
111
  ## 🎨 样式说明
@@ -127,6 +132,116 @@ jmGraph 支持简化的样式名称和原生 Canvas 样式:
127
132
  | lineJoin | lineJoin | 线条连接样式 |
128
133
  | lineCap | lineCap | 线条端点样式 |
129
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
+ ```
130
245
 
131
246
  ## 🎯 内置图形
132
247
 
@@ -439,6 +554,24 @@ g.exportToJPEG('my-graph', 0.8);
439
554
  g.exportToSVG('my-graph');
440
555
  ```
441
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
+
442
575
  ## 📝 文本换行
443
576
 
444
577
  当文本长度超过 `maxWidth` 时,会自动换行显示: