vkedit 2.8.6 → 3.2.5
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.en.md +385 -1193
- package/README.md +383 -1190
- package/dist/commands/distribute-elements-command.d.ts +13 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/components/ContextMenuDelete.vue.d.ts +1 -1
- package/dist/components/ui/{select/SelectTrigger.vue.d.ts → VkButton.vue.d.ts} +13 -7
- package/dist/components/ui/VkDropdown.vue.d.ts +22 -0
- package/dist/components/ui/VkIcon.vue.d.ts +8 -0
- package/dist/components/ui/{textarea/Textarea.vue.d.ts → VkInput.vue.d.ts} +6 -4
- package/dist/components/ui/VkInputMM.vue.d.ts +17 -0
- package/dist/components/ui/VkInputNumber.vue.d.ts +16 -0
- package/dist/components/ui/{input-mm/InputMM.vue.d.ts → VkInputNumberMM.vue.d.ts} +8 -6
- package/dist/components/ui/{number-field/NumberFieldContent.vue.d.ts → VkLabel.vue.d.ts} +3 -3
- package/dist/components/ui/{dropdown-menu/DropdownMenuRadioItem.vue.d.ts → VkSelect.vue.d.ts} +7 -7
- package/dist/components/ui/VkSwitch.vue.d.ts +14 -0
- package/dist/components/ui/{toggle/Toggle.vue.d.ts → VkToggle.vue.d.ts} +9 -12
- package/dist/components/ui/index.d.ts +11 -14
- package/dist/core/Editor.vue.d.ts +1 -7
- package/dist/{components/ui/button-group/ButtonGroupText.vue.d.ts → core/GraphicToolPanel.vue.d.ts} +14 -12
- package/dist/core/HelpGuide.vue.d.ts +2 -0
- package/dist/core/PropertyPanel.vue.d.ts +1 -0
- package/dist/core/{ScrollbarLayer.vue.d.ts → StatusBar.vue.d.ts} +1 -3
- package/dist/core/Toolbar.vue.d.ts +4 -6
- package/dist/core/editor-host.d.ts +12 -0
- package/dist/create-host.d.ts +1 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/use-bg-layer.d.ts +6 -0
- package/dist/hooks/use-content-layer.d.ts +4 -0
- package/dist/hooks/use-ruler-layer.d.ts +6 -1
- package/dist/hooks/use-stage-event.d.ts +6 -1
- package/dist/hooks/use-stage.d.ts +11 -7
- package/dist/hooks/use-zoom.d.ts +20 -1
- package/dist/{index-CjPgwxVC.js → index-Bisex1w7.js} +25500 -35357
- package/dist/index.d.ts +0 -1
- package/dist/{index.es-DekiblxN.js → index.es-CEBX1sXY.js} +1 -1
- package/dist/lib/utils.d.ts +1 -2
- package/dist/plugins/barcode/Tool.vue.d.ts +2 -1
- package/dist/plugins/barcode/barcode.d.ts +4 -0
- package/dist/plugins/chart/Tool.vue.d.ts +2 -1
- package/dist/plugins/clipboard/clipboard.d.ts +33 -0
- package/dist/plugins/clipboard/index.d.ts +1 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/keydown.d.ts +11 -1
- package/dist/plugins/line/Tool.vue.d.ts +2 -1
- package/dist/plugins/line/line.d.ts +1 -2
- package/dist/plugins/preview/PreviewButton.vue.d.ts +1 -1
- package/dist/plugins/qrcode/Tool.vue.d.ts +2 -1
- package/dist/plugins/rect/Tool.vue.d.ts +2 -1
- package/dist/plugins/rect/rect.d.ts +1 -2
- package/dist/plugins/selection.d.ts +5 -0
- package/dist/{components/ui/number-field/NumberFieldInput.vue.d.ts → plugins/snap/SnapToggle.vue.d.ts} +4 -3
- package/dist/plugins/snap/index.d.ts +2 -0
- package/dist/plugins/snap/snap.d.ts +24 -0
- package/dist/plugins/table/Tool.vue.d.ts +2 -1
- package/dist/plugins/table/table.d.ts +1 -2
- package/dist/plugins/text/TextContextMenu.vue.d.ts +1 -1
- package/dist/plugins/text/Tool.vue.d.ts +2 -1
- package/dist/plugins/text/text.d.ts +1 -0
- package/dist/plugins/toolbar-manager.d.ts +3 -1
- package/dist/types/base-graphic-element.d.ts +3 -0
- package/dist/types/base.d.ts +14 -0
- package/dist/types/event-data.d.ts +16 -0
- package/dist/types/event-map.d.ts +6 -3
- package/dist/utils/geometry.d.ts +38 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/vkedit.css +1 -1
- package/dist/vkedit.es.js +97 -107
- package/package.json +12 -21
- package/dist/components/ui/button/Button.vue.d.ts +0 -27
- package/dist/components/ui/button/index.d.ts +0 -7
- package/dist/components/ui/button-group/ButtonGroup.vue.d.ts +0 -23
- package/dist/components/ui/button-group/ButtonGroupSeparator.vue.d.ts +0 -9
- package/dist/components/ui/button-group/index.d.ts +0 -8
- package/dist/components/ui/dropdown-menu/DropdownMenu.vue.d.ts +0 -22
- package/dist/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue.d.ts +0 -28
- package/dist/components/ui/dropdown-menu/DropdownMenuContent.vue.d.ts +0 -36
- package/dist/components/ui/dropdown-menu/DropdownMenuGroup.vue.d.ts +0 -18
- package/dist/components/ui/dropdown-menu/DropdownMenuItem.vue.d.ts +0 -26
- package/dist/components/ui/dropdown-menu/DropdownMenuLabel.vue.d.ts +0 -23
- package/dist/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue.d.ts +0 -22
- package/dist/components/ui/dropdown-menu/DropdownMenuSeparator.vue.d.ts +0 -7
- package/dist/components/ui/dropdown-menu/DropdownMenuShortcut.vue.d.ts +0 -21
- package/dist/components/ui/dropdown-menu/DropdownMenuSub.vue.d.ts +0 -22
- package/dist/components/ui/dropdown-menu/DropdownMenuSubContent.vue.d.ts +0 -38
- package/dist/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue.d.ts +0 -23
- package/dist/components/ui/dropdown-menu/DropdownMenuTrigger.vue.d.ts +0 -18
- package/dist/components/ui/dropdown-menu/index.d.ts +0 -15
- package/dist/components/ui/input/Input.vue.d.ts +0 -12
- package/dist/components/ui/input/index.d.ts +0 -1
- package/dist/components/ui/input-mm/InputNumberMM.vue.d.ts +0 -14
- package/dist/components/ui/input-mm/index.d.ts +0 -2
- package/dist/components/ui/input-number/VkInputNumber.vue.d.ts +0 -9
- package/dist/components/ui/input-number/index.d.ts +0 -1
- package/dist/components/ui/label/Label.vue.d.ts +0 -22
- package/dist/components/ui/label/index.d.ts +0 -1
- package/dist/components/ui/number-field/NumberField.vue.d.ts +0 -26
- package/dist/components/ui/number-field/NumberFieldDecrement.vue.d.ts +0 -22
- package/dist/components/ui/number-field/NumberFieldIncrement.vue.d.ts +0 -22
- package/dist/components/ui/number-field/index.d.ts +0 -5
- package/dist/components/ui/scroll-area/ScrollArea.vue.d.ts +0 -22
- package/dist/components/ui/scroll-area/ScrollBar.vue.d.ts +0 -9
- package/dist/components/ui/scroll-area/index.d.ts +0 -2
- package/dist/components/ui/select/Select.vue.d.ts +0 -25
- package/dist/components/ui/select/SelectContent.vue.d.ts +0 -32
- package/dist/components/ui/select/SelectGroup.vue.d.ts +0 -18
- package/dist/components/ui/select/SelectItem.vue.d.ts +0 -22
- package/dist/components/ui/select/SelectItemText.vue.d.ts +0 -18
- package/dist/components/ui/select/SelectLabel.vue.d.ts +0 -22
- package/dist/components/ui/select/SelectScrollDownButton.vue.d.ts +0 -22
- package/dist/components/ui/select/SelectScrollUpButton.vue.d.ts +0 -22
- package/dist/components/ui/select/SelectSeparator.vue.d.ts +0 -7
- package/dist/components/ui/select/SelectValue.vue.d.ts +0 -18
- package/dist/components/ui/select/index.d.ts +0 -11
- package/dist/components/ui/separator/Separator.vue.d.ts +0 -10
- package/dist/components/ui/separator/index.d.ts +0 -1
- package/dist/components/ui/slider/Slider.vue.d.ts +0 -13
- package/dist/components/ui/slider/index.d.ts +0 -1
- package/dist/components/ui/switch/Switch.vue.d.ts +0 -26
- package/dist/components/ui/switch/index.d.ts +0 -1
- package/dist/components/ui/textarea/index.d.ts +0 -1
- package/dist/components/ui/toggle/index.d.ts +0 -7
- package/dist/core/Toolbox.vue.d.ts +0 -23
- package/dist/hooks/use-scrollbar-layer.d.ts +0 -47
- package/dist/stores/index.d.ts +0 -1
- package/dist/stores/use-stage-store.d.ts +0 -40
- package/dist/styles/index.css +0 -144
- /package/dist/core/{Zoom.vue.d.ts → GuideLayer.vue.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,1190 +1,383 @@
|
|
|
1
|
-
# vkedit
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[![
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
host
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
|
174
|
-
|
|
|
175
|
-
|
|
|
176
|
-
|
|
|
177
|
-
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
host
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
A --> F[ScrollbarLayer 滚动条层]
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
---
|
|
388
|
-
|
|
389
|
-
## 📁 项目结构
|
|
390
|
-
|
|
391
|
-
```
|
|
392
|
-
vkedit/
|
|
393
|
-
├── src/
|
|
394
|
-
│ ├── commands/ # 命令模式实现
|
|
395
|
-
│ │ ├── base-command.ts
|
|
396
|
-
│ │ ├── add-element-command.ts
|
|
397
|
-
│ │ ├── remove-element-command.ts
|
|
398
|
-
│ │ ├── transform-element-command.ts
|
|
399
|
-
│ │ ├── update-property-command.ts
|
|
400
|
-
│ │ ├── batch-command.ts
|
|
401
|
-
│ │ ├── align-elements-command.ts
|
|
402
|
-
│ │ └── ...
|
|
403
|
-
│ ├── components/ # Vue 组件
|
|
404
|
-
│ │ ├── ui/ # UI 统一组件库
|
|
405
|
-
│ │ │ ├── button/
|
|
406
|
-
│ │ │ ├── dropdown-menu/
|
|
407
|
-
│ │ │ ├── input/
|
|
408
|
-
│ │ │ ├── select/
|
|
409
|
-
│ │ │ └── ...
|
|
410
|
-
│ │ ├── BaseElementPropertyPanel.vue
|
|
411
|
-
│ │ ├── CanvasPropertyPanel.vue
|
|
412
|
-
│ │ └── ...
|
|
413
|
-
│ ├── core/ # 核心编辑器组件
|
|
414
|
-
│ │ ├── Editor.vue
|
|
415
|
-
│ │ ├── editor-host.ts
|
|
416
|
-
│ │ ├── StageView.vue
|
|
417
|
-
│ │ ├── Toolbar.vue
|
|
418
|
-
│ │ ├── PropertyPanel.vue
|
|
419
|
-
│ │ ├── BgLayer.vue
|
|
420
|
-
│ │ ├── ContentLayer.vue
|
|
421
|
-
│ │ ├── SelectionLayer.vue
|
|
422
|
-
│ │ ├── RulerLayer.vue
|
|
423
|
-
│ │ ├── ScrollbarLayer.vue
|
|
424
|
-
│ │ ├── ContextMenu.vue
|
|
425
|
-
│ │ ├── Zoom.vue
|
|
426
|
-
│ │ └── Toolbox.vue
|
|
427
|
-
│ ├── hooks/ # Vue 组合式函数
|
|
428
|
-
│ │ ├── use-host-state.ts
|
|
429
|
-
│ │ ├── use-bg-layer.ts
|
|
430
|
-
│ │ ├── use-content-layer.ts
|
|
431
|
-
│ │ ├── use-selection-layer.ts
|
|
432
|
-
│ │ ├── use-ruler-layer.ts
|
|
433
|
-
│ │ ├── use-scrollbar-layer.ts
|
|
434
|
-
│ │ ├── use-zoom.ts
|
|
435
|
-
│ │ └── use-stage-event.ts
|
|
436
|
-
│ ├── plugins/ # 插件系统
|
|
437
|
-
│ │ ├── element-manager.ts
|
|
438
|
-
│ │ ├── graphic-tool-manager.ts
|
|
439
|
-
│ │ ├── graphic-manager.ts
|
|
440
|
-
│ │ ├── selection.ts
|
|
441
|
-
│ │ ├── toolbar-manager.ts
|
|
442
|
-
│ │ ├── keydown.ts
|
|
443
|
-
│ │ ├── align/
|
|
444
|
-
│ │ │ ├── Align.vue
|
|
445
|
-
│ │ │ └── align.ts
|
|
446
|
-
│ │ ├── export/
|
|
447
|
-
│ │ │ ├── Export.vue
|
|
448
|
-
│ │ │ └── export.ts
|
|
449
|
-
│ │ ├── import/
|
|
450
|
-
│ │ │ ├── Import.vue
|
|
451
|
-
│ │ │ └── import.ts
|
|
452
|
-
│ │ ├── preview/
|
|
453
|
-
│ │ │ ├── PreviewButton.vue
|
|
454
|
-
│ │ │ └── preview.ts
|
|
455
|
-
│ │ ├── rect/
|
|
456
|
-
│ │ │ ├── RectPlugin.ts
|
|
457
|
-
│ │ │ ├── Shape.vue
|
|
458
|
-
│ │ │ ├── PropertyPanel.vue
|
|
459
|
-
│ │ │ └── Tool.vue
|
|
460
|
-
│ │ ├── text/
|
|
461
|
-
│ │ ├── table/
|
|
462
|
-
│ │ ├── qrcode/
|
|
463
|
-
│ │ ├── barcode/
|
|
464
|
-
│ │ ├── chart/
|
|
465
|
-
│ │ ├── line/
|
|
466
|
-
│ │ └── context-menu-manager/
|
|
467
|
-
│ ├── stores/ # Pinia 状态管理
|
|
468
|
-
│ ├── types/ # TypeScript 类型定义
|
|
469
|
-
│ │ ├── base-graphic-element.ts
|
|
470
|
-
│ │ ├── base-graphic-type.ts
|
|
471
|
-
│ │ ├── base-plugin.ts
|
|
472
|
-
│ │ ├── event-map.ts
|
|
473
|
-
│ │ ├── event-data.ts
|
|
474
|
-
│ │ └── ...
|
|
475
|
-
│ ├── styles/ # 样式文件
|
|
476
|
-
│ ├── create-host.ts # 宿主创建函数
|
|
477
|
-
│ └── index.ts # 入口文件
|
|
478
|
-
├── playground/ # 示例项目
|
|
479
|
-
│ ├── App.vue
|
|
480
|
-
│ └── main.ts
|
|
481
|
-
├── package.json
|
|
482
|
-
├── vite.config.ts
|
|
483
|
-
├── tsconfig.json
|
|
484
|
-
└── README.md
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
---
|
|
488
|
-
|
|
489
|
-
## 🔌 可用插件列表
|
|
490
|
-
|
|
491
|
-
### 核心插件
|
|
492
|
-
|
|
493
|
-
| 插件名称 | 说明 |
|
|
494
|
-
| ------------------------------ | -------------------------------- |
|
|
495
|
-
| **ToolbarManagerPlugin** | 工具栏管理器,提供顶部工具栏功能 |
|
|
496
|
-
| **GraphicToolManagerPlugin** | 图形工具管理器,管理图形绘制工具 |
|
|
497
|
-
| **GraphicManagerPlugin** | 图形管理器,统一管理所有图形元素 |
|
|
498
|
-
| **ElementManagerPlugin** | 元素管理器,管理元素的生命周期 |
|
|
499
|
-
| **SelectionPlugin** | 选择插件,处理元素选择和多选操作 |
|
|
500
|
-
| **PropertyPanelManagerPlugin** | 属性面板管理器,动态渲染属性面板 |
|
|
501
|
-
| **KeyDownPlugin** | 键盘事件插件,处理快捷键 |
|
|
502
|
-
| **AlignPlugin** | 对齐插件,提供元素对齐和分布功能 |
|
|
503
|
-
| **ContextMenuManagerPlugin** | 上下文菜单管理器 |
|
|
504
|
-
|
|
505
|
-
### 功能插件
|
|
506
|
-
|
|
507
|
-
| 插件名称 | 说明 |
|
|
508
|
-
| ----------------- | ----------------------------------------------- |
|
|
509
|
-
| **ExportPlugin** | 导出插件,支持导出为 JSON、PNG、JPG、PDF 等格式 |
|
|
510
|
-
| **ImportPlugin** | 导入插件,支持从 JSON 文件导入设计数据 |
|
|
511
|
-
| **PreviewPlugin** | 预览插件,提供设计预览功能 |
|
|
512
|
-
|
|
513
|
-
### 图形插件
|
|
514
|
-
|
|
515
|
-
| 插件名称 | 图形类型 | 说明 |
|
|
516
|
-
| ----------------- | -------- | ------------------------------------------- |
|
|
517
|
-
| **RectPlugin** | 矩形 | 可拖拽、缩放、调整填充和边框的矩形元素 |
|
|
518
|
-
| **TextPlugin** | 文本 | 支持字体、大小、颜色、对齐方式的文本元素 |
|
|
519
|
-
| **LinePlugin** | 线条 | 支持起点、终点、颜色、宽度的线条元素 |
|
|
520
|
-
| **TablePlugin** | 表格 | 支持行列、边框、文字对齐的表格元素 |
|
|
521
|
-
| **QrcodePlugin** | 二维码 | 可生成可配置的二维码元素 |
|
|
522
|
-
| **BarcodePlugin** | 条形码 | 支持多种格式(EAN-13、CODE-128 等)的条形码 |
|
|
523
|
-
| **ChartPlugin** | 图表 | 基于 ECharts 的图表元素 |
|
|
524
|
-
|
|
525
|
-
---
|
|
526
|
-
|
|
527
|
-
## 📚 API 参考
|
|
528
|
-
|
|
529
|
-
### createEditorHost()
|
|
530
|
-
|
|
531
|
-
创建编辑器宿主实例并安装核心插件。
|
|
532
|
-
|
|
533
|
-
```typescript
|
|
534
|
-
function createEditorHost(options: IOptions): EditorHost
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
**参数:**
|
|
538
|
-
|
|
539
|
-
```typescript
|
|
540
|
-
interface IOptions {
|
|
541
|
-
basePropertyPanel?: boolean // 是否启用基础元素属性面板
|
|
542
|
-
baseCanvasPropertyPanel?: boolean // 是否启用画布属性面板
|
|
543
|
-
exportPlugin?: boolean // 是否启用导出插件
|
|
544
|
-
previewPlugin?: boolean // 是否启用预览插件
|
|
545
|
-
importPlugin?: boolean // 是否启用导入插件
|
|
546
|
-
}
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
**返回:** `EditorHost` 实例
|
|
550
|
-
|
|
551
|
-
---
|
|
552
|
-
|
|
553
|
-
### EditorHost 类方法
|
|
554
|
-
|
|
555
|
-
#### 插件管理
|
|
556
|
-
|
|
557
|
-
| 方法 | 说明 |
|
|
558
|
-
| ---------------------------------- | ------------ |
|
|
559
|
-
| `installPlugin(name, pluginClass)` | 安装插件 |
|
|
560
|
-
| `uninstallPlugin(pluginName)` | 卸载插件 |
|
|
561
|
-
| `getPlugin<T>(pluginName)` | 获取插件实例 |
|
|
562
|
-
|
|
563
|
-
```typescript
|
|
564
|
-
// 安装插件
|
|
565
|
-
host.installPlugin('rect-plugin', RectPlugin)
|
|
566
|
-
|
|
567
|
-
// 卸载插件
|
|
568
|
-
host.uninstallPlugin('rect-plugin')
|
|
569
|
-
|
|
570
|
-
// 获取插件实例
|
|
571
|
-
const rectPlugin = host.getPlugin<RectPlugin>('rect-plugin')
|
|
572
|
-
```
|
|
573
|
-
|
|
574
|
-
#### 命令操作
|
|
575
|
-
|
|
576
|
-
| 方法 | 说明 |
|
|
577
|
-
| ------------------------- | -------- |
|
|
578
|
-
| `executeCommand(command)` | 执行命令 |
|
|
579
|
-
| `undo()` | 撤销 |
|
|
580
|
-
| `redo()` | 重做 |
|
|
581
|
-
|
|
582
|
-
```typescript
|
|
583
|
-
import { AddElementCommand } from 'vkedit'
|
|
584
|
-
|
|
585
|
-
// 执行命令
|
|
586
|
-
const command = new AddElementCommand(element, host)
|
|
587
|
-
host.executeCommand(command)
|
|
588
|
-
|
|
589
|
-
// 撤销
|
|
590
|
-
host.undo()
|
|
591
|
-
|
|
592
|
-
// 重做
|
|
593
|
-
host.redo()
|
|
594
|
-
```
|
|
595
|
-
|
|
596
|
-
#### 事件系统
|
|
597
|
-
|
|
598
|
-
| 方法 | 说明 |
|
|
599
|
-
| ---------------------- | -------- |
|
|
600
|
-
| `emit(event, payload)` | 触发事件 |
|
|
601
|
-
| `on(event, handler)` | 订阅事件 |
|
|
602
|
-
| `off(event, handler)` | 取消订阅 |
|
|
603
|
-
|
|
604
|
-
```typescript
|
|
605
|
-
// 订阅事件
|
|
606
|
-
host.on('element:added', (payload) => {
|
|
607
|
-
console.log('元素已添加:', payload)
|
|
608
|
-
})
|
|
609
|
-
|
|
610
|
-
// 触发事件
|
|
611
|
-
host.emit('element:added', { element: myElement })
|
|
612
|
-
|
|
613
|
-
// 取消订阅
|
|
614
|
-
host.off('element:added')
|
|
615
|
-
```
|
|
616
|
-
|
|
617
|
-
#### 状态管理
|
|
618
|
-
|
|
619
|
-
| 属性 | 类型 | 说明 |
|
|
620
|
-
| -------- | -------------- | ------------------ |
|
|
621
|
-
| `status` | `IEditorState` | 编辑器状态(只读) |
|
|
622
|
-
|
|
623
|
-
```typescript
|
|
624
|
-
interface IEditorState {
|
|
625
|
-
zoom: number // 缩放级别
|
|
626
|
-
currentTool: string // 当前工具
|
|
627
|
-
snapToGrid: boolean // 是否吸附网格
|
|
628
|
-
showGrid: boolean // 是否显示网格
|
|
629
|
-
width: number // 画布宽度(像素)
|
|
630
|
-
height: number // 画布高度(像素)
|
|
631
|
-
wmm: number // 画布宽度(毫米)
|
|
632
|
-
hmm: number // 画布高度(毫米)
|
|
633
|
-
dpm: number // 每毫米点数
|
|
634
|
-
}
|
|
635
|
-
```
|
|
636
|
-
|
|
637
|
-
```typescript
|
|
638
|
-
// 更新状态
|
|
639
|
-
host.setStatus({
|
|
640
|
-
zoom: 1,
|
|
641
|
-
width: 800,
|
|
642
|
-
height: 600
|
|
643
|
-
})
|
|
644
|
-
|
|
645
|
-
// 读取状态
|
|
646
|
-
console.log(host.status.zoom)
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
#### 序列化
|
|
650
|
-
|
|
651
|
-
| 方法 | 说明 |
|
|
652
|
-
| ------------------- | ------------------ |
|
|
653
|
-
| `toJSON()` | 导出为 JSON 字符串 |
|
|
654
|
-
| `loadJSON(jsonStr)` | 从 JSON 字符串导入 |
|
|
655
|
-
|
|
656
|
-
```typescript
|
|
657
|
-
// 导出
|
|
658
|
-
const json = host.toJSON()
|
|
659
|
-
|
|
660
|
-
// 导入
|
|
661
|
-
host.loadJSON(json)
|
|
662
|
-
```
|
|
663
|
-
|
|
664
|
-
---
|
|
665
|
-
|
|
666
|
-
## 🎯 事件系统
|
|
667
|
-
|
|
668
|
-
编辑器提供丰富的事件类型,支持插件间的松耦合通信。
|
|
669
|
-
|
|
670
|
-
### 生命周期事件
|
|
671
|
-
|
|
672
|
-
| 事件名 | 说明 |
|
|
673
|
-
| ---------------- | -------------- |
|
|
674
|
-
| `editor:ready` | 编辑器准备就绪 |
|
|
675
|
-
| `editor:destroy` | 编辑器销毁 |
|
|
676
|
-
| `editor:reset` | 编辑器重置 |
|
|
677
|
-
|
|
678
|
-
### 文件操作事件
|
|
679
|
-
|
|
680
|
-
| 事件名 | 说明 |
|
|
681
|
-
| ---------------------- | ---------------- |
|
|
682
|
-
| `file:new` | 新建文件 |
|
|
683
|
-
| `file:open` | 打开文件 |
|
|
684
|
-
| `file:save` | 保存文件 |
|
|
685
|
-
| `file:save-as` | 另存为 |
|
|
686
|
-
| `file:export` | 导出文件 |
|
|
687
|
-
| `file:import` | 导入文件 |
|
|
688
|
-
| `file:loaded` | 文件已加载 |
|
|
689
|
-
| `file:saved` | 文件已保存 |
|
|
690
|
-
| `file:modified-change` | 文件修改状态变化 |
|
|
691
|
-
|
|
692
|
-
### 舞台交互事件
|
|
693
|
-
|
|
694
|
-
| 事件名 | 说明 |
|
|
695
|
-
| ------------------- | ---------- |
|
|
696
|
-
| `stage:mousedown` | 鼠标按下 |
|
|
697
|
-
| `stage:mousemove` | 鼠标移动 |
|
|
698
|
-
| `stage:mouseup` | 鼠标松开 |
|
|
699
|
-
| `stage:click` | 鼠标点击 |
|
|
700
|
-
| `stage:dblclick` | 鼠标双击 |
|
|
701
|
-
| `stage:contextmenu` | 上下文菜单 |
|
|
702
|
-
| `stage:wheel` | 鼠标滚轮 |
|
|
703
|
-
| `stage:dragstart` | 拖拽开始 |
|
|
704
|
-
| `stage:dragend` | 拖拽结束 |
|
|
705
|
-
| `stage:redraw` | 舞台重绘 |
|
|
706
|
-
|
|
707
|
-
### 键盘事件
|
|
708
|
-
|
|
709
|
-
| 事件名 | 说明 |
|
|
710
|
-
| ---------------------- | -------- |
|
|
711
|
-
| `stage:keydown` | 键盘按下 |
|
|
712
|
-
| `stage:keydown-delete` | 删除键 |
|
|
713
|
-
| `stage:keydown-left` | 左箭头 |
|
|
714
|
-
| `stage:keydown-right` | 右箭头 |
|
|
715
|
-
| `stage:keydown-up` | 上箭头 |
|
|
716
|
-
| `stage:keydown-down` | 下箭头 |
|
|
717
|
-
|
|
718
|
-
### 图形元素事件
|
|
719
|
-
|
|
720
|
-
| 事件名 | 说明 |
|
|
721
|
-
| --------------------------- | ------------ |
|
|
722
|
-
| `element:registered` | 元素类型注册 |
|
|
723
|
-
| `element:unregistered` | 元素类型注销 |
|
|
724
|
-
| `element:added` | 元素添加 |
|
|
725
|
-
| `element:removed` | 元素移除 |
|
|
726
|
-
| `element:selected` | 元素选中 |
|
|
727
|
-
| `element:deselected` | 元素取消选中 |
|
|
728
|
-
| `element:transformed` | 元素变换 |
|
|
729
|
-
| `element:updated` | 元素更新 |
|
|
730
|
-
| `element:copied` | 元素复制 |
|
|
731
|
-
| `element:pasted` | 元素粘贴 |
|
|
732
|
-
| `element:cloned` | 元素克隆 |
|
|
733
|
-
| `element:locked-change` | 锁定状态变化 |
|
|
734
|
-
| `element:visibility-change` | 可见性变化 |
|
|
735
|
-
| `element:zindex-change` | 层级变化 |
|
|
736
|
-
|
|
737
|
-
### 选择事件
|
|
738
|
-
|
|
739
|
-
| 事件名 | 说明 |
|
|
740
|
-
| ------------------------ | -------- |
|
|
741
|
-
| `selection:changed` | 选择变化 |
|
|
742
|
-
| `selection:cleared` | 清除选择 |
|
|
743
|
-
| `selection:multi-change` | 多选变化 |
|
|
744
|
-
|
|
745
|
-
### 视图事件
|
|
746
|
-
|
|
747
|
-
| 事件名 | 说明 |
|
|
748
|
-
| ------------------------------ | ---------- |
|
|
749
|
-
| `view:zoom-change` | 缩放变化 |
|
|
750
|
-
| `view:pan` | 平移 |
|
|
751
|
-
| `view:zoom-to` | 适应视图 |
|
|
752
|
-
| `view:reset` | 重置视图 |
|
|
753
|
-
| `view:grid-visibility-change` | 网格可见性 |
|
|
754
|
-
| `view:snap-change` | 吸附变化 |
|
|
755
|
-
| `view:ruler-visibility-change` | 标尺可见性 |
|
|
756
|
-
|
|
757
|
-
### 图层事件
|
|
758
|
-
|
|
759
|
-
| 事件名 | 说明 |
|
|
760
|
-
| ------------------------- | ------------ |
|
|
761
|
-
| `layer:added` | 图层添加 |
|
|
762
|
-
| `layer:removed` | 图层移除 |
|
|
763
|
-
| `layer:order-changed` | 图层顺序变化 |
|
|
764
|
-
| `layer:visibility-change` | 图层可见性 |
|
|
765
|
-
| `layer:locked-change` | 图层锁定 |
|
|
766
|
-
| `layer:active-change` | 图层激活 |
|
|
767
|
-
|
|
768
|
-
### 命令历史事件
|
|
769
|
-
|
|
770
|
-
| 事件名 | 说明 |
|
|
771
|
-
| ------------------ | -------- |
|
|
772
|
-
| `command:executed` | 命令执行 |
|
|
773
|
-
| `command:undone` | 命令撤销 |
|
|
774
|
-
| `command:redone` | 命令重做 |
|
|
775
|
-
| `history:changed` | 历史变化 |
|
|
776
|
-
| `history:cleared` | 历史清除 |
|
|
777
|
-
|
|
778
|
-
### 插件系统事件
|
|
779
|
-
|
|
780
|
-
| 事件名 | 说明 |
|
|
781
|
-
| --------------------- | -------- |
|
|
782
|
-
| `plugin:registered` | 插件注册 |
|
|
783
|
-
| `plugin:unregistered` | 插件注销 |
|
|
784
|
-
| `plugin:activated` | 插件激活 |
|
|
785
|
-
| `plugin:deactivated` | 插件停用 |
|
|
786
|
-
| `plugin:loaded` | 插件加载 |
|
|
787
|
-
| `plugin:error` | 插件错误 |
|
|
788
|
-
|
|
789
|
-
### 对齐分布事件
|
|
790
|
-
|
|
791
|
-
| 事件名 | 说明 |
|
|
792
|
-
| --------------------- | ------------ |
|
|
793
|
-
| `elements:align` | 元素对齐 |
|
|
794
|
-
| `elements:distribute` | 元素分布 |
|
|
795
|
-
| `elements:group` | 元素组合 |
|
|
796
|
-
| `elements:ungroup` | 元素取消组合 |
|
|
797
|
-
| `elements:layer` | 图层操作 |
|
|
798
|
-
|
|
799
|
-
### 状态管理事件
|
|
800
|
-
|
|
801
|
-
| 事件名 | 说明 |
|
|
802
|
-
| ---------------------- | -------- |
|
|
803
|
-
| `host:status-changed` | 状态变化 |
|
|
804
|
-
| `host:status-saved` | 状态保存 |
|
|
805
|
-
| `host:status-restored` | 状态恢复 |
|
|
806
|
-
|
|
807
|
-
### 序列化事件
|
|
808
|
-
|
|
809
|
-
| 事件名 | 说明 |
|
|
810
|
-
| ------------------------- | -------------- |
|
|
811
|
-
| `host:load-json:start` | 加载 JSON 开始 |
|
|
812
|
-
| `host:load-json:complete` | 加载 JSON 完成 |
|
|
813
|
-
| `host:load-json:error` | 加载 JSON 错误 |
|
|
814
|
-
| `host:to-json:start` | 导出 JSON 开始 |
|
|
815
|
-
| `host:to-json:complete` | 导出 JSON 完成 |
|
|
816
|
-
| `host:to-json:error` | 导出 JSON 错误 |
|
|
817
|
-
|
|
818
|
-
### 事件使用示例
|
|
819
|
-
|
|
820
|
-
```typescript
|
|
821
|
-
import type { ElementEventData, SelectionEventData } from 'vkedit'
|
|
822
|
-
|
|
823
|
-
// 监听元素添加事件
|
|
824
|
-
host.on('element:added', (payload: ElementEventData) => {
|
|
825
|
-
console.log('新元素添加:', payload.element)
|
|
826
|
-
})
|
|
827
|
-
|
|
828
|
-
// 监听选择变化事件
|
|
829
|
-
host.on('selection:changed', (payload: SelectionEventData) => {
|
|
830
|
-
console.log('选中元素数量:', payload.selectedIds.length)
|
|
831
|
-
})
|
|
832
|
-
|
|
833
|
-
// 监听状态变化
|
|
834
|
-
host.on('host:status-changed', (payload) => {
|
|
835
|
-
console.log('状态已更新:', payload.status)
|
|
836
|
-
})
|
|
837
|
-
|
|
838
|
-
// 触发自定义事件
|
|
839
|
-
host.emit('custom:my-event', { data: 'some data' })
|
|
840
|
-
```
|
|
841
|
-
|
|
842
|
-
### 扩展事件系统
|
|
843
|
-
|
|
844
|
-
开发者可以通过模块声明扩展事件映射:
|
|
845
|
-
|
|
846
|
-
```typescript
|
|
847
|
-
declare module '@/types' {
|
|
848
|
-
interface EventMap {
|
|
849
|
-
'my-plugin:some-event': (payload: MyEventData) => void
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
interface MyEventData {
|
|
854
|
-
id: string
|
|
855
|
-
value: number
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
// 使用扩展事件
|
|
859
|
-
host.emit('my-plugin:some-event', { id: '123', value: 42 })
|
|
860
|
-
|
|
861
|
-
// 监听扩展事件
|
|
862
|
-
host.on('my-plugin:some-event', (payload) => {
|
|
863
|
-
console.log(payload.value)
|
|
864
|
-
})
|
|
865
|
-
```
|
|
866
|
-
|
|
867
|
-
---
|
|
868
|
-
|
|
869
|
-
## 📝 命令系统
|
|
870
|
-
|
|
871
|
-
vkedit 使用命令模式实现可撤销的操作。所有修改编辑器状态的操作都应通过命令执行。
|
|
872
|
-
|
|
873
|
-
### 可用命令类型
|
|
874
|
-
|
|
875
|
-
| 命令类 | 说明 |
|
|
876
|
-
| ------------------------- | ---------------------------- |
|
|
877
|
-
| `AddElementCommand` | 添加元素 |
|
|
878
|
-
| `RemoveElementCommand` | 移除元素 |
|
|
879
|
-
| `TransformElementCommand` | 变换元素(位置、大小、旋转) |
|
|
880
|
-
| `UpdatePropertyCommand` | 更新元素属性 |
|
|
881
|
-
| `ClearSelectionCommand` | 清除选择 |
|
|
882
|
-
| `BatchCommand` | 批量命令 |
|
|
883
|
-
| `ChangeLayerOrderCommand` | 改变图层顺序 |
|
|
884
|
-
| `AlignElementsCommand` | 对齐元素 |
|
|
885
|
-
|
|
886
|
-
### 命令执行
|
|
887
|
-
|
|
888
|
-
```typescript
|
|
889
|
-
import { AddElementCommand, TransformElementCommand } from 'vkedit'
|
|
890
|
-
|
|
891
|
-
// 创建并执行命令
|
|
892
|
-
const command = new AddElementCommand(element, host)
|
|
893
|
-
host.executeCommand(command)
|
|
894
|
-
```
|
|
895
|
-
|
|
896
|
-
### 撤销和重做
|
|
897
|
-
|
|
898
|
-
```typescript
|
|
899
|
-
// 撤销上一步操作
|
|
900
|
-
host.undo()
|
|
901
|
-
|
|
902
|
-
// 重做已撤销的操作
|
|
903
|
-
host.redo()
|
|
904
|
-
```
|
|
905
|
-
|
|
906
|
-
### 批量命令
|
|
907
|
-
|
|
908
|
-
```typescript
|
|
909
|
-
import { BatchCommand } from 'vkedit'
|
|
910
|
-
|
|
911
|
-
const commands = [
|
|
912
|
-
new UpdatePropertyCommand(element1, 'x', 100),
|
|
913
|
-
new UpdatePropertyCommand(element2, 'y', 200)
|
|
914
|
-
]
|
|
915
|
-
|
|
916
|
-
const batchCommand = new BatchCommand(commands)
|
|
917
|
-
host.executeCommand(batchCommand)
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
---
|
|
921
|
-
|
|
922
|
-
## 💻 开发指南
|
|
923
|
-
|
|
924
|
-
### 开发环境设置
|
|
925
|
-
|
|
926
|
-
```bash
|
|
927
|
-
# 克隆仓库
|
|
928
|
-
git clone https://github.com/pwg-code/vkedit.git
|
|
929
|
-
cd vkedit
|
|
930
|
-
|
|
931
|
-
# 安装依赖(推荐使用 pnpm)
|
|
932
|
-
pnpm install
|
|
933
|
-
|
|
934
|
-
# 启动开发服务器
|
|
935
|
-
pnpm dev
|
|
936
|
-
|
|
937
|
-
# 类型检查
|
|
938
|
-
pnpm type-check
|
|
939
|
-
|
|
940
|
-
# 代码检查和修复
|
|
941
|
-
pnpm lint
|
|
942
|
-
|
|
943
|
-
# 代码格式化
|
|
944
|
-
pnpm format
|
|
945
|
-
|
|
946
|
-
# 构建生产版本
|
|
947
|
-
pnpm build
|
|
948
|
-
```
|
|
949
|
-
|
|
950
|
-
### 可用脚本命令
|
|
951
|
-
|
|
952
|
-
| 命令 | 说明 |
|
|
953
|
-
| ----------------- | ------------------------ |
|
|
954
|
-
| `pnpm dev` | 启动开发服务器 |
|
|
955
|
-
| `pnpm build` | 构建生产版本 |
|
|
956
|
-
| `pnpm build-only` | 仅构建(不运行类型检查) |
|
|
957
|
-
| `pnpm preview` | 预览生产构建 |
|
|
958
|
-
| `pnpm type-check` | TypeScript 类型检查 |
|
|
959
|
-
| `pnpm lint` | ESLint 检查并自动修复 |
|
|
960
|
-
| `pnpm format` | Prettier 格式化代码 |
|
|
961
|
-
| `pnpm build:css` | 构建 CSS 文件 |
|
|
962
|
-
|
|
963
|
-
### 开发自定义插件
|
|
964
|
-
|
|
965
|
-
自定义插件需要实现 [`IEditorPlugin`](src/types/base-plugin.ts:5) 接口:
|
|
966
|
-
|
|
967
|
-
```typescript
|
|
968
|
-
import type { IEditorPlugin } from 'vkedit'
|
|
969
|
-
|
|
970
|
-
export class MyCustomPlugin implements IEditorPlugin {
|
|
971
|
-
constructor(private host: EditorHost) {}
|
|
972
|
-
|
|
973
|
-
install(host: EditorHost): void {
|
|
974
|
-
// 监听事件
|
|
975
|
-
host.on('element:added', this.onElementAdded)
|
|
976
|
-
|
|
977
|
-
// 注册工具
|
|
978
|
-
host.emit('tool:registered', {
|
|
979
|
-
name: 'my-tool',
|
|
980
|
-
icon: 'my-icon',
|
|
981
|
-
render: () => MyToolComponent
|
|
982
|
-
})
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
uninstall(): void {
|
|
986
|
-
// 清理资源
|
|
987
|
-
this.host.off('element:added', this.onElementAdded)
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
private onElementAdded = (payload: any) => {
|
|
991
|
-
console.log('元素已添加:', payload)
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
// 使用自定义插件
|
|
996
|
-
host.installPlugin('my-custom-plugin', MyCustomPlugin)
|
|
997
|
-
```
|
|
998
|
-
|
|
999
|
-
### 自定义图形元素
|
|
1000
|
-
|
|
1001
|
-
创建自定义图形元素需要继承 [`BaseGraphicElement`](src/types/base-graphic-element.ts:5):
|
|
1002
|
-
|
|
1003
|
-
```typescript
|
|
1004
|
-
import { BaseGraphicElement } from 'vkedit'
|
|
1005
|
-
|
|
1006
|
-
export class MyCustomElement extends BaseGraphicElement {
|
|
1007
|
-
constructor(
|
|
1008
|
-
id: string,
|
|
1009
|
-
public width: number = 100,
|
|
1010
|
-
public height: number = 100,
|
|
1011
|
-
public fill: string = '#ff0000'
|
|
1012
|
-
) {
|
|
1013
|
-
super(id, 'my-custom')
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
serialize(): Record<string, any> {
|
|
1017
|
-
return {
|
|
1018
|
-
...super.serialize(),
|
|
1019
|
-
width: this.width,
|
|
1020
|
-
height: this.height,
|
|
1021
|
-
fill: this.fill
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
deserialize(data: Record<string, any>): void {
|
|
1026
|
-
super.deserialize(data)
|
|
1027
|
-
this.width = data.width
|
|
1028
|
-
this.height = data.height
|
|
1029
|
-
this.fill = data.fill
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
render() {
|
|
1033
|
-
return {
|
|
1034
|
-
tag: 'rect',
|
|
1035
|
-
props: {
|
|
1036
|
-
x: this.x,
|
|
1037
|
-
y: this.y,
|
|
1038
|
-
width: this.width,
|
|
1039
|
-
height: this.height,
|
|
1040
|
-
fill: this.fill
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
```
|
|
1046
|
-
|
|
1047
|
-
---
|
|
1048
|
-
|
|
1049
|
-
## ❓ 常见问题(FAQ)
|
|
1050
|
-
|
|
1051
|
-
### Q: 如何设置画布尺寸为 A4 纸张?
|
|
1052
|
-
|
|
1053
|
-
```typescript
|
|
1054
|
-
host.setStatus({
|
|
1055
|
-
dpm: 8, // 每毫米点数(DPI / 25.4)
|
|
1056
|
-
width: 210 * 8, // A4 宽度 210mm
|
|
1057
|
-
height: 297 * 8 // A4 高度 297mm
|
|
1058
|
-
})
|
|
1059
|
-
```
|
|
1060
|
-
|
|
1061
|
-
### Q: 如何导出设计数据?
|
|
1062
|
-
|
|
1063
|
-
```typescript
|
|
1064
|
-
// 导出为 JSON
|
|
1065
|
-
const json = host.toJSON()
|
|
1066
|
-
|
|
1067
|
-
// 导出为图片(需要使用 ExportPlugin)
|
|
1068
|
-
host.getPlugin('export-plugin').exportAsPNG()
|
|
1069
|
-
```
|
|
1070
|
-
|
|
1071
|
-
### Q: 如何监听元素选择变化?
|
|
1072
|
-
|
|
1073
|
-
```typescript
|
|
1074
|
-
host.on('selection:changed', (payload) => {
|
|
1075
|
-
const selectedIds = payload.selectedIds
|
|
1076
|
-
console.log('当前选中元素:', selectedIds)
|
|
1077
|
-
})
|
|
1078
|
-
```
|
|
1079
|
-
|
|
1080
|
-
### Q: 如何批量更新多个元素的属性?
|
|
1081
|
-
|
|
1082
|
-
```typescript
|
|
1083
|
-
const batchCommand = new BatchCommand([
|
|
1084
|
-
new UpdatePropertyCommand(element1, 'fill', '#ff0000'),
|
|
1085
|
-
new UpdatePropertyCommand(element2, 'fill', '#00ff00'),
|
|
1086
|
-
new UpdatePropertyCommand(element3, 'fill', '#0000ff')
|
|
1087
|
-
])
|
|
1088
|
-
host.executeCommand(batchCommand)
|
|
1089
|
-
```
|
|
1090
|
-
|
|
1091
|
-
### Q: 如何禁用所有核心插件并自定义配置?
|
|
1092
|
-
|
|
1093
|
-
```typescript
|
|
1094
|
-
const host = createEditorHost({
|
|
1095
|
-
basePropertyPanel: false,
|
|
1096
|
-
baseCanvasPropertyPanel: false,
|
|
1097
|
-
exportPlugin: false,
|
|
1098
|
-
previewPlugin: false,
|
|
1099
|
-
importPlugin: false
|
|
1100
|
-
})
|
|
1101
|
-
```
|
|
1102
|
-
|
|
1103
|
-
---
|
|
1104
|
-
|
|
1105
|
-
## 🤝 贡献指南
|
|
1106
|
-
|
|
1107
|
-
欢迎贡献代码!请遵循以下规范:
|
|
1108
|
-
|
|
1109
|
-
### 代码规范
|
|
1110
|
-
|
|
1111
|
-
- 使用 TypeScript 编写代码
|
|
1112
|
-
- 遵循 ESLint 规则(`pnpm lint` 自动检查)
|
|
1113
|
-
- 使用 Prettier 格式化代码(`pnpm format`)
|
|
1114
|
-
- 编写清晰的注释和文档
|
|
1115
|
-
|
|
1116
|
-
### 提交规范
|
|
1117
|
-
|
|
1118
|
-
使用语义化提交信息:
|
|
1119
|
-
|
|
1120
|
-
```
|
|
1121
|
-
feat: 添加新功能
|
|
1122
|
-
fix: 修复 bug
|
|
1123
|
-
docs: 更新文档
|
|
1124
|
-
style: 代码格式调整
|
|
1125
|
-
refactor: 代码重构
|
|
1126
|
-
perf: 性能优化
|
|
1127
|
-
test: 添加测试
|
|
1128
|
-
chore: 构建/工具变动
|
|
1129
|
-
```
|
|
1130
|
-
|
|
1131
|
-
### 开发流程
|
|
1132
|
-
|
|
1133
|
-
1. Fork 仓库
|
|
1134
|
-
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
|
|
1135
|
-
3. 提交更改 (`git commit -m 'feat: add amazing feature'`)
|
|
1136
|
-
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
|
1137
|
-
5. 创建 Pull Request
|
|
1138
|
-
|
|
1139
|
-
---
|
|
1140
|
-
|
|
1141
|
-
## 📋 更新日志
|
|
1142
|
-
|
|
1143
|
-
### 2.8.5
|
|
1144
|
-
- 当前稳定版本
|
|
1145
|
-
- 完整的插件系统架构
|
|
1146
|
-
- 支持多种图形元素
|
|
1147
|
-
- 导入/导出功能
|
|
1148
|
-
- 撤销/重做机制
|
|
1149
|
-
|
|
1150
|
-
### 版本历史
|
|
1151
|
-
详细版本历史请查看 [GitHub Releases](https://github.com/pwg-code/vkedit/releases)
|
|
1152
|
-
|
|
1153
|
-
---
|
|
1154
|
-
|
|
1155
|
-
## 📄 许可证
|
|
1156
|
-
|
|
1157
|
-
本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件
|
|
1158
|
-
|
|
1159
|
-
---
|
|
1160
|
-
|
|
1161
|
-
## 🔗 相关链接
|
|
1162
|
-
|
|
1163
|
-
- [Vue.js](https://vuejs.org/)
|
|
1164
|
-
- [Konva.js](https://konvajs.org/)
|
|
1165
|
-
- [vue-konva](https://www.npmjs.com/package/vue-konva)
|
|
1166
|
-
- [Pinia](https://pinia.vuejs.org/)
|
|
1167
|
-
|
|
1168
|
-
---
|
|
1169
|
-
|
|
1170
|
-
## ☕ 支持作者
|
|
1171
|
-
|
|
1172
|
-
如果您觉得 vkedit 对您有帮助,欢迎支持作者喝杯咖啡!您的支持是项目持续发展的动力。
|
|
1173
|
-
|
|
1174
|
-
<div align="center">
|
|
1175
|
-
|
|
1176
|
-
**Made with ❤️ by vkedit contributors**
|
|
1177
|
-
|
|
1178
|
-
</div>
|
|
1179
|
-
|
|
1180
|
-
---
|
|
1181
|
-
|
|
1182
|
-
## 📞 联系支持
|
|
1183
|
-
|
|
1184
|
-
如果您需要技术支持、功能定制或有任何问题,欢迎随时联系:
|
|
1185
|
-
|
|
1186
|
-
- **QQ**: 16871824
|
|
1187
|
-
- **邮箱**: 168715824@qq.com
|
|
1188
|
-
- **服务**: 技术支持、功能定制、项目合作
|
|
1189
|
-
|
|
1190
|
-
期待与您交流,共同完善 vkedit!
|
|
1
|
+
# vkedit
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/vkedit)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](package.json)
|
|
6
|
+
|
|
7
|
+
基于 Vue 3 与 Konva.js 的可视化画布设计器组件,采用插件化架构,适用于标签、二维码、条码、票据、名片、证书等模板设计与打印排版场景。
|
|
8
|
+
|
|
9
|
+
**[English](README.en.md)**
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 特性
|
|
18
|
+
|
|
19
|
+
- **插件化架构** — 核心功能与图形元素均以插件形式注册,按需启用
|
|
20
|
+
- **7 种图形元素** — 矩形、文本、线条、表格、二维码、条形码、图表(ECharts)
|
|
21
|
+
- **撤销/重做** — 基于命令模式,所有修改操作可逆
|
|
22
|
+
- **导入/导出** — JSON 序列化、PNG/JPG 图片、PDF 文档
|
|
23
|
+
- **对齐与分布** — 左/右/上/下/居中对齐、水平/垂直均分
|
|
24
|
+
- **标尺与缩放** — 毫米级精度标尺、可配置 DPM(每毫米点数)
|
|
25
|
+
- **事件驱动** — 类型安全的事件系统,插件间松耦合通信
|
|
26
|
+
- **TypeScript** — 完整类型定义,泛型推断插件与元素类型
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 安装
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add vkedit vue konva vue-konva
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
vkedit 将 `vue`、`konva`、`vue-konva` 作为 peerDependencies,需由宿主项目提供。
|
|
37
|
+
|
|
38
|
+
| Peer Dependency | 版本 |
|
|
39
|
+
| --------------- | ------- |
|
|
40
|
+
| vue | ^3.5.18 |
|
|
41
|
+
| konva | ^10.0.2 |
|
|
42
|
+
| vue-konva | ^3.2.6 |
|
|
43
|
+
|
|
44
|
+
Node.js 要求:`^20.19.0 || >=22.12.0`
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 快速上手
|
|
49
|
+
|
|
50
|
+
### 1. 配置入口文件
|
|
51
|
+
|
|
52
|
+
在 `main.ts` 中注册 VueKonva 并引入样式:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { createApp } from 'vue'
|
|
56
|
+
import App from './App.vue'
|
|
57
|
+
import VueKonva from 'vue-konva'
|
|
58
|
+
import 'vkedit/dist/vkedit.css'
|
|
59
|
+
|
|
60
|
+
const app = createApp(App)
|
|
61
|
+
app.use(VueKonva)
|
|
62
|
+
app.mount('#app')
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 2. 使用编辑器组件
|
|
66
|
+
|
|
67
|
+
```vue
|
|
68
|
+
<template>
|
|
69
|
+
<Vkedit :host="host" />
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<script setup lang="ts">
|
|
73
|
+
import { createEditorHost, Vkedit } from 'vkedit'
|
|
74
|
+
import {
|
|
75
|
+
RectPlugin,
|
|
76
|
+
TextPlugin,
|
|
77
|
+
TablePlugin,
|
|
78
|
+
QrcodePlugin,
|
|
79
|
+
BarcodePlugin,
|
|
80
|
+
ChartPlugin,
|
|
81
|
+
LinePlugin,
|
|
82
|
+
} from 'vkedit'
|
|
83
|
+
|
|
84
|
+
const host = createEditorHost()
|
|
85
|
+
|
|
86
|
+
// 安装图形插件
|
|
87
|
+
host
|
|
88
|
+
.installPlugin('rect-plugin', RectPlugin)
|
|
89
|
+
.installPlugin('text-plugin', TextPlugin)
|
|
90
|
+
.installPlugin('table-plugin', TablePlugin)
|
|
91
|
+
.installPlugin('qr-plugin', QrcodePlugin)
|
|
92
|
+
.installPlugin('barcode-plugin', BarcodePlugin)
|
|
93
|
+
.installPlugin('chart-plugin', ChartPlugin)
|
|
94
|
+
.installPlugin('line-plugin', LinePlugin)
|
|
95
|
+
|
|
96
|
+
// 设置画布尺寸(A4 纸张,DPM = 8)
|
|
97
|
+
host.setStatus({
|
|
98
|
+
dpm: 8,
|
|
99
|
+
width: 210 * 8,
|
|
100
|
+
height: 297 * 8,
|
|
101
|
+
zoom: 0.4,
|
|
102
|
+
})
|
|
103
|
+
</script>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Vkedit 组件 Props
|
|
107
|
+
|
|
108
|
+
| Prop | 类型 | 默认值 | 说明 |
|
|
109
|
+
| ------------------- | ------------ | ------ | ---------------- |
|
|
110
|
+
| `host` | `EditorHost` | — | 编辑器宿主实例 |
|
|
111
|
+
| `showToolbox` | `boolean` | `true` | 显示左侧工具箱 |
|
|
112
|
+
| `showPropertyPanel` | `boolean` | `true` | 显示右侧属性面板 |
|
|
113
|
+
| `showToolbar` | `boolean` | `true` | 显示顶部工具栏 |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 配置
|
|
118
|
+
|
|
119
|
+
### createEditorHost 选项
|
|
120
|
+
|
|
121
|
+
`createEditorHost(options)` 创建宿主实例并自动安装核心插件。可选插件通过以下选项控制:
|
|
122
|
+
|
|
123
|
+
| 选项 | 类型 | 默认值 | 说明 |
|
|
124
|
+
| ------------------------- | --------- | ------- | ---------------- |
|
|
125
|
+
| `basePropertyPanel` | `boolean` | `false` | 基础元素属性面板 |
|
|
126
|
+
| `baseCanvasPropertyPanel` | `boolean` | `true` | 画布属性面板 |
|
|
127
|
+
| `exportPlugin` | `boolean` | `true` | 导出插件 |
|
|
128
|
+
| `previewPlugin` | `boolean` | `true` | 预览插件 |
|
|
129
|
+
| `importPlugin` | `boolean` | `true` | 导入插件 |
|
|
130
|
+
|
|
131
|
+
### 画布状态
|
|
132
|
+
|
|
133
|
+
通过 `host.setStatus()` 更新画布状态,支持部分更新:
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface IEditorState {
|
|
137
|
+
zoom: number // 缩放级别
|
|
138
|
+
currentTool: string // 当前工具
|
|
139
|
+
snapToGrid: boolean // 网格吸附
|
|
140
|
+
showGrid: boolean // 网格显示
|
|
141
|
+
width: number // 画布宽度(像素)
|
|
142
|
+
height: number // 画布高度(像素)
|
|
143
|
+
wmm: number // 画布宽度(毫米)
|
|
144
|
+
hmm: number // 画布高度(毫米)
|
|
145
|
+
dpm: number // 每毫米点数(DPI / 25.4)
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`width`/`height` 与 `wmm`/`hmm` 通过 `dpm` 自动换算。设置 `dpm` 会以当前毫米尺寸重新计算像素宽高。
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 插件列表
|
|
154
|
+
|
|
155
|
+
### 核心插件(createEditorHost 自动安装)
|
|
156
|
+
|
|
157
|
+
| 插件 | 说明 |
|
|
158
|
+
| ---------------------------- | ---------------- |
|
|
159
|
+
| `ToolbarManagerPlugin` | 顶部工具栏管理 |
|
|
160
|
+
| `GraphicToolManagerPlugin` | 图形工具管理 |
|
|
161
|
+
| `GraphicManagerPlugin` | 图形渲染管理 |
|
|
162
|
+
| `PropertyPanelManagerPlugin` | 属性面板动态渲染 |
|
|
163
|
+
| `ElementManagerPlugin` | 元素生命周期管理 |
|
|
164
|
+
| `SelectionPlugin` | 元素选择与多选 |
|
|
165
|
+
| `KeyDownPlugin` | 键盘快捷键 |
|
|
166
|
+
| `SnapPlugin` | 网格吸附 |
|
|
167
|
+
| `ClipboardPlugin` | 复制/剪切/粘贴 |
|
|
168
|
+
| `AlignPlugin` | 对齐与分布 |
|
|
169
|
+
| `ContextMenuManagerPlugin` | 右键菜单 |
|
|
170
|
+
|
|
171
|
+
### 功能插件(通过选项启用)
|
|
172
|
+
|
|
173
|
+
| 插件 | 选项 | 说明 |
|
|
174
|
+
| --------------- | --------------- | --------------------------- |
|
|
175
|
+
| `ExportPlugin` | `exportPlugin` | 导出 JSON / PNG / JPG / PDF |
|
|
176
|
+
| `ImportPlugin` | `importPlugin` | 导入 JSON 文件 |
|
|
177
|
+
| `PreviewPlugin` | `previewPlugin` | 预览与打印预览 |
|
|
178
|
+
|
|
179
|
+
### 图形插件(手动安装)
|
|
180
|
+
|
|
181
|
+
| 插件 | 元素类型 | 说明 |
|
|
182
|
+
| --------------- | --------- | ----------------------------------- |
|
|
183
|
+
| `RectPlugin` | `rect` | 矩形,支持填充、描边 |
|
|
184
|
+
| `TextPlugin` | `text` | 文本,支持字体、对齐、样式 |
|
|
185
|
+
| `LinePlugin` | `line` | 线条,支持颜色、宽度 |
|
|
186
|
+
| `TablePlugin` | `table` | 表格,支持行列、合并单元格、边框 |
|
|
187
|
+
| `QrcodePlugin` | `qr` | 二维码,支持前景/背景色 |
|
|
188
|
+
| `BarcodePlugin` | `barcode` | 条形码,支持 CODE128、EAN-13 等格式 |
|
|
189
|
+
| `ChartPlugin` | `chart` | 图表,基于 ECharts |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 核心概念
|
|
194
|
+
|
|
195
|
+
### EditorHost
|
|
196
|
+
|
|
197
|
+
`EditorHost` 是编辑器的核心宿主类,管理插件、状态、命令和历史记录。通过 `createEditorHost()` 创建实例后,所有操作都围绕 `host` 进行。
|
|
198
|
+
|
|
199
|
+
### 插件系统
|
|
200
|
+
|
|
201
|
+
插件通过 `installPlugin` / `uninstallPlugin` / `getPlugin` 管理。插件需继承 `BasePlugin` 并实现 `onInstall()` 钩子。`getPlugin` 支持泛型推断:
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const rectPlugin = host.getPlugin('rect-plugin') // 自动推断为 RectPlugin
|
|
205
|
+
const exportPlugin = host.getPlugin('export-plugin')
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### 命令模式
|
|
209
|
+
|
|
210
|
+
所有可撤销的操作通过命令实现。`executeCommand()` 执行命令并压入历史栈,`undo()` / `redo()` 在栈中导航:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
host.executeCommand(command) // 执行并入栈
|
|
214
|
+
host.undo() // 撤销
|
|
215
|
+
host.redo() // 重做
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 事件系统
|
|
219
|
+
|
|
220
|
+
编辑器通过 `emit` / `on` / `off` 实现类型安全的事件通信:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// 监听元素添加
|
|
224
|
+
host.on('element:added', (payload) => {
|
|
225
|
+
console.log('元素已添加:', payload.element)
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
// 监听选择变化
|
|
229
|
+
host.on('selection:changed', (payload) => {
|
|
230
|
+
console.log('选中元素:', payload.selection)
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
完整事件列表及自定义事件扩展请参阅 API 文档。
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 常用操作
|
|
239
|
+
|
|
240
|
+
### 导出 / 导入 JSON
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
// 导出为 JSON 字符串
|
|
244
|
+
const json = host.toJSON()
|
|
245
|
+
|
|
246
|
+
// 从 JSON 字符串加载
|
|
247
|
+
host.loadJSON(json)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
通过 ExportPlugin / ImportPlugin 可触发文件下载和文件选择:
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
const exportPlugin = host.getPlugin('export-plugin')
|
|
254
|
+
exportPlugin.handleExportJSON() // 下载 .json 文件
|
|
255
|
+
exportPlugin.handleExportImage() // 下载 PNG 图片
|
|
256
|
+
exportPlugin.handleExportPdf() // 下载 PDF 文档
|
|
257
|
+
|
|
258
|
+
const importPlugin = host.getPlugin('import-plugin')
|
|
259
|
+
importPlugin.handleImportJSON() // 弹出文件选择器
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 撤销 / 重做
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
host.undo()
|
|
266
|
+
host.redo()
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### 监听事件
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
host.on('selection:changed', (payload) => {
|
|
273
|
+
console.log('选中元素 ID:', payload.selection)
|
|
274
|
+
})
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 添加元素(通过命令)
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import { AddElementCommand } from 'vkedit'
|
|
281
|
+
|
|
282
|
+
const elementManager = host.getPlugin('element-manager-plugin')
|
|
283
|
+
const element = elementManager.createElement('rect')
|
|
284
|
+
host.executeCommand(new AddElementCommand(host, element))
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### 更新元素属性(通过命令)
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { UpdatePropertyCommand } from 'vkedit'
|
|
291
|
+
|
|
292
|
+
host.executeCommand(
|
|
293
|
+
new UpdatePropertyCommand(host, element, 'fill', 'red', 'blue')
|
|
294
|
+
)
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### 批量操作
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
import { BatchCommand, UpdatePropertyCommand } from 'vkedit'
|
|
301
|
+
|
|
302
|
+
const batch = new BatchCommand(host, [
|
|
303
|
+
new UpdatePropertyCommand(host, el1, 'fill', 'red', 'blue'),
|
|
304
|
+
new UpdatePropertyCommand(host, el2, 'fill', 'red', 'green'),
|
|
305
|
+
])
|
|
306
|
+
host.executeCommand(batch)
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## 适用场景
|
|
312
|
+
|
|
313
|
+
| 场景 | 适用插件 |
|
|
314
|
+
| ------------ | -------------------------------- |
|
|
315
|
+
| 标签模板设计 | 二维码、条形码、文本、矩形、表格 |
|
|
316
|
+
| 二维码设计 | 二维码、文本、矩形 |
|
|
317
|
+
| 条码设计 | 条形码、文本、线条 |
|
|
318
|
+
| 票据设计 | 表格、文本、矩形、线条 |
|
|
319
|
+
| 名片设计 | 文本、矩形、线条 |
|
|
320
|
+
| 证书设计 | 文本、矩形、表格 |
|
|
321
|
+
| 数据可视化 | 图表、文本、矩形 |
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 可用命令
|
|
326
|
+
|
|
327
|
+
| 命令 | 构造参数 | 说明 |
|
|
328
|
+
| --------------------------- | --------------------------------------------------- | -------------------------- |
|
|
329
|
+
| `AddElementCommand` | `(host, element)` | 添加元素 |
|
|
330
|
+
| `RemoveElementCommand` | `(host, element)` | 移除元素 |
|
|
331
|
+
| `TransformElementCommand` | `(host, element, oldState, newState)` | 变换元素(位置/大小/旋转) |
|
|
332
|
+
| `UpdatePropertyCommand` | `(host, element, propertyPath, oldValue, newValue)` | 更新属性 |
|
|
333
|
+
| `BatchCommand` | `(host, commands, description?)` | 批量命令 |
|
|
334
|
+
| `AlignElementsCommand` | `(host, alignment, elementIds)` | 对齐元素 |
|
|
335
|
+
| `DistributeElementsCommand` | `(host, direction, elementIds)` | 分布元素 |
|
|
336
|
+
| `ChangeLayerOrderCommand` | `(host, elementId, direction)` | 调整图层顺序 |
|
|
337
|
+
| `ClearSelectionCommand` | `(host)` | 清空选择 |
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## 链接
|
|
342
|
+
|
|
343
|
+
- [npm](https://www.npmjs.com/package/vkedit)
|
|
344
|
+
- [GitHub Releases](https://github.com/pwg-code/vkedit/releases)
|
|
345
|
+
- [Vue.js](https://vuejs.org/)
|
|
346
|
+
- [Konva.js](https://konvajs.org/)
|
|
347
|
+
- [vue-konva](https://www.npmjs.com/package/vue-konva)
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## License
|
|
352
|
+
|
|
353
|
+
[MIT](LICENSE)
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## 联系方式
|
|
358
|
+
|
|
359
|
+
- **QQ**: 16871824
|
|
360
|
+
- **邮箱**: 168715824@qq.com
|
|
361
|
+
|
|
362
|
+
提供技术支持、功能定制、项目合作。
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
如果 vkedit 对您有帮助,欢迎请作者喝杯咖啡。
|
|
367
|
+
|
|
368
|
+
<div align="center">
|
|
369
|
+
|
|
370
|
+
<table>
|
|
371
|
+
<tr>
|
|
372
|
+
<td align="center">
|
|
373
|
+
<img src="./截图/reward-alipay.png" width="200" alt="支付宝打赏" />
|
|
374
|
+
<br>支付宝
|
|
375
|
+
</td>
|
|
376
|
+
<td align="center">
|
|
377
|
+
<img src="./截图/reward-wechat.png" width="200" alt="微信打赏" />
|
|
378
|
+
<br>微信
|
|
379
|
+
</td>
|
|
380
|
+
</tr>
|
|
381
|
+
</table>
|
|
382
|
+
|
|
383
|
+
</div>
|