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.en.md
CHANGED
|
@@ -1,1193 +1,385 @@
|
|
|
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
|
-
import
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
app
|
|
61
|
-
app.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
385
|
-
|
|
386
|
-
A --> F[ScrollbarLayer Scrollbar Layer]
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
---
|
|
390
|
-
|
|
391
|
-
## 📁 Project Structure
|
|
392
|
-
|
|
393
|
-
```
|
|
394
|
-
vkedit/
|
|
395
|
-
├── src/
|
|
396
|
-
│ ├── commands/ # Command pattern implementation
|
|
397
|
-
│ │ ├── base-command.ts
|
|
398
|
-
│ │ ├── add-element-command.ts
|
|
399
|
-
│ │ ├── remove-element-command.ts
|
|
400
|
-
│ │ ├── transform-element-command.ts
|
|
401
|
-
│ │ ├── update-property-command.ts
|
|
402
|
-
│ │ ├── batch-command.ts
|
|
403
|
-
│ │ ├── align-elements-command.ts
|
|
404
|
-
│ │ └── ...
|
|
405
|
-
│ ├── components/ # Vue components
|
|
406
|
-
│ │ ├── ui/ # Unified UI component library
|
|
407
|
-
│ │ │ ├── button/
|
|
408
|
-
│ │ │ ├── dropdown-menu/
|
|
409
|
-
│ │ │ ├── input/
|
|
410
|
-
│ │ │ ├── select/
|
|
411
|
-
│ │ │ └── ...
|
|
412
|
-
│ │ ├── BaseElementPropertyPanel.vue
|
|
413
|
-
│ │ ├── CanvasPropertyPanel.vue
|
|
414
|
-
│ │ └── ...
|
|
415
|
-
│ ├── core/ # Core editor components
|
|
416
|
-
│ │ ├── Editor.vue
|
|
417
|
-
│ │ ├── editor-host.ts
|
|
418
|
-
│ │ ├── StageView.vue
|
|
419
|
-
│ │ ├── Toolbar.vue
|
|
420
|
-
│ │ ├── PropertyPanel.vue
|
|
421
|
-
│ │ ├── BgLayer.vue
|
|
422
|
-
│ │ ├── ContentLayer.vue
|
|
423
|
-
│ │ ├── SelectionLayer.vue
|
|
424
|
-
│ │ ├── RulerLayer.vue
|
|
425
|
-
│ │ ├── ScrollbarLayer.vue
|
|
426
|
-
│ │ ├── ContextMenu.vue
|
|
427
|
-
│ │ ├── Zoom.vue
|
|
428
|
-
│ │ └── Toolbox.vue
|
|
429
|
-
│ ├── hooks/ # Vue composition functions
|
|
430
|
-
│ │ ├── use-host-state.ts
|
|
431
|
-
│ │ ├── use-bg-layer.ts
|
|
432
|
-
│ │ ├── use-content-layer.ts
|
|
433
|
-
│ │ ├── use-selection-layer.ts
|
|
434
|
-
│ │ ├── use-ruler-layer.ts
|
|
435
|
-
│ │ ├── use-scrollbar-layer.ts
|
|
436
|
-
│ │ ├── use-zoom.ts
|
|
437
|
-
│ │ └── use-stage-event.ts
|
|
438
|
-
│ ├── plugins/ # Plugin system
|
|
439
|
-
│ │ ├── element-manager.ts
|
|
440
|
-
│ │ ├── graphic-tool-manager.ts
|
|
441
|
-
│ │ ├── graphic-manager.ts
|
|
442
|
-
│ │ ├── selection.ts
|
|
443
|
-
│ │ ├── toolbar-manager.ts
|
|
444
|
-
│ │ ├── keydown.ts
|
|
445
|
-
│ │ ├── align/
|
|
446
|
-
│ │ │ ├── Align.vue
|
|
447
|
-
│ │ │ └── align.ts
|
|
448
|
-
│ │ ├── export/
|
|
449
|
-
│ │ │ ├── Export.vue
|
|
450
|
-
│ │ │ └── export.ts
|
|
451
|
-
│ │ ├── import/
|
|
452
|
-
│ │ │ ├── Import.vue
|
|
453
|
-
│ │ │ └── import.ts
|
|
454
|
-
│ │ ├── preview/
|
|
455
|
-
│ │ │ ├── PreviewButton.vue
|
|
456
|
-
│ │ │ └── preview.ts
|
|
457
|
-
│ │ ├── rect/
|
|
458
|
-
│ │ │ ├── RectPlugin.ts
|
|
459
|
-
│ │ │ ├── Shape.vue
|
|
460
|
-
│ │ │ ├── PropertyPanel.vue
|
|
461
|
-
│ │ │ └── Tool.vue
|
|
462
|
-
│ │ ├── text/
|
|
463
|
-
│ │ ├── table/
|
|
464
|
-
│ │ ├── qrcode/
|
|
465
|
-
│ │ ├── barcode/
|
|
466
|
-
│ │ ├── chart/
|
|
467
|
-
│ │ ├── line/
|
|
468
|
-
│ │ └── context-menu-manager/
|
|
469
|
-
│ ├── stores/ # Pinia state management
|
|
470
|
-
│ ├── types/ # TypeScript type definitions
|
|
471
|
-
│ │ ├── base-graphic-element.ts
|
|
472
|
-
│ │ ├── base-graphic-type.ts
|
|
473
|
-
│ │ ├── base-plugin.ts
|
|
474
|
-
│ │ ├── event-map.ts
|
|
475
|
-
│ │ ├── event-data.ts
|
|
476
|
-
│ │ └── ...
|
|
477
|
-
│ ├── styles/ # Style files
|
|
478
|
-
│ ├── create-host.ts # Host creation function
|
|
479
|
-
│ └── index.ts # Entry file
|
|
480
|
-
├── playground/ # Example project
|
|
481
|
-
│ ├── App.vue
|
|
482
|
-
│ └── main.ts
|
|
483
|
-
├── package.json
|
|
484
|
-
├── vite.config.ts
|
|
485
|
-
├── tsconfig.json
|
|
486
|
-
└── README.md
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
---
|
|
490
|
-
|
|
491
|
-
## 🔌 Available Plugin List
|
|
492
|
-
|
|
493
|
-
### Core Plugins
|
|
494
|
-
|
|
495
|
-
| Plugin Name | Description |
|
|
496
|
-
| ------------------------------ | ---------------------------------------------------------------------------- |
|
|
497
|
-
| **ToolbarManagerPlugin** | Toolbar manager, providing top toolbar functionality |
|
|
498
|
-
| **GraphicToolManagerPlugin** | Graphic tool manager, managing graphic drawing tools |
|
|
499
|
-
| **GraphicManagerPlugin** | Graphic manager, unified management of all graphic elements |
|
|
500
|
-
| **ElementManagerPlugin** | Element manager, managing element lifecycle |
|
|
501
|
-
| **SelectionPlugin** | Selection plugin, handling element selection and multi-selection operations |
|
|
502
|
-
| **PropertyPanelManagerPlugin** | Property property panel manager, dynamically rendering property panels |
|
|
503
|
-
| **KeyDownPlugin** | Keyboard event plugin, handling shortcuts |
|
|
504
|
-
| **AlignPlugin** | Alignment plugin, providing element alignment and distribution functionality |
|
|
505
|
-
| **ContextMenuManagerPlugin** | Context menu manager |
|
|
506
|
-
|
|
507
|
-
### Feature Plugins
|
|
508
|
-
|
|
509
|
-
| Plugin Name | Description |
|
|
510
|
-
| ----------------- | ------------------------------------------------------------------------- |
|
|
511
|
-
| **ExportPlugin** | Export plugin, supporting export to JSON, PNG, JPG, PDF and other formats |
|
|
512
|
-
| **ImportPlugin** | Import plugin, supporting importing design data from JSON files |
|
|
513
|
-
| **PreviewPlugin** | Preview plugin, providing design preview functionality |
|
|
514
|
-
|
|
515
|
-
### Graphic Plugins
|
|
516
|
-
|
|
517
|
-
| Plugin Name | Graphic Type | Description |
|
|
518
|
-
| ----------------- | ------------ | ------------------------------------------------------------------- |
|
|
519
|
-
| **RectPlugin** | Rectangle | Rectangle elements with drag, resize, fill and border adjustments |
|
|
520
|
-
| **TextPlugin** | Text | Text elements supporting font, size, color, and alignment |
|
|
521
|
-
| **LinePlugin** | Line | Line elements supporting start point, end point, color, and width |
|
|
522
|
-
| **TablePlugin** | Table | Table elements supporting rows/columns, borders, and text alignment |
|
|
523
|
-
| **QrcodePlugin** | QR Code | Configurable QR code elements |
|
|
524
|
-
| **BarcodePlugin** | Barcode | Barcodes supporting multiple formats (EAN-13, CODE-128, etc.) |
|
|
525
|
-
| **ChartPlugin** | Chart | Chart elements based on ECharts |
|
|
526
|
-
|
|
527
|
-
---
|
|
528
|
-
|
|
529
|
-
## 📚 API Reference
|
|
530
|
-
|
|
531
|
-
### createEditorHost()
|
|
532
|
-
|
|
533
|
-
Creates an editor host instance and installs core plugins.
|
|
534
|
-
|
|
535
|
-
```typescript
|
|
536
|
-
function createEditorHost(options: IOptions): EditorHost
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
**Parameters:**
|
|
540
|
-
|
|
541
|
-
```typescript
|
|
542
|
-
interface IOptions {
|
|
543
|
-
basePropertyPanel?: boolean // Enable base element property panel
|
|
544
|
-
baseCanvasPropertyPanel?: boolean // Enable canvas property panel
|
|
545
|
-
exportPlugin?: boolean // Enable export plugin
|
|
546
|
-
previewPlugin?: boolean // Enable preview plugin
|
|
547
|
-
importPlugin?: boolean // Enable import plugin
|
|
548
|
-
}
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
**Returns:** `EditorHost` instance
|
|
552
|
-
|
|
553
|
-
---
|
|
554
|
-
|
|
555
|
-
### EditorHost Class Methods
|
|
556
|
-
|
|
557
|
-
#### Plugin Management
|
|
558
|
-
|
|
559
|
-
| Method | Description |
|
|
560
|
-
| ---------------------------------- | ------------------- |
|
|
561
|
-
| `installPlugin(name, pluginClass)` | Install plugin |
|
|
562
|
-
| `uninstallPlugin(pluginName)` | Uninstall plugin |
|
|
563
|
-
| `getPlugin<T>(pluginName)` | Get plugin instance |
|
|
564
|
-
|
|
565
|
-
```typescript
|
|
566
|
-
// Install plugin
|
|
567
|
-
host.installPlugin('rect-plugin', RectPlugin)
|
|
568
|
-
|
|
569
|
-
// Uninstall plugin
|
|
570
|
-
host.uninstallPlugin('rect-plugin')
|
|
571
|
-
|
|
572
|
-
// Get plugin instance
|
|
573
|
-
const rectPlugin = host.getPlugin<RectPlugin>('rect-plugin')
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
#### Command Operations
|
|
577
|
-
|
|
578
|
-
| Method | Description |
|
|
579
|
-
| ------------------------- | --------------- |
|
|
580
|
-
| `executeCommand(command)` | Execute command |
|
|
581
|
-
| `undo()` | Undo |
|
|
582
|
-
| `redo()` | Redo |
|
|
583
|
-
|
|
584
|
-
```typescript
|
|
585
|
-
import { AddElementCommand } from 'vkedit'
|
|
586
|
-
|
|
587
|
-
// Execute command
|
|
588
|
-
const command = new AddElementCommand(element, host)
|
|
589
|
-
host.executeCommand(command)
|
|
590
|
-
|
|
591
|
-
// Undo
|
|
592
|
-
host.undo()
|
|
593
|
-
|
|
594
|
-
// Redo
|
|
595
|
-
host.redo()
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
#### Event System
|
|
599
|
-
|
|
600
|
-
| Method | Description |
|
|
601
|
-
| ---------------------- | ------------------ |
|
|
602
|
-
| `emit(event, payload)` | Trigger event |
|
|
603
|
-
| `on(event, handler)` | Subscribe to event |
|
|
604
|
-
| `off(event, handler)` | Unsubscribe |
|
|
605
|
-
|
|
606
|
-
```typescript
|
|
607
|
-
// Subscribe to event
|
|
608
|
-
host.on('element:added', (payload) => {
|
|
609
|
-
console.log('Element added:', payload)
|
|
610
|
-
})
|
|
611
|
-
|
|
612
|
-
// Trigger event
|
|
613
|
-
host.emit('element:added', { element: myElement })
|
|
614
|
-
|
|
615
|
-
// Unsubscribe
|
|
616
|
-
host.off('element:added')
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
#### State Management
|
|
620
|
-
|
|
621
|
-
| Property | Type | Description |
|
|
622
|
-
| -------- | -------------- | ------------------------ |
|
|
623
|
-
| `status` | `IEditorState` | Editor state (read-only) |
|
|
624
|
-
|
|
625
|
-
```typescript
|
|
626
|
-
interface IEditorState {
|
|
627
|
-
zoom: number // Zoom level
|
|
628
|
-
currentTool: string // Current tool
|
|
629
|
-
snapToGrid: boolean // Whether to snap to grid
|
|
630
|
-
showGrid: boolean // Whether to show grid
|
|
631
|
-
width: number // Canvas width (pixels)
|
|
632
|
-
height: number // Canvas height (pixels)
|
|
633
|
-
wmm: number // Canvas width (mm)
|
|
634
|
-
hmm: number // Canvas height (mm)
|
|
635
|
-
dpm: number // Dots per millimeter
|
|
636
|
-
}
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
```typescript
|
|
640
|
-
// Update state
|
|
641
|
-
host.setStatus({
|
|
642
|
-
zoom: 1,
|
|
643
|
-
width: 800,
|
|
644
|
-
height: 600
|
|
645
|
-
})
|
|
646
|
-
|
|
647
|
-
// Read state
|
|
648
|
-
console.log(host.status.zoom)
|
|
649
|
-
```
|
|
650
|
-
|
|
651
|
-
#### Serialization
|
|
652
|
-
|
|
653
|
-
| Method | Description |
|
|
654
|
-
| ------------------- | ----------------------- |
|
|
655
|
-
| `toJSON()` | Export as JSON string |
|
|
656
|
-
| `loadJSON(jsonStr)` | Import from JSON string |
|
|
657
|
-
|
|
658
|
-
```typescript
|
|
659
|
-
// Export
|
|
660
|
-
const json = host.toJSON()
|
|
661
|
-
|
|
662
|
-
// Import
|
|
663
|
-
host.loadJSON(json)
|
|
664
|
-
```
|
|
665
|
-
|
|
666
|
-
---
|
|
667
|
-
|
|
668
|
-
## 🎯 Event System
|
|
669
|
-
|
|
670
|
-
The editor provides rich event types, supporting loose coupling communication between plugins.
|
|
671
|
-
|
|
672
|
-
### Lifecycle Events
|
|
673
|
-
|
|
674
|
-
| Event Name | Description |
|
|
675
|
-
| ---------------- | ---------------- |
|
|
676
|
-
| `editor:ready` | Editor ready |
|
|
677
|
-
| `editor:destroy` | Editor destroyed |
|
|
678
|
-
| `editor:reset` | Editor reset |
|
|
679
|
-
|
|
680
|
-
### File Operation Events
|
|
681
|
-
|
|
682
|
-
| Event Name | Description |
|
|
683
|
-
| ---------------------- | ------------------------------- |
|
|
684
|
-
| `file:new` | New file |
|
|
685
|
-
| `file:open` | Open file |
|
|
686
|
-
| `file:save` | Save file |
|
|
687
|
-
| `file:save-as` | Save as |
|
|
688
|
-
| `file:export` | Export file |
|
|
689
|
-
| `file:import` | Import file |
|
|
690
|
-
| `file:loaded` | File loaded |
|
|
691
|
-
| `file:saved` | File saved |
|
|
692
|
-
| `file:modified-change` | File modification state changed |
|
|
693
|
-
|
|
694
|
-
### Stage Interaction Events
|
|
695
|
-
|
|
696
|
-
| Event Name | Description |
|
|
697
|
-
| ------------------- | ------------------ |
|
|
698
|
-
| `stage:mousedown` | Mouse down |
|
|
699
|
-
| `stage:mousemove` | Mouse move |
|
|
700
|
-
| `stage:mouseup` | Mouse up |
|
|
701
|
-
| `stage:click` | Mouse click |
|
|
702
|
-
| `stage:dblclick` | Mouse double click |
|
|
703
|
-
| `stage:contextmenu` | Context menu |
|
|
704
|
-
| `stage:wheel` | Mouse wheel |
|
|
705
|
-
| `stage:dragstart` | Drag start |
|
|
706
|
-
| `stage:dragend` | Drag end |
|
|
707
|
-
| `stage:redraw` | Stage redraw |
|
|
708
|
-
|
|
709
|
-
### Keyboard Events
|
|
710
|
-
|
|
711
|
-
| Event Name | Description |
|
|
712
|
-
| ---------------------- | ----------- |
|
|
713
|
-
| `stage:keydown` | Key down |
|
|
714
|
-
| `stage:keydown-delete` | Delete key |
|
|
715
|
-
| `stage:keydown-left` | Left arrow |
|
|
716
|
-
| `stage:keydown-right` | Right arrow |
|
|
717
|
-
| `stage:keydown-up` | Up arrow |
|
|
718
|
-
| `stage:keydown-down` | Down arrow |
|
|
719
|
-
|
|
720
|
-
### Graphic Element Events
|
|
721
|
-
|
|
722
|
-
| Event Name | Description |
|
|
723
|
-
| --------------------------- | ------------------------- |
|
|
724
|
-
| `element:registered` | Element type registered |
|
|
725
|
-
| `element:unregistered` | Element type unregistered |
|
|
726
|
-
| `element:added` | Element added |
|
|
727
|
-
| `element:removed` | Element removed |
|
|
728
|
-
| `element:selected` | Element selected |
|
|
729
|
-
| `element:deselected` | Element deselected |
|
|
730
|
-
| `element:transformed` | Element transformed |
|
|
731
|
-
| `element:updated` | Element updated |
|
|
732
|
-
| `element:copied` | Element copied |
|
|
733
|
-
| `element:pasted` | Element pasted |
|
|
734
|
-
| `element:cloned` | Element cloned |
|
|
735
|
-
| `element:locked-change` | Lock state changed |
|
|
736
|
-
| `element:visibility-change` | Visibility changed |
|
|
737
|
-
| `element:zindex-change` | Z-index changed |
|
|
738
|
-
|
|
739
|
-
### Selection Events
|
|
740
|
-
|
|
741
|
-
| Event Name | Description |
|
|
742
|
-
| ------------------------ | ----------------------- |
|
|
743
|
-
| `selection:changed` | Selection changed |
|
|
744
|
-
| `selection:cleared` | Selection cleared |
|
|
745
|
-
| `selection:multi-change` | Multi-selection changed |
|
|
746
|
-
|
|
747
|
-
### View Events
|
|
748
|
-
|
|
749
|
-
| Event Name | Description |
|
|
750
|
-
| ------------------------------ | ---------------- |
|
|
751
|
-
| `view:zoom-change` | Zoom changed |
|
|
752
|
-
| `view:pan` | Pan |
|
|
753
|
-
| `view:zoom-to` | Fit to view |
|
|
754
|
-
| `view:reset` | Reset view |
|
|
755
|
-
| `view:grid-visibility-change` | Grid visibility |
|
|
756
|
-
| `view:snap-change` | Snap changed |
|
|
757
|
-
| `view:ruler-visibility-change` | Ruler visibility |
|
|
758
|
-
|
|
759
|
-
### Layer Events
|
|
760
|
-
|
|
761
|
-
| Event Name | Description |
|
|
762
|
-
| ------------------------- | ------------------- |
|
|
763
|
-
| `layer:added` | Layer added |
|
|
764
|
-
| `layer:removed` | Layer removed |
|
|
765
|
-
| `layer:order-changed` | Layer order changed |
|
|
766
|
-
| `layer:visibility-change` | Layer visibility |
|
|
767
|
-
| `layer:locked-change` | Layer locked |
|
|
768
|
-
| `layer:active-change` | Layer active |
|
|
769
|
-
|
|
770
|
-
### Command History Events
|
|
771
|
-
|
|
772
|
-
| Event Name | Description |
|
|
773
|
-
| ------------------ | ---------------- |
|
|
774
|
-
| `command:executed` | Command executed |
|
|
775
|
-
| `command:undone` | Command undone |
|
|
776
|
-
| `command:redone` | Command redone |
|
|
777
|
-
| `history:changed` | History changed |
|
|
778
|
-
| `history:cleared` | History cleared |
|
|
779
|
-
|
|
780
|
-
### Plugin System Events
|
|
781
|
-
|
|
782
|
-
| Event Name | Description |
|
|
783
|
-
| --------------------- | ------------------- |
|
|
784
|
-
| `plugin:registered` | Plugin registered |
|
|
785
|
-
| `plugin:unregistered` | Plugin unregistered |
|
|
786
|
-
| `plugin:activated` | Plugin activated |
|
|
787
|
-
| `plugin:deactivated` | Plugin deactivated |
|
|
788
|
-
| `plugin:loaded` | Plugin loaded |
|
|
789
|
-
| `plugin:error` | Plugin error |
|
|
790
|
-
|
|
791
|
-
### Alignment Distribution Events
|
|
792
|
-
|
|
793
|
-
| Event Name | Description |
|
|
794
|
-
| --------------------- | -------------------- |
|
|
795
|
-
| `elements:align` | Elements aligned |
|
|
796
|
-
| `elements:distribute` | Elements distributed |
|
|
797
|
-
| `elements:group` | Elements grouped |
|
|
798
|
-
| `elements:ungroup`` | Elements ungrouped |
|
|
799
|
-
| `elements:layer` | Layer operation |
|
|
800
|
-
|
|
801
|
-
### State Management Events
|
|
802
|
-
|
|
803
|
-
| Event Name | Description |
|
|
804
|
-
| ---------------------- | --------------- |
|
|
805
|
-
| `host:status-changed` | Status changed |
|
|
806
|
-
| `host:status-saved` | Status saved |
|
|
807
|
-
| `host:status-restored` | Status restored |
|
|
808
|
-
|
|
809
|
-
### Serialization Events
|
|
810
|
-
|
|
811
|
-
| Event Name | Description |
|
|
812
|
-
| ------------------------- | -------------------- |
|
|
813
|
-
| `host:load-json:start` | Load JSON start |
|
|
814
|
-
| `host:load-json:complete` | Load JSON complete |
|
|
815
|
-
| `host:load-json:error` | Load JSON error |
|
|
816
|
-
| `host:to-json:start` | Export JSON start |
|
|
817
|
-
| `host:to-json:complete` | Export JSON complete |
|
|
818
|
-
| `host:to-json:error` | Export JSON error |
|
|
819
|
-
|
|
820
|
-
### Event Usage Example
|
|
821
|
-
|
|
822
|
-
```typescript
|
|
823
|
-
import type { ElementEventData, SelectionEventData } from 'vkedit'
|
|
824
|
-
|
|
825
|
-
// Listen to element add event
|
|
826
|
-
host.on('element:added', (payload: ElementEventData) => {
|
|
827
|
-
console.log('New element added:', payload.element)
|
|
828
|
-
})
|
|
829
|
-
|
|
830
|
-
// Listen to selection change event
|
|
831
|
-
host.on('selection:changed', (payload: SelectionEventData) => {
|
|
832
|
-
console.log('Selected element count:', payload.selectedIds.length)
|
|
833
|
-
})
|
|
834
|
-
|
|
835
|
-
// Listen to status change
|
|
836
|
-
host.on('host:status-changed', (payload) => {
|
|
837
|
-
console.log('Status updated:', payload.status)
|
|
838
|
-
})
|
|
839
|
-
|
|
840
|
-
// Trigger custom event
|
|
841
|
-
host.emit('custom:my-event', { data: 'some data' })
|
|
842
|
-
```
|
|
843
|
-
|
|
844
|
-
### Extending Event System
|
|
845
|
-
|
|
846
|
-
Developers can extend the event map through module declarations:
|
|
847
|
-
|
|
848
|
-
```typescript
|
|
849
|
-
declare module '@/types' {
|
|
850
|
-
interface EventMap {
|
|
851
|
-
'my-plugin:some-event': (payload: MyEventData) => void
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
interface MyEventData {
|
|
856
|
-
id: string
|
|
857
|
-
value: number
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
// Use extended event
|
|
861
|
-
host.emit('my-plugin:some-event', { id: '123', value: 42 })
|
|
862
|
-
|
|
863
|
-
// Listen to extended event
|
|
864
|
-
host.on('my-plugin:some-event', (payload) => {
|
|
865
|
-
console.log(payload.value)
|
|
866
|
-
})
|
|
867
|
-
```
|
|
868
|
-
|
|
869
|
-
---
|
|
870
|
-
|
|
871
|
-
## 📝 Command System
|
|
872
|
-
|
|
873
|
-
vkedit uses the command pattern to implement undoable operations. All operations that modify the editor state should be executed through commands.
|
|
874
|
-
|
|
875
|
-
### Available Command Types
|
|
876
|
-
|
|
877
|
-
| Command Class | Description |
|
|
878
|
-
| ------------------------- | -------------------------------------------- |
|
|
879
|
-
| `AddElementCommand` | Add element |
|
|
880
|
-
| `RemoveElementCommand` | Remove element |
|
|
881
|
-
| `TransformElementCommand` | Transform element (position, size, rotation) |
|
|
882
|
-
| `UpdatePropertyCommand` | Update element property |
|
|
883
|
-
| `ClearSelectionCommand` | Clear selection |
|
|
884
|
-
| `BatchCommand` | Batch command |
|
|
885
|
-
| `ChangeLayerOrderCommand` | Change layer order |
|
|
886
|
-
| `AlignElementsCommand` | Align elements |
|
|
887
|
-
|
|
888
|
-
### Command Execution
|
|
889
|
-
|
|
890
|
-
```typescript
|
|
891
|
-
import { AddElementCommand, TransformElementCommand } from 'vkedit'
|
|
892
|
-
|
|
893
|
-
// Create and execute command
|
|
894
|
-
const command = new AddElementCommand(element, host)
|
|
895
|
-
host.executeCommand(command)
|
|
896
|
-
```
|
|
897
|
-
|
|
898
|
-
### Undo and Redo
|
|
899
|
-
|
|
900
|
-
```typescript
|
|
901
|
-
// Undo last operation
|
|
902
|
-
host.undo()
|
|
903
|
-
|
|
904
|
-
// Redo undone operation
|
|
905
|
-
host.redo()
|
|
906
|
-
```
|
|
907
|
-
|
|
908
|
-
### Batch Commands
|
|
909
|
-
|
|
910
|
-
```typescript
|
|
911
|
-
import { BatchCommand } from 'vkedit'
|
|
912
|
-
|
|
913
|
-
const commands = [
|
|
914
|
-
new UpdatePropertyCommand(element1, 'x', 100),
|
|
915
|
-
new UpdatePropertyCommand(element2, 'y', 200)
|
|
916
|
-
]
|
|
917
|
-
|
|
918
|
-
const batchCommand = new BatchCommand(commands)
|
|
919
|
-
host.executeCommand(batchCommand)
|
|
920
|
-
```
|
|
921
|
-
|
|
922
|
-
---
|
|
923
|
-
|
|
924
|
-
## 💻 Development Guide
|
|
925
|
-
|
|
926
|
-
### Development Environment Setup
|
|
927
|
-
|
|
928
|
-
```bash
|
|
929
|
-
# Clone repository
|
|
930
|
-
git clone https://github.com/pwg-code/vkedit.git
|
|
931
|
-
cd vkedit
|
|
932
|
-
|
|
933
|
-
# Install dependencies (recommended pnpm)
|
|
934
|
-
pnpm install
|
|
935
|
-
|
|
936
|
-
# Start development server
|
|
937
|
-
pnpm dev
|
|
938
|
-
|
|
939
|
-
# Type check
|
|
940
|
-
pnpm type-check
|
|
941
|
-
|
|
942
|
-
# Code check and fix
|
|
943
|
-
pnpm lint
|
|
944
|
-
|
|
945
|
-
# Code formatting
|
|
946
|
-
pnpm format
|
|
947
|
-
|
|
948
|
-
# Build production version
|
|
949
|
-
pnpm build
|
|
950
|
-
```
|
|
951
|
-
|
|
952
|
-
### Available Script Commands
|
|
953
|
-
|
|
954
|
-
| Command | Description |
|
|
955
|
-
| ----------------- | -------------------------- |
|
|
956
|
-
| `pnpm dev` | Start development server |
|
|
957
|
-
| `pnpm build` | Build production version |
|
|
958
|
-
| `pnpm build-only` | Build only (no type check) |
|
|
959
|
-
| `pnpm preview` | Preview production build |
|
|
960
|
-
| `pnpm type-check` | TypeScript type check |
|
|
961
|
-
| `pnpm lint` | ESLint check and auto-fix |
|
|
962
|
-
| `pnpm format` | Prettier format code |
|
|
963
|
-
| `pnpm build:css` | Build CSS files |
|
|
964
|
-
|
|
965
|
-
### Developing Custom Plugins
|
|
966
|
-
|
|
967
|
-
Custom plugins need to implement the [`IEditorPlugin`](src/types/base-plugin.ts:5) interface:
|
|
968
|
-
|
|
969
|
-
```typescript
|
|
970
|
-
import type { IEditorPlugin } from ''vkedit'
|
|
971
|
-
|
|
972
|
-
export class MyCustomPlugin implements IEditorPlugin {
|
|
973
|
-
constructor(private host: EditorHost) {}
|
|
974
|
-
|
|
975
|
-
install(host: EditorHost): void {
|
|
976
|
-
// Listen to events
|
|
977
|
-
host.on('element:added', this.onElementAdded)
|
|
978
|
-
|
|
979
|
-
// Register tool
|
|
980
|
-
host.emit('tool:registered', {
|
|
981
|
-
name: 'my-tool',
|
|
982
|
-
icon: 'my-icon',
|
|
983
|
-
render: () => MyToolComponent
|
|
984
|
-
})
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
uninstall(): void {
|
|
988
|
-
// Clean up resources
|
|
989
|
-
this.host.off('element:added', this.onElementAdded)
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
private onElementAdded = (payload: any) => {
|
|
993
|
-
console.log('Element added:', payload)
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
// Use custom plugin
|
|
998
|
-
host.installPlugin('my-custom-plugin', MyCustomPlugin)
|
|
999
|
-
```
|
|
1000
|
-
|
|
1001
|
-
### Custom Graphic Elements
|
|
1002
|
-
|
|
1003
|
-
Creating custom graphic elements requires extending [`BaseGraphicElement`](src/types/base-graphic-element.ts:5):
|
|
1004
|
-
|
|
1005
|
-
```typescript
|
|
1006
|
-
import { BaseGraphicElement } from 'vkedit'
|
|
1007
|
-
|
|
1008
|
-
export class MyCustomElement extends BaseGraphicElement {
|
|
1009
|
-
constructor(
|
|
1010
|
-
id: string,
|
|
1011
|
-
public width: number = 100,
|
|
1012
|
-
public height: number = 100,
|
|
1013
|
-
public fill: string = '#ff0000'
|
|
1014
|
-
) {
|
|
1015
|
-
super(id, 'my-custom')
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
serialize(): Record<string, any> {
|
|
1019
|
-
return {
|
|
1020
|
-
...super.serialize(),
|
|
1021
|
-
width: this.width,
|
|
1022
|
-
height: this.height,
|
|
1023
|
-
fill: this.fill
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
deserialize(data: Record<string, any>): void {
|
|
1028
|
-
super.deserialize(data)
|
|
1029
|
-
this.width = data.width
|
|
1030
|
-
this.height = data.height
|
|
1031
|
-
this.fill = data.fill
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
render() {
|
|
1035
|
-
return {
|
|
1036
|
-
tag: 'rect',
|
|
1037
|
-
props: {
|
|
1038
|
-
x: this.x,
|
|
1039
|
-
y: this.y,
|
|
1040
|
-
width: this.width,
|
|
1041
|
-
height: this.height,
|
|
1042
|
-
fill: this.fill
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
```
|
|
1048
|
-
|
|
1049
|
-
---
|
|
1050
|
-
|
|
1051
|
-
## ❓ Frequently Asked Questions (FAQ)
|
|
1052
|
-
|
|
1053
|
-
### Q: How to set canvas size to A4 paper?
|
|
1054
|
-
|
|
1055
|
-
```typescript
|
|
1056
|
-
host.setStatus({
|
|
1057
|
-
dpm: 8, // Dots per millimeter (DPI / 25.4)
|
|
1058
|
-
width: 210 * 8, // A4 width 210mm
|
|
1059
|
-
height: 297 * 8 // A4 height 297mm
|
|
1060
|
-
})
|
|
1061
|
-
```
|
|
1062
|
-
|
|
1063
|
-
### Q: How to export design data?
|
|
1064
|
-
|
|
1065
|
-
```typescript
|
|
1066
|
-
// Export as JSON
|
|
1067
|
-
const json = host.toJSON()
|
|
1068
|
-
|
|
1069
|
-
// Export as image (requires ExportPlugin)
|
|
1070
|
-
host.getPlugin('export-plugin').exportAsPNG()
|
|
1071
|
-
```
|
|
1072
|
-
|
|
1073
|
-
### Q: How to listen to element selection changes?
|
|
1074
|
-
|
|
1075
|
-
```typescript
|
|
1076
|
-
host.on('selection:changed', (payload) => {
|
|
1077
|
-
const selectedIds = payload.selectedIds
|
|
1078
|
-
console.log('Currently selected elements:', selectedIds)
|
|
1079
|
-
})
|
|
1080
|
-
```
|
|
1081
|
-
|
|
1082
|
-
### Q: How to batch update properties of multiple elements?
|
|
1083
|
-
|
|
1084
|
-
```typescript
|
|
1085
|
-
const batchCommand = new BatchCommand([
|
|
1086
|
-
new UpdatePropertyCommand(element1, 'fill', '#ff0000'),
|
|
1087
|
-
new UpdatePropertyCommand(element2, 'fill', '#00ff00'),
|
|
1088
|
-
new UpdatePropertyCommand(element3, 'fill', '#0000ff')
|
|
1089
|
-
])
|
|
1090
|
-
host.executeCommand(batchCommand)
|
|
1091
|
-
```
|
|
1092
|
-
|
|
1093
|
-
### Q: How to disable all core plugins and customize configuration?
|
|
1094
|
-
|
|
1095
|
-
```typescript
|
|
1096
|
-
const host = createEditorHost({
|
|
1097
|
-
basePropertyPanel: false,
|
|
1098
|
-
baseCanvasPropertyPanel: false,
|
|
1099
|
-
exportPlugin: false,
|
|
1100
|
-
previewPlugin: false,
|
|
1101
|
-
importPlugin: false
|
|
1102
|
-
})
|
|
1103
|
-
```
|
|
1104
|
-
|
|
1105
|
-
---
|
|
1106
|
-
|
|
1107
|
-
## 🤝 Contributing Guidelines
|
|
1108
|
-
|
|
1109
|
-
Contributions are welcome! Please follow the guidelines:
|
|
1110
|
-
|
|
1111
|
-
### Code Standards
|
|
1112
|
-
|
|
1113
|
-
- Write code using TypeScript
|
|
1114
|
-
- Follow ESLint rules (auto-check with `pnpm lint`)
|
|
1115
|
-
- Format code with Prettier (`pnpm format`)
|
|
1116
|
-
- Write clear comments and documentation
|
|
1117
|
-
|
|
1118
|
-
### Commit Standards
|
|
1119
|
-
|
|
1120
|
-
Use semantic commit messages:
|
|
1121
|
-
|
|
1122
|
-
```
|
|
1123
|
-
feat: add new feature
|
|
1124
|
-
fix: fix bug
|
|
1125
|
-
docs: update documentation
|
|
1126
|
-
style: code format adjustment
|
|
1127
|
-
refactor: code refactoring
|
|
1128
|
-
perf: performance optimization
|
|
1129
|
-
test: add tests
|
|
1130
|
-
chore: build/tool changes
|
|
1131
|
-
```
|
|
1132
|
-
|
|
1133
|
-
### Development Workflow
|
|
1134
|
-
|
|
1135
|
-
1. Fork repository
|
|
1136
|
-
2. Create feature branch (`git checkout -b feature/AmazingFeature`)
|
|
1137
|
-
3. Commit changes (`git commit -m 'feat: add amazing feature'`)
|
|
1138
|
-
4. Push to branch (`git push origin feature/AmazingFeature`)
|
|
1139
|
-
5. Create Pull Request
|
|
1140
|
-
|
|
1141
|
-
---
|
|
1142
|
-
|
|
1143
|
-
## 📋 Changelog
|
|
1144
|
-
|
|
1145
|
-
### 2.8.5
|
|
1146
|
-
- Current stable version
|
|
1147
|
-
- Complete plugin system architecture
|
|
1148
|
-
- Support for multiple graphic elements
|
|
1149
|
-
- Import/Export functionality
|
|
1150
|
-
- Undo/Redo mechanism
|
|
1151
|
-
|
|
1152
|
-
### Version History
|
|
1153
|
-
For detailed version history, see [GitHub Releases](https://github.com/pwg-code/vkedit/releases)
|
|
1154
|
-
|
|
1155
|
-
---
|
|
1156
|
-
|
|
1157
|
-
## 📄 License
|
|
1158
|
-
|
|
1159
|
-
This project is licensed under the MIT License - see [LICENSE](LICENSE) file for details
|
|
1160
|
-
|
|
1161
|
-
---
|
|
1162
|
-
|
|
1163
|
-
## 🔗 Related Links
|
|
1164
|
-
|
|
1165
|
-
- [Vue.js](https://vuejs.org/)
|
|
1166
|
-
- [Konva.js](https://konvajs.org/)
|
|
1167
|
-
- [vue-konva](https://www.npmjs.com/package/vue-konva)
|
|
1168
|
-
- [Pinia](https://pinia.vuejs.org/)
|
|
1169
|
-
|
|
1170
|
-
---
|
|
1171
|
-
|
|
1172
|
-
## ☕ Support the Author
|
|
1173
|
-
|
|
1174
|
-
If you find vkedit helpful, please consider supporting the author! Your support is the driving force behind the continued development of the project.
|
|
1175
|
-
|
|
1176
|
-
<div align="center">
|
|
1177
|
-
|
|
1178
|
-
**Made with ❤️ by vkedit contributors**
|
|
1179
|
-
|
|
1180
|
-
</div>
|
|
1181
|
-
|
|
1182
|
-
---
|
|
1183
|
-
|
|
1184
|
-
## 📞 Contact Support
|
|
1185
|
-
|
|
1186
|
-
If you need technical support, custom features, or have any questions, please feel free to contact:
|
|
1187
|
-
|
|
1188
|
-
- **QQ**: 16871824
|
|
1189
|
-
- **Email**: 168715824@qq.com
|
|
1190
|
-
- **Services**: Technical support, feature customization, project collaboration
|
|
1191
|
-
|
|
1192
|
-
Looking forward to communicating with you and improving vkedit together!
|
|
1193
|
-
|
|
1
|
+
# vkedit
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/vkedit)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](package.json)
|
|
6
|
+
|
|
7
|
+
A visual canvas designer component built on Vue 3 and Konva.js. Features a plugin-based architecture for label, QR code, barcode, receipt, business card, and certificate template design and print layout.
|
|
8
|
+
|
|
9
|
+
**[中文](README.md)**
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- **Plugin-based architecture** - Core features and graphic elements are registered as plugins, enabled on demand
|
|
20
|
+
- **7 graphic element types** - Rectangle, text, line, table, QR code, barcode, chart (ECharts)
|
|
21
|
+
- **Undo / Redo** - Command pattern, all modifications are reversible
|
|
22
|
+
- **Import / Export** - JSON serialization, PNG/JPG images, PDF documents
|
|
23
|
+
- **Align & Distribute** - Left/right/top/bottom/center alignment, horizontal/vertical distribution
|
|
24
|
+
- **Ruler & Zoom** - Millimeter-precision ruler, configurable DPM (dots per millimeter)
|
|
25
|
+
- **Event-driven** - Type-safe event system for loosely coupled plugin communication
|
|
26
|
+
- **TypeScript** - Full type definitions with generic plugin and element type inference
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add vkedit vue konva vue-konva
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
vkedit declares `vue`, `konva`, and `vue-konva` as peerDependencies, which must be provided by the host project.
|
|
37
|
+
|
|
38
|
+
| Peer Dependency | Version |
|
|
39
|
+
| --------------- | -------- |
|
|
40
|
+
| vue | ^3.5.18 |
|
|
41
|
+
| konva | ^10.0.2 |
|
|
42
|
+
| vue-konva | ^3.2.6 |
|
|
43
|
+
|
|
44
|
+
Node.js requirement: `^20.19.0 || >=22.12.0`
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
### 1. Configure entry file
|
|
51
|
+
|
|
52
|
+
Register VueKonva and import styles in `main.ts`:
|
|
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. Use the editor component
|
|
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
|
+
// Install graphic plugins
|
|
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
|
+
// Set canvas size (A4 paper, 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 Component Props
|
|
107
|
+
|
|
108
|
+
| Prop | Type | Default | Description |
|
|
109
|
+
| ------------------- | ------------ | ------- | ------------------------ |
|
|
110
|
+
| `host` | `EditorHost` | - | Editor host instance |
|
|
111
|
+
| `showToolbox` | `boolean` | `true` | Show left toolbox |
|
|
112
|
+
| `showPropertyPanel` | `boolean` | `true` | Show right property panel|
|
|
113
|
+
| `showToolbar` | `boolean` | `true` | Show top toolbar |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Configuration
|
|
118
|
+
|
|
119
|
+
### createEditorHost Options
|
|
120
|
+
|
|
121
|
+
`createEditorHost(options)` creates a host instance and automatically installs core plugins. Optional plugins are controlled by the following options:
|
|
122
|
+
|
|
123
|
+
| Option | Type | Default | Description |
|
|
124
|
+
| ------------------------ | --------- | ------- | -------------------------- |
|
|
125
|
+
| `basePropertyPanel` | `boolean` | `false` | Base element property panel|
|
|
126
|
+
| `baseCanvasPropertyPanel`| `boolean` | `true` | Canvas property panel |
|
|
127
|
+
| `exportPlugin` | `boolean` | `true` | Export plugin |
|
|
128
|
+
| `previewPlugin` | `boolean` | `true` | Preview plugin |
|
|
129
|
+
| `importPlugin` | `boolean` | `true` | Import plugin |
|
|
130
|
+
|
|
131
|
+
### Canvas State
|
|
132
|
+
|
|
133
|
+
Update canvas state via `host.setStatus()`, which supports partial updates:
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface IEditorState {
|
|
137
|
+
zoom: number // Zoom level
|
|
138
|
+
currentTool: string // Current tool
|
|
139
|
+
snapToGrid: boolean // Snap to grid
|
|
140
|
+
showGrid: boolean // Show grid
|
|
141
|
+
width: number // Canvas width (pixels)
|
|
142
|
+
height: number // Canvas height (pixels)
|
|
143
|
+
wmm: number // Canvas width (millimeters)
|
|
144
|
+
hmm: number // Canvas height (millimeters)
|
|
145
|
+
dpm: number // Dots per millimeter (DPI / 25.4)
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`width`/`height` and `wmm`/`hmm` are automatically converted via `dpm`. Setting `dpm` recalculates pixel dimensions from the current millimeter sizes.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Plugin List
|
|
154
|
+
|
|
155
|
+
### Core Plugins (auto-installed by createEditorHost)
|
|
156
|
+
|
|
157
|
+
| Plugin | Description |
|
|
158
|
+
| --- | --- |
|
|
159
|
+
| `ToolbarManagerPlugin` | Top toolbar management |
|
|
160
|
+
| `GraphicToolManagerPlugin` | Graphic tool management |
|
|
161
|
+
| `GraphicManagerPlugin` | Graphic rendering management |
|
|
162
|
+
| `PropertyPanelManagerPlugin` | Dynamic property panel rendering |
|
|
163
|
+
| `ElementManagerPlugin` | Element lifecycle management |
|
|
164
|
+
| `SelectionPlugin` | Element selection and multi-select |
|
|
165
|
+
| `KeyDownPlugin` | Keyboard shortcuts |
|
|
166
|
+
| `SnapPlugin` | Grid snapping |
|
|
167
|
+
| `ClipboardPlugin` | Copy / cut / paste |
|
|
168
|
+
| `AlignPlugin` | Alignment and distribution |
|
|
169
|
+
| `ContextMenuManagerPlugin` | Context menu |
|
|
170
|
+
|
|
171
|
+
### Feature Plugins (enabled via options)
|
|
172
|
+
|
|
173
|
+
| Plugin | Option | Description |
|
|
174
|
+
| --- | --- | --- |
|
|
175
|
+
| `ExportPlugin` | `exportPlugin` | Export JSON / PNG / JPG / PDF |
|
|
176
|
+
| `ImportPlugin` | `importPlugin` | Import JSON files |
|
|
177
|
+
| `PreviewPlugin` | `previewPlugin` | Preview and print preview |
|
|
178
|
+
|
|
179
|
+
### Graphic Plugins (manually installed)
|
|
180
|
+
|
|
181
|
+
| Plugin | Element Type | Description |
|
|
182
|
+
| --- | --- | --- |
|
|
183
|
+
| `RectPlugin` | `rect` | Rectangle with fill and stroke |
|
|
184
|
+
| `TextPlugin` | `text` | Text with font, alignment, and style |
|
|
185
|
+
| `LinePlugin` | `line` | Line with color and width |
|
|
186
|
+
| `TablePlugin` | `table` | Table with rows, merged cells, and borders |
|
|
187
|
+
| `QrcodePlugin` | `qr` | QR code with foreground/background colors |
|
|
188
|
+
| `BarcodePlugin` | `barcode` | Barcode supporting CODE128, EAN-13, etc. |
|
|
189
|
+
| `ChartPlugin` | `chart` | Chart powered by ECharts |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Core Concepts
|
|
194
|
+
|
|
195
|
+
### EditorHost
|
|
196
|
+
|
|
197
|
+
`EditorHost` is the core host class of the editor, managing plugins, state, commands, and history. After creating an instance via `createEditorHost()`, all operations revolve around the `host`.
|
|
198
|
+
|
|
199
|
+
### Plugin System
|
|
200
|
+
|
|
201
|
+
Plugins are managed via `installPlugin` / `uninstallPlugin` / `getPlugin`. Plugins must extend `BasePlugin` and implement the `onInstall()` hook. `getPlugin` supports generic type inference:
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const rectPlugin = host.getPlugin('rect-plugin') // inferred as RectPlugin
|
|
205
|
+
const exportPlugin = host.getPlugin('export-plugin')
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Command Pattern
|
|
209
|
+
|
|
210
|
+
All reversible operations are implemented as commands. `executeCommand()` executes a command and pushes it onto the history stack, while `undo()` / `redo()` navigate the stack:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
host.executeCommand(command) // execute and push
|
|
214
|
+
host.undo() // undo
|
|
215
|
+
host.redo() // redo
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Event System
|
|
219
|
+
|
|
220
|
+
The editor provides type-safe event communication via `emit` / `on` / `off`:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// Listen for element added
|
|
224
|
+
host.on('element:added', (payload) => {
|
|
225
|
+
console.log('Element added:', payload.element)
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
// Listen for selection changed
|
|
229
|
+
host.on('selection:changed', (payload) => {
|
|
230
|
+
console.log('Selected:', payload.selection)
|
|
231
|
+
})
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
For the full event list and custom event extension, refer to the API documentation.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Common Operations
|
|
239
|
+
|
|
240
|
+
### Export / Import JSON
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
// Export to JSON string
|
|
244
|
+
const json = host.toJSON()
|
|
245
|
+
|
|
246
|
+
// Load from JSON string
|
|
247
|
+
host.loadJSON(json)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Use ExportPlugin / ImportPlugin to trigger file download and file picker:
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
const exportPlugin = host.getPlugin('export-plugin')
|
|
254
|
+
exportPlugin.handleExportJSON() // download .json file
|
|
255
|
+
exportPlugin.handleExportImage() // download PNG image
|
|
256
|
+
exportPlugin.handleExportPdf() // download PDF document
|
|
257
|
+
|
|
258
|
+
const importPlugin = host.getPlugin('import-plugin')
|
|
259
|
+
importPlugin.handleImportJSON() // open file picker
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Undo / Redo
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
host.undo()
|
|
266
|
+
host.redo()
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Listen to Events
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
host.on('selection:changed', (payload) => {
|
|
273
|
+
console.log('Selected element IDs:', payload.selection)
|
|
274
|
+
})
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Add Element (via command)
|
|
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
|
+
### Update Element Property (via command)
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { UpdatePropertyCommand } from 'vkedit'
|
|
291
|
+
|
|
292
|
+
host.executeCommand(
|
|
293
|
+
new UpdatePropertyCommand(host, element, 'fill', 'red', 'blue')
|
|
294
|
+
)
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Batch Operations
|
|
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
|
+
## Use Cases
|
|
312
|
+
|
|
313
|
+
| Scenario | Applicable Plugins |
|
|
314
|
+
| --- | --- |
|
|
315
|
+
| Label template design | QR code, barcode, text, rectangle, table |
|
|
316
|
+
| QR code design | QR code, text, rectangle |
|
|
317
|
+
| Barcode design | Barcode, text, line |
|
|
318
|
+
| Receipt design | Table, text, rectangle, line |
|
|
319
|
+
| Business card design | Text, rectangle, line |
|
|
320
|
+
| Certificate design | Text, rectangle, table |
|
|
321
|
+
| Data visualization | Chart, text, rectangle |
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Available Commands
|
|
326
|
+
|
|
327
|
+
| Command | Constructor Params | Description |
|
|
328
|
+
| --- | --- | --- |
|
|
329
|
+
| `AddElementCommand` | `(host, element)` | Add element |
|
|
330
|
+
| `RemoveElementCommand` | `(host, element)` | Remove element |
|
|
331
|
+
| `TransformElementCommand` | `(host, element, oldState, newState)` | Transform element (position/size/rotation) |
|
|
332
|
+
| `UpdatePropertyCommand` | `(host, element, propertyPath, oldValue, newValue)` | Update property |
|
|
333
|
+
| `BatchCommand` | `(host, commands, description?)` | Batch command |
|
|
334
|
+
| `AlignElementsCommand` | `(host, alignment, elementIds)` | Align elements |
|
|
335
|
+
| `DistributeElementsCommand` | `(host, direction, elementIds)` | Distribute elements |
|
|
336
|
+
| `ChangeLayerOrderCommand` | `(host, elementId, direction)` | Change layer order |
|
|
337
|
+
| `ClearSelectionCommand` | `(host)` | Clear selection |
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Links
|
|
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
|
+
## Contact
|
|
358
|
+
|
|
359
|
+
- **QQ**: 16871824
|
|
360
|
+
- **Email**: 168715824@qq.com
|
|
361
|
+
|
|
362
|
+
Available for technical support, custom features, and project collaboration.
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Sponsor
|
|
367
|
+
|
|
368
|
+
If vkedit helps you, consider buying the author a coffee.
|
|
369
|
+
|
|
370
|
+
<div align="center">
|
|
371
|
+
|
|
372
|
+
<table>
|
|
373
|
+
<tr>
|
|
374
|
+
<td align="center">
|
|
375
|
+
<img src="./截图/reward-alipay.png" width="200" alt="Alipay" />
|
|
376
|
+
<br>Alipay
|
|
377
|
+
</td>
|
|
378
|
+
<td align="center">
|
|
379
|
+
<img src="./截图/reward-wechat.png" width="200" alt="WeChat Pay" />
|
|
380
|
+
<br>WeChat
|
|
381
|
+
</td>
|
|
382
|
+
</tr>
|
|
383
|
+
</table>
|
|
384
|
+
|
|
385
|
+
</div>
|