@hprint/plugins 0.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/dist/index.css +1 -0
  2. package/dist/index.js +478 -0
  3. package/dist/index.mjs +41731 -0
  4. package/dist/src/index.d.ts +8 -0
  5. package/dist/src/index.d.ts.map +1 -0
  6. package/dist/src/objects/Arrow.d.ts +2 -0
  7. package/dist/src/objects/Arrow.d.ts.map +1 -0
  8. package/dist/src/objects/ThinTailArrow.d.ts +2 -0
  9. package/dist/src/objects/ThinTailArrow.d.ts.map +1 -0
  10. package/dist/src/plugins/AddBaseTypePlugin.d.ts +26 -0
  11. package/dist/src/plugins/AddBaseTypePlugin.d.ts.map +1 -0
  12. package/dist/src/plugins/AlignGuidLinePlugin.d.ts +16 -0
  13. package/dist/src/plugins/AlignGuidLinePlugin.d.ts.map +1 -0
  14. package/dist/src/plugins/BarCodePlugin.d.ts +68 -0
  15. package/dist/src/plugins/BarCodePlugin.d.ts.map +1 -0
  16. package/dist/src/plugins/CenterAlignPlugin.d.ts +29 -0
  17. package/dist/src/plugins/CenterAlignPlugin.d.ts.map +1 -0
  18. package/dist/src/plugins/ControlsPlugin.d.ts +11 -0
  19. package/dist/src/plugins/ControlsPlugin.d.ts.map +1 -0
  20. package/dist/src/plugins/ControlsRotatePlugin.d.ts +11 -0
  21. package/dist/src/plugins/ControlsRotatePlugin.d.ts.map +1 -0
  22. package/dist/src/plugins/CopyPlugin.d.ts +30 -0
  23. package/dist/src/plugins/CopyPlugin.d.ts.map +1 -0
  24. package/dist/src/plugins/CreateElementPlugin.d.ts +121 -0
  25. package/dist/src/plugins/CreateElementPlugin.d.ts.map +1 -0
  26. package/dist/src/plugins/DeleteHotKeyPlugin.d.ts +25 -0
  27. package/dist/src/plugins/DeleteHotKeyPlugin.d.ts.map +1 -0
  28. package/dist/src/plugins/DrawLinePlugin.d.ts +26 -0
  29. package/dist/src/plugins/DrawLinePlugin.d.ts.map +1 -0
  30. package/dist/src/plugins/DrawPolygonPlugin.d.ts +41 -0
  31. package/dist/src/plugins/DrawPolygonPlugin.d.ts.map +1 -0
  32. package/dist/src/plugins/DringPlugin.d.ts +33 -0
  33. package/dist/src/plugins/DringPlugin.d.ts.map +1 -0
  34. package/dist/src/plugins/FlipPlugin.d.ts +26 -0
  35. package/dist/src/plugins/FlipPlugin.d.ts.map +1 -0
  36. package/dist/src/plugins/FontPlugin.d.ts +33 -0
  37. package/dist/src/plugins/FontPlugin.d.ts.map +1 -0
  38. package/dist/src/plugins/FreeDrawPlugin.d.ts +23 -0
  39. package/dist/src/plugins/FreeDrawPlugin.d.ts.map +1 -0
  40. package/dist/src/plugins/GroupAlignPlugin.d.ts +24 -0
  41. package/dist/src/plugins/GroupAlignPlugin.d.ts.map +1 -0
  42. package/dist/src/plugins/GroupPlugin.d.ts +24 -0
  43. package/dist/src/plugins/GroupPlugin.d.ts.map +1 -0
  44. package/dist/src/plugins/GroupTextEditorPlugin.d.ts +18 -0
  45. package/dist/src/plugins/GroupTextEditorPlugin.d.ts.map +1 -0
  46. package/dist/src/plugins/HistoryPlugin.d.ts +30 -0
  47. package/dist/src/plugins/HistoryPlugin.d.ts.map +1 -0
  48. package/dist/src/plugins/ImageStroke.d.ts +18 -0
  49. package/dist/src/plugins/ImageStroke.d.ts.map +1 -0
  50. package/dist/src/plugins/LayerPlugin.d.ts +31 -0
  51. package/dist/src/plugins/LayerPlugin.d.ts.map +1 -0
  52. package/dist/src/plugins/LockPlugin.d.ts +27 -0
  53. package/dist/src/plugins/LockPlugin.d.ts.map +1 -0
  54. package/dist/src/plugins/MaskPlugin.d.ts +38 -0
  55. package/dist/src/plugins/MaskPlugin.d.ts.map +1 -0
  56. package/dist/src/plugins/MaterialPlugin.d.ts +45 -0
  57. package/dist/src/plugins/MaterialPlugin.d.ts.map +1 -0
  58. package/dist/src/plugins/MiddleMousePlugin.d.ts +18 -0
  59. package/dist/src/plugins/MiddleMousePlugin.d.ts.map +1 -0
  60. package/dist/src/plugins/MoveHotKeyPlugin.d.ts +12 -0
  61. package/dist/src/plugins/MoveHotKeyPlugin.d.ts.map +1 -0
  62. package/dist/src/plugins/PathTextPlugin.d.ts +30 -0
  63. package/dist/src/plugins/PathTextPlugin.d.ts.map +1 -0
  64. package/dist/src/plugins/PolygonModifyPlugin.d.ts +28 -0
  65. package/dist/src/plugins/PolygonModifyPlugin.d.ts.map +1 -0
  66. package/dist/src/plugins/PrintPlugin.d.ts +39 -0
  67. package/dist/src/plugins/PrintPlugin.d.ts.map +1 -0
  68. package/dist/src/plugins/PsdPlugin.d.ts +17 -0
  69. package/dist/src/plugins/PsdPlugin.d.ts.map +1 -0
  70. package/dist/src/plugins/QrCodePlugin.d.ts +137 -0
  71. package/dist/src/plugins/QrCodePlugin.d.ts.map +1 -0
  72. package/dist/src/plugins/ResizePlugin.d.ts +44 -0
  73. package/dist/src/plugins/ResizePlugin.d.ts.map +1 -0
  74. package/dist/src/plugins/RulerPlugin.d.ts +24 -0
  75. package/dist/src/plugins/RulerPlugin.d.ts.map +1 -0
  76. package/dist/src/plugins/SimpleClipImagePlugin.d.ts +18 -0
  77. package/dist/src/plugins/SimpleClipImagePlugin.d.ts.map +1 -0
  78. package/dist/src/plugins/UnitPlugin.d.ts +84 -0
  79. package/dist/src/plugins/UnitPlugin.d.ts.map +1 -0
  80. package/dist/src/plugins/WaterMarkPlugin.d.ts +40 -0
  81. package/dist/src/plugins/WaterMarkPlugin.d.ts.map +1 -0
  82. package/dist/src/plugins/WorkspacePlugin.d.ts +57 -0
  83. package/dist/src/plugins/WorkspacePlugin.d.ts.map +1 -0
  84. package/dist/src/types/eventType.d.ts +11 -0
  85. package/dist/src/types/eventType.d.ts.map +1 -0
  86. package/dist/src/utils/psd.d.ts +3 -0
  87. package/dist/src/utils/psd.d.ts.map +1 -0
  88. package/dist/src/utils/ruler/guideline.d.ts +4 -0
  89. package/dist/src/utils/ruler/guideline.d.ts.map +1 -0
  90. package/dist/src/utils/ruler/index.d.ts +5 -0
  91. package/dist/src/utils/ruler/index.d.ts.map +1 -0
  92. package/dist/src/utils/ruler/ruler.d.ts +147 -0
  93. package/dist/src/utils/ruler/ruler.d.ts.map +1 -0
  94. package/dist/src/utils/ruler/utils.d.ts +50 -0
  95. package/dist/src/utils/ruler/utils.d.ts.map +1 -0
  96. package/dist/src/utils/units.d.ts +22 -0
  97. package/dist/src/utils/units.d.ts.map +1 -0
  98. package/package.json +51 -0
  99. package/src/assets/edgecontrol.svg +17 -0
  100. package/src/assets/lock.svg +7 -0
  101. package/src/assets/middlecontrol.svg +17 -0
  102. package/src/assets/middlecontrolhoz.svg +17 -0
  103. package/src/assets/rotateicon.svg +20 -0
  104. package/src/assets/style/resizePlugin.css +27 -0
  105. package/src/index.ts +121 -0
  106. package/src/objects/Arrow.js +47 -0
  107. package/src/objects/ThinTailArrow.js +50 -0
  108. package/src/plugins/AddBaseTypePlugin.ts +107 -0
  109. package/src/plugins/AlignGuidLinePlugin.ts +1141 -0
  110. package/src/plugins/BarCodePlugin.ts +860 -0
  111. package/src/plugins/CenterAlignPlugin.ts +133 -0
  112. package/src/plugins/ControlsPlugin.ts +251 -0
  113. package/src/plugins/ControlsRotatePlugin.ts +111 -0
  114. package/src/plugins/CopyPlugin.ts +255 -0
  115. package/src/plugins/CreateElementPlugin.ts +548 -0
  116. package/src/plugins/DeleteHotKeyPlugin.ts +57 -0
  117. package/src/plugins/DrawLinePlugin.ts +162 -0
  118. package/src/plugins/DrawPolygonPlugin.ts +205 -0
  119. package/src/plugins/DringPlugin.ts +125 -0
  120. package/src/plugins/FlipPlugin.ts +59 -0
  121. package/src/plugins/FontPlugin.ts +165 -0
  122. package/src/plugins/FreeDrawPlugin.ts +49 -0
  123. package/src/plugins/GroupAlignPlugin.ts +365 -0
  124. package/src/plugins/GroupPlugin.ts +82 -0
  125. package/src/plugins/GroupTextEditorPlugin.ts +198 -0
  126. package/src/plugins/HistoryPlugin.ts +181 -0
  127. package/src/plugins/ImageStroke.ts +121 -0
  128. package/src/plugins/LayerPlugin.ts +108 -0
  129. package/src/plugins/LockPlugin.ts +240 -0
  130. package/src/plugins/MaskPlugin.ts +155 -0
  131. package/src/plugins/MaterialPlugin.ts +224 -0
  132. package/src/plugins/MiddleMousePlugin.ts +45 -0
  133. package/src/plugins/MoveHotKeyPlugin.ts +46 -0
  134. package/src/plugins/PathTextPlugin.ts +89 -0
  135. package/src/plugins/PolygonModifyPlugin.ts +224 -0
  136. package/src/plugins/PrintPlugin.ts +81 -0
  137. package/src/plugins/PsdPlugin.ts +52 -0
  138. package/src/plugins/QrCodePlugin.ts +393 -0
  139. package/src/plugins/ResizePlugin.ts +274 -0
  140. package/src/plugins/RulerPlugin.ts +78 -0
  141. package/src/plugins/SimpleClipImagePlugin.ts +244 -0
  142. package/src/plugins/UnitPlugin.ts +327 -0
  143. package/src/plugins/WaterMarkPlugin.ts +257 -0
  144. package/src/plugins/WorkspacePlugin.ts +307 -0
  145. package/src/types/eventType.ts +11 -0
  146. package/src/utils/psd.js +432 -0
  147. package/src/utils/ruler/guideline.ts +145 -0
  148. package/src/utils/ruler/index.ts +91 -0
  149. package/src/utils/ruler/ruler.ts +924 -0
  150. package/src/utils/ruler/utils.ts +162 -0
  151. package/src/utils/units.ts +133 -0
  152. package/tsconfig.json +10 -0
  153. package/vite.config.ts +29 -0
@@ -0,0 +1,1141 @@
1
+ import { fabric, IEditor, IPluginTempl } from '@hprint/core';
2
+
3
+ declare interface VerticalLine {
4
+ x: number;
5
+ y1: number;
6
+ y2: number;
7
+ }
8
+
9
+ declare interface HorizontalLine {
10
+ x1: number;
11
+ x2: number;
12
+ y: number;
13
+ }
14
+
15
+ class AlignGuidLinePlugin implements IPluginTempl {
16
+ defautOption = {
17
+ color: 'rgba(255,95,95,1)',
18
+ width: 1,
19
+ };
20
+ static pluginName = 'AlignGuidLinePlugin';
21
+ dragMode = false;
22
+ constructor(
23
+ public canvas: fabric.Canvas,
24
+ public editor: IEditor
25
+ ) {
26
+ this.dragMode = false;
27
+ this.init();
28
+ }
29
+ init() {
30
+ const { canvas } = this;
31
+ const ctx = canvas.getSelectionContext();
32
+ const aligningLineOffset = 5;
33
+ const aligningLineMargin = 4;
34
+ const This = this;
35
+ let viewportTransform: number[] | undefined;
36
+ let zoom = 1;
37
+ let activeWidth = 0;
38
+ let activeHeight = 0;
39
+ let activeLeft = 0;
40
+ let activeTop = 0;
41
+
42
+ function drawVerticalLine(coords: VerticalLine) {
43
+ drawLine(
44
+ coords.x + 0.5,
45
+ coords.y1 > coords.y2 ? coords.y2 : coords.y1,
46
+ coords.x + 0.5,
47
+ coords.y2 > coords.y1 ? coords.y2 : coords.y1
48
+ );
49
+ }
50
+
51
+ function drawHorizontalLine(coords: HorizontalLine) {
52
+ drawLine(
53
+ coords.x1 > coords.x2 ? coords.x2 : coords.x1,
54
+ coords.y + 0.5,
55
+ coords.x2 > coords.x1 ? coords.x2 : coords.x1,
56
+ coords.y + 0.5
57
+ );
58
+ }
59
+
60
+ function drawLine(x1: number, y1: number, x2: number, y2: number) {
61
+ if (viewportTransform == null) return;
62
+
63
+ ctx.moveTo(
64
+ x1 * zoom + viewportTransform[4],
65
+ y1 * zoom + viewportTransform[5]
66
+ );
67
+ ctx.lineTo(
68
+ x2 * zoom + viewportTransform[4],
69
+ y2 * zoom + viewportTransform[5]
70
+ );
71
+ }
72
+
73
+ function isInRange(value1: number, value2: number) {
74
+ value1 = Math.round(value1);
75
+ value2 = Math.round(value2);
76
+ for (
77
+ let i = value1 - aligningLineMargin,
78
+ len = value1 + aligningLineMargin;
79
+ i <= len;
80
+ i++
81
+ ) {
82
+ if (i === value2) {
83
+ return true;
84
+ }
85
+ }
86
+ return false;
87
+ }
88
+
89
+ let verticalLines: VerticalLine[] = [];
90
+ let horizontalLines: HorizontalLine[] = [];
91
+
92
+ canvas.on('mouse:down', (e) => {
93
+ viewportTransform = canvas.viewportTransform;
94
+ zoom = canvas.getZoom();
95
+ try {
96
+ if (e) {
97
+ activeLeft = e.target.left;
98
+ activeTop = e.target.top;
99
+ activeWidth = e.target.getScaledWidth();
100
+ activeHeight = e.target.getScaledHeight();
101
+ }
102
+ } catch (e) {}
103
+ });
104
+
105
+ canvas.on('object:moving', (e) => {
106
+ if (viewportTransform === undefined || e.target === undefined)
107
+ return;
108
+
109
+ const activeObject = e.target;
110
+ const canvasObjects = canvas.getObjects();
111
+ const activeObjectCenter = activeObject.getCenterPoint();
112
+ const activeObjectLeft = activeObjectCenter.x;
113
+ const activeObjectTop = activeObjectCenter.y;
114
+ const activeObjectBoundingRect = activeObject.getBoundingRect();
115
+ const activeObjectHeight = activeObject.getScaledHeight();
116
+ const activeObjectWidth = activeObject.getScaledWidth();
117
+ let horizontalInTheRange = false;
118
+ let verticalInTheRange = false;
119
+ const transform = canvas._currentTransform;
120
+
121
+ //到达位置
122
+ let reachLeft = false; //左
123
+ let reachTop = false; //上
124
+
125
+ //距离
126
+ let _elReachLeft = 0; //左距离
127
+ let _elReachTop = 0; //上距离
128
+
129
+ activeObject.set('hasControls', false);
130
+
131
+ if (!transform) return;
132
+
133
+ for (let i = canvasObjects.length; i--; ) {
134
+ // eslint-disable-next-line no-continue
135
+ if (canvasObjects[i] === activeObject) continue;
136
+
137
+ // 排除辅助线
138
+ if (
139
+ activeObject instanceof fabric.GuideLine &&
140
+ canvasObjects[i] instanceof fabric.GuideLine
141
+ ) {
142
+ continue;
143
+ }
144
+
145
+ const objectCenter = canvasObjects[i].getCenterPoint();
146
+ const objectLeft = objectCenter.x;
147
+ const objectTop = objectCenter.y;
148
+ const objectBoundingRect = canvasObjects[i].getBoundingRect();
149
+ const objectHeight =
150
+ objectBoundingRect.height / viewportTransform[3];
151
+ const objectWidth =
152
+ objectBoundingRect.width / viewportTransform[0];
153
+
154
+ // snap by the horizontal center line
155
+ //水平中心线
156
+ if (isInRange(objectLeft, activeObjectLeft)) {
157
+ verticalInTheRange = true;
158
+ verticalLines = [];
159
+ verticalLines.push({
160
+ x: objectLeft,
161
+ y1:
162
+ objectTop < activeObjectTop
163
+ ? objectTop -
164
+ objectHeight / 2 -
165
+ aligningLineOffset
166
+ : objectTop +
167
+ objectHeight / 2 +
168
+ aligningLineOffset,
169
+ y2:
170
+ activeObjectTop > objectTop
171
+ ? activeObjectTop +
172
+ activeObjectHeight / 2 +
173
+ aligningLineOffset
174
+ : activeObjectTop -
175
+ activeObjectHeight / 2 -
176
+ aligningLineOffset,
177
+ });
178
+ activeObject.setPositionByOrigin(
179
+ new fabric.Point(objectLeft, activeObjectTop),
180
+ 'center',
181
+ 'center'
182
+ );
183
+ }
184
+
185
+ // snap by the vertical center line
186
+ //垂直中心线
187
+ if (isInRange(objectTop, activeObjectTop)) {
188
+ horizontalInTheRange = true;
189
+ horizontalLines = [];
190
+ horizontalLines.push({
191
+ y: objectTop,
192
+ x1:
193
+ objectLeft < activeObjectLeft
194
+ ? objectLeft -
195
+ objectWidth / 2 -
196
+ aligningLineOffset
197
+ : objectLeft +
198
+ objectWidth / 2 +
199
+ aligningLineOffset,
200
+ x2:
201
+ activeObjectLeft > objectLeft
202
+ ? activeObjectLeft +
203
+ activeObjectWidth / 2 +
204
+ aligningLineOffset
205
+ : activeObjectLeft -
206
+ activeObjectWidth / 2 -
207
+ aligningLineOffset,
208
+ });
209
+ activeObject.setPositionByOrigin(
210
+ new fabric.Point(activeObjectLeft, objectTop),
211
+ 'center',
212
+ 'center'
213
+ );
214
+ }
215
+ // snap by the left edge
216
+ //左边线
217
+ if (
218
+ isInRange(
219
+ objectLeft - objectWidth / 2,
220
+ activeObjectLeft - activeObjectWidth / 2
221
+ )
222
+ ) {
223
+ verticalInTheRange = true;
224
+ verticalLines = [];
225
+ reachLeft = true;
226
+ verticalLines.push({
227
+ x: objectLeft - objectWidth / 2,
228
+ y1:
229
+ objectTop < activeObjectTop
230
+ ? objectTop -
231
+ objectHeight / 2 -
232
+ aligningLineOffset
233
+ : objectTop +
234
+ objectHeight / 2 +
235
+ aligningLineOffset,
236
+ y2:
237
+ activeObjectTop > objectTop
238
+ ? activeObjectTop +
239
+ activeObjectHeight / 2 +
240
+ aligningLineOffset
241
+ : activeObjectTop -
242
+ activeObjectHeight / 2 -
243
+ aligningLineOffset,
244
+ });
245
+ _elReachLeft =
246
+ objectLeft - objectWidth / 2 + activeObjectWidth / 2;
247
+ let x =
248
+ objectLeft - objectWidth / 2 + activeObjectWidth / 2;
249
+ let y = reachTop ? _elReachTop : activeObjectTop;
250
+
251
+ activeObject.setPositionByOrigin(
252
+ new fabric.Point(x, y),
253
+ 'center',
254
+ 'center'
255
+ );
256
+ }
257
+
258
+ // snap by the right edge
259
+ //右边线
260
+ if (
261
+ isInRange(
262
+ objectLeft + objectWidth / 2,
263
+ activeObjectLeft + activeObjectWidth / 2
264
+ )
265
+ ) {
266
+ reachLeft = true;
267
+ verticalInTheRange = true;
268
+ verticalLines = [];
269
+ verticalLines.push({
270
+ x: objectLeft + objectWidth / 2,
271
+ y1:
272
+ objectTop < activeObjectTop
273
+ ? objectTop -
274
+ objectHeight / 2 -
275
+ aligningLineOffset
276
+ : objectTop +
277
+ objectHeight / 2 +
278
+ aligningLineOffset,
279
+ y2:
280
+ activeObjectTop > objectTop
281
+ ? activeObjectTop +
282
+ activeObjectHeight / 2 +
283
+ aligningLineOffset
284
+ : activeObjectTop -
285
+ activeObjectHeight / 2 -
286
+ aligningLineOffset,
287
+ });
288
+ _elReachLeft =
289
+ objectLeft + objectWidth / 2 - activeObjectWidth / 2;
290
+ let x =
291
+ objectLeft + objectWidth / 2 - activeObjectWidth / 2;
292
+ let y = reachTop ? _elReachTop : activeObjectTop;
293
+ activeObject.setPositionByOrigin(
294
+ new fabric.Point(x, y),
295
+ 'center',
296
+ 'center'
297
+ );
298
+ }
299
+
300
+ // snap by the top edge
301
+ //上边线
302
+ if (
303
+ isInRange(
304
+ objectTop - objectHeight / 2,
305
+ activeObjectTop - activeObjectHeight / 2
306
+ )
307
+ ) {
308
+ reachTop = true;
309
+ horizontalInTheRange = true;
310
+ horizontalLines = [];
311
+ horizontalLines.push({
312
+ y: objectTop - objectHeight / 2,
313
+ x1:
314
+ objectLeft < activeObjectLeft
315
+ ? objectLeft -
316
+ objectWidth / 2 -
317
+ aligningLineOffset
318
+ : objectLeft +
319
+ objectWidth / 2 +
320
+ aligningLineOffset,
321
+ x2:
322
+ activeObjectLeft > objectLeft
323
+ ? activeObjectLeft +
324
+ activeObjectWidth / 2 +
325
+ aligningLineOffset
326
+ : activeObjectLeft -
327
+ activeObjectWidth / 2 -
328
+ aligningLineOffset,
329
+ });
330
+ _elReachTop =
331
+ objectTop - objectHeight / 2 + activeObjectHeight / 2;
332
+ let x = reachLeft ? _elReachLeft : activeObjectLeft;
333
+ let y =
334
+ objectTop - objectHeight / 2 + activeObjectHeight / 2;
335
+ activeObject.setPositionByOrigin(
336
+ new fabric.Point(x, y),
337
+ 'center',
338
+ 'center'
339
+ );
340
+ }
341
+
342
+ // snap by the bottom edge
343
+ //底边线
344
+ if (
345
+ isInRange(
346
+ objectTop + objectHeight / 2,
347
+ activeObjectTop + activeObjectHeight / 2
348
+ )
349
+ ) {
350
+ reachTop = true;
351
+
352
+ horizontalInTheRange = true;
353
+ horizontalLines = [];
354
+ horizontalLines.push({
355
+ y: objectTop + objectHeight / 2,
356
+ x1:
357
+ objectLeft < activeObjectLeft
358
+ ? objectLeft -
359
+ objectWidth / 2 -
360
+ aligningLineOffset
361
+ : objectLeft +
362
+ objectWidth / 2 +
363
+ aligningLineOffset,
364
+ x2:
365
+ activeObjectLeft > objectLeft
366
+ ? activeObjectLeft +
367
+ activeObjectWidth / 2 +
368
+ aligningLineOffset
369
+ : activeObjectLeft -
370
+ activeObjectWidth / 2 -
371
+ aligningLineOffset,
372
+ });
373
+ _elReachTop =
374
+ objectTop + objectHeight / 2 - activeObjectHeight / 2;
375
+ let x = reachLeft ? _elReachLeft : activeObjectLeft;
376
+ let y =
377
+ objectTop + objectHeight / 2 - activeObjectHeight / 2;
378
+ activeObject.setPositionByOrigin(
379
+ new fabric.Point(x, y),
380
+ 'center',
381
+ 'center'
382
+ );
383
+ }
384
+
385
+ //左边线和右边线
386
+ if (
387
+ isInRange(
388
+ objectLeft - objectWidth / 2,
389
+ activeObjectLeft + activeObjectWidth / 2
390
+ )
391
+ ) {
392
+ reachLeft = true;
393
+ verticalInTheRange = true;
394
+ verticalInTheRange = [];
395
+ verticalLines.push({
396
+ x: objectLeft - objectWidth / 2,
397
+ y1:
398
+ objectTop < activeObjectTop
399
+ ? objectTop -
400
+ objectHeight / 2 -
401
+ aligningLineOffset
402
+ : objectTop +
403
+ objectHeight / 2 +
404
+ aligningLineOffset,
405
+ y2:
406
+ activeObjectTop > objectTop
407
+ ? activeObjectTop +
408
+ activeObjectHeight / 2 +
409
+ aligningLineOffset
410
+ : activeObjectTop -
411
+ activeObjectHeight / 2 -
412
+ aligningLineOffset,
413
+ });
414
+
415
+ _elReachLeft =
416
+ objectLeft - objectWidth / 2 - activeObjectWidth / 2;
417
+ let x =
418
+ objectLeft - objectWidth / 2 - activeObjectWidth / 2;
419
+ let y = activeObjectTop;
420
+
421
+ activeObject.setPositionByOrigin(
422
+ new fabric.Point(x, y),
423
+ 'center',
424
+ 'center'
425
+ );
426
+ }
427
+ //右边线和左边线
428
+ if (
429
+ isInRange(
430
+ objectLeft + objectWidth / 2,
431
+ activeObjectLeft - activeObjectWidth / 2
432
+ )
433
+ ) {
434
+ reachLeft = true;
435
+ verticalInTheRange = true;
436
+ verticalInTheRange = [];
437
+ verticalLines.push({
438
+ x: objectLeft + objectWidth / 2,
439
+ y1:
440
+ objectTop < activeObjectTop
441
+ ? objectTop -
442
+ objectHeight / 2 -
443
+ aligningLineOffset
444
+ : objectTop +
445
+ objectHeight / 2 +
446
+ aligningLineOffset,
447
+ y2:
448
+ activeObjectTop > objectTop
449
+ ? activeObjectTop +
450
+ activeObjectHeight / 2 +
451
+ aligningLineOffset
452
+ : activeObjectTop -
453
+ activeObjectHeight / 2 -
454
+ aligningLineOffset,
455
+ });
456
+ _elReachLeft =
457
+ objectLeft + objectWidth / 2 + activeObjectWidth / 2;
458
+
459
+ let x =
460
+ objectLeft + objectWidth / 2 + activeObjectWidth / 2;
461
+ let y = activeObjectTop;
462
+
463
+ activeObject.setPositionByOrigin(
464
+ new fabric.Point(x, y),
465
+ 'center',
466
+ 'center'
467
+ );
468
+ }
469
+ //上边线和下边线
470
+ if (
471
+ isInRange(
472
+ objectTop - objectHeight / 2,
473
+ activeObjectTop + activeObjectHeight / 2
474
+ )
475
+ ) {
476
+ reachTop = true;
477
+ horizontalInTheRange = true;
478
+ horizontalLines = [];
479
+ horizontalLines.push({
480
+ y: objectTop - objectHeight / 2,
481
+ x1:
482
+ objectLeft < activeObjectLeft
483
+ ? objectLeft -
484
+ objectWidth / 2 -
485
+ aligningLineOffset
486
+ : objectLeft +
487
+ objectWidth / 2 +
488
+ aligningLineOffset,
489
+ x2:
490
+ activeObjectLeft > objectLeft
491
+ ? activeObjectLeft +
492
+ activeObjectWidth / 2 +
493
+ aligningLineOffset
494
+ : activeObjectLeft -
495
+ activeObjectWidth / 2 -
496
+ aligningLineOffset,
497
+ });
498
+ _elReachTop =
499
+ objectTop - objectHeight / 2 - activeObjectHeight / 2;
500
+
501
+ let x = reachLeft ? _elReachLeft : activeObjectLeft;
502
+ let y =
503
+ objectTop - objectHeight / 2 - activeObjectHeight / 2;
504
+ activeObject.setPositionByOrigin(
505
+ new fabric.Point(x, y),
506
+ 'center',
507
+ 'center'
508
+ );
509
+ }
510
+ //下边线和上变线
511
+ if (
512
+ isInRange(
513
+ objectTop + objectHeight / 2,
514
+ activeObjectTop - activeObjectHeight / 2
515
+ )
516
+ ) {
517
+ reachTop = true;
518
+ horizontalInTheRange = true;
519
+ horizontalLines = [];
520
+ horizontalLines.push({
521
+ y: objectTop + objectHeight / 2,
522
+ x1:
523
+ objectLeft < activeObjectLeft
524
+ ? objectLeft -
525
+ objectWidth / 2 -
526
+ aligningLineOffset
527
+ : objectLeft +
528
+ objectWidth / 2 +
529
+ aligningLineOffset,
530
+ x2:
531
+ activeObjectLeft > objectLeft
532
+ ? activeObjectLeft +
533
+ activeObjectWidth / 2 +
534
+ aligningLineOffset
535
+ : activeObjectLeft -
536
+ activeObjectWidth / 2 -
537
+ aligningLineOffset,
538
+ });
539
+ _elReachTop =
540
+ objectTop + objectHeight / 2 + activeObjectHeight / 2;
541
+ let x = reachLeft ? _elReachLeft : activeObjectLeft;
542
+ let y =
543
+ objectTop + objectHeight / 2 + activeObjectHeight / 2;
544
+ activeObject.setPositionByOrigin(
545
+ new fabric.Point(x, y),
546
+ 'center',
547
+ 'center'
548
+ );
549
+ }
550
+ }
551
+
552
+ if (!horizontalInTheRange) {
553
+ horizontalLines.length = 0;
554
+ }
555
+
556
+ if (!verticalInTheRange) {
557
+ verticalLines.length = 0;
558
+ }
559
+ });
560
+
561
+ canvas.on('before:render', () => {
562
+ // fix 保存图片时报错
563
+ if (canvas.contextTop === null) {
564
+ return;
565
+ }
566
+ try {
567
+ canvas.clearContext(canvas.contextTop);
568
+ } catch (error) {
569
+ console.log(error);
570
+ }
571
+ });
572
+
573
+ canvas.on('object:scaling', (e) => {
574
+ if (viewportTransform === undefined || e.target === undefined)
575
+ return;
576
+
577
+ const activeObject = e.target;
578
+ const canvasObjects = canvas.getObjects();
579
+ const activeObjectCenter = activeObject.getCenterPoint();
580
+ const activeObjectLeft = activeObjectCenter.x;
581
+ const activeObjectTop = activeObjectCenter.y;
582
+ const activeObjectBoundingRect = activeObject.getBoundingRect();
583
+ const activeObjectHeight = activeObject.getScaledHeight();
584
+ const activeObjectWidth = activeObject.getScaledWidth();
585
+ let horizontalInTheRange = false;
586
+ let verticalInTheRange = false;
587
+ const transform = canvas._currentTransform;
588
+
589
+ activeObject.set('hasControls', false);
590
+ if (!transform) return;
591
+
592
+ for (let i = canvasObjects.length; i--; ) {
593
+ // eslint-disable-next-line no-continue
594
+ if (canvasObjects[i] === activeObject) continue;
595
+
596
+ // 排除辅助线
597
+ if (
598
+ activeObject instanceof fabric.GuideLine &&
599
+ canvasObjects[i] instanceof fabric.GuideLine
600
+ ) {
601
+ continue;
602
+ }
603
+
604
+ const objectCenter = canvasObjects[i].getCenterPoint();
605
+ const objectLeft = objectCenter.x;
606
+ const objectTop = objectCenter.y;
607
+ const objectBoundingRect = canvasObjects[i].getBoundingRect();
608
+ const objectHeight =
609
+ objectBoundingRect.height / viewportTransform[3];
610
+ const objectWidth =
611
+ objectBoundingRect.width / viewportTransform[0];
612
+
613
+ // snap by the horizontal center line
614
+ //水平中心线
615
+ if (isInRange(objectLeft, activeObjectLeft)) {
616
+ verticalInTheRange = true;
617
+ verticalLines = [];
618
+ verticalLines.push({
619
+ x: objectLeft,
620
+ y1:
621
+ objectTop < activeObjectTop
622
+ ? objectTop -
623
+ objectHeight / 2 -
624
+ aligningLineOffset
625
+ : objectTop +
626
+ objectHeight / 2 +
627
+ aligningLineOffset,
628
+ y2:
629
+ activeObjectTop > objectTop
630
+ ? activeObjectTop +
631
+ activeObjectHeight / 2 +
632
+ aligningLineOffset
633
+ : activeObjectTop -
634
+ activeObjectHeight / 2 -
635
+ aligningLineOffset,
636
+ });
637
+ }
638
+
639
+ // snap by the left edge
640
+ //左边线
641
+ if (
642
+ isInRange(
643
+ objectLeft - objectWidth / 2,
644
+ activeObjectLeft - activeObjectWidth / 2
645
+ )
646
+ ) {
647
+ verticalInTheRange = true;
648
+ verticalLines = [];
649
+ verticalLines.push({
650
+ x: objectLeft - objectWidth / 2,
651
+ y1:
652
+ objectTop < activeObjectTop
653
+ ? objectTop -
654
+ objectHeight / 2 -
655
+ aligningLineOffset
656
+ : objectTop +
657
+ objectHeight / 2 +
658
+ aligningLineOffset,
659
+ y2:
660
+ activeObjectTop > objectTop
661
+ ? activeObjectTop +
662
+ activeObjectHeight / 2 +
663
+ aligningLineOffset
664
+ : activeObjectTop -
665
+ activeObjectHeight / 2 -
666
+ aligningLineOffset,
667
+ });
668
+
669
+ let leftRight = new Map([
670
+ ['bl', 1],
671
+ ['ml', 1],
672
+ ['tl', 1],
673
+ ]);
674
+ if (leftRight.get(e.transform.corner)) {
675
+ activeObject.setPositionByOrigin(
676
+ new fabric.Point(
677
+ objectLeft -
678
+ objectWidth / 2 +
679
+ activeObjectWidth / 2,
680
+ activeObjectTop
681
+ ),
682
+ 'center',
683
+ 'center'
684
+ );
685
+
686
+ activeObject.set(
687
+ 'scaleX',
688
+ ((activeLeft -
689
+ (objectLeft - objectWidth / 2) +
690
+ activeWidth) *
691
+ activeObject.scaleX) /
692
+ activeObject.getScaledWidth()
693
+ );
694
+ break;
695
+ }
696
+ }
697
+
698
+ // snap by the right edge
699
+ //右边线
700
+ if (
701
+ isInRange(
702
+ objectLeft + objectWidth / 2,
703
+ activeObjectLeft + activeObjectWidth / 2
704
+ )
705
+ ) {
706
+ verticalInTheRange = true;
707
+ verticalLines = [];
708
+ verticalLines.push({
709
+ x: objectLeft + objectWidth / 2,
710
+ y1:
711
+ objectTop < activeObjectTop
712
+ ? objectTop -
713
+ objectHeight / 2 -
714
+ aligningLineOffset
715
+ : objectTop +
716
+ objectHeight / 2 +
717
+ aligningLineOffset,
718
+ y2:
719
+ activeObjectTop > objectTop
720
+ ? activeObjectTop +
721
+ activeObjectHeight / 2 +
722
+ aligningLineOffset
723
+ : activeObjectTop -
724
+ activeObjectHeight / 2 -
725
+ aligningLineOffset,
726
+ });
727
+
728
+ let Right = new Map([
729
+ ['mr', 1],
730
+ ['tr', 1],
731
+ ['br', 1],
732
+ ]);
733
+
734
+ if (Right.get(e.transform.corner)) {
735
+ activeObject.set(
736
+ 'scaleX',
737
+ ((objectLeft +
738
+ objectWidth / 2 -
739
+ (activeLeft + activeWidth) +
740
+ activeWidth) *
741
+ activeObject.scaleX) /
742
+ activeObject.getScaledWidth()
743
+ );
744
+ break;
745
+ }
746
+ }
747
+
748
+ // snap by the vertical center line
749
+ //垂直中心线
750
+ if (isInRange(objectTop, activeObjectTop)) {
751
+ horizontalInTheRange = true;
752
+ horizontalLines = [];
753
+ horizontalLines.push({
754
+ y: objectTop,
755
+ x1:
756
+ objectLeft < activeObjectLeft
757
+ ? objectLeft -
758
+ objectWidth / 2 -
759
+ aligningLineOffset
760
+ : objectLeft +
761
+ objectWidth / 2 +
762
+ aligningLineOffset,
763
+ x2:
764
+ activeObjectLeft > objectLeft
765
+ ? activeObjectLeft +
766
+ activeObjectWidth / 2 +
767
+ aligningLineOffset
768
+ : activeObjectLeft -
769
+ activeObjectWidth / 2 -
770
+ aligningLineOffset,
771
+ });
772
+ }
773
+
774
+ // snap by the top edge
775
+ if (
776
+ isInRange(
777
+ objectTop - objectHeight / 2,
778
+ activeObjectTop - activeObjectHeight / 2
779
+ )
780
+ ) {
781
+ horizontalInTheRange = true;
782
+ horizontalLines = [];
783
+ horizontalLines.push({
784
+ y: objectTop - objectHeight / 2,
785
+ x1:
786
+ objectLeft < activeObjectLeft
787
+ ? objectLeft -
788
+ objectWidth / 2 -
789
+ aligningLineOffset
790
+ : objectLeft +
791
+ objectWidth / 2 +
792
+ aligningLineOffset,
793
+ x2:
794
+ activeObjectLeft > objectLeft
795
+ ? activeObjectLeft +
796
+ activeObjectWidth / 2 +
797
+ aligningLineOffset
798
+ : activeObjectLeft -
799
+ activeObjectWidth / 2 -
800
+ aligningLineOffset,
801
+ });
802
+
803
+ let bottomRight = new Map([
804
+ ['tr', 1],
805
+ ['tl', 1],
806
+ ['mt', 1],
807
+ ]);
808
+
809
+ if (bottomRight.get(e.transform.corner)) {
810
+ activeObject.setPositionByOrigin(
811
+ new fabric.Point(
812
+ activeObjectLeft,
813
+ objectTop -
814
+ objectHeight / 2 +
815
+ activeObjectHeight / 2
816
+ ),
817
+ 'center',
818
+ 'center'
819
+ );
820
+
821
+ activeObject.set(
822
+ 'scaleY',
823
+ ((activeTop +
824
+ activeHeight -
825
+ (objectTop - objectHeight / 2)) *
826
+ activeObject.scaleY) /
827
+ activeObject.getScaledHeight()
828
+ );
829
+ break;
830
+ }
831
+ }
832
+
833
+ // snap by the bottom edge
834
+ if (
835
+ isInRange(
836
+ objectTop + objectHeight / 2,
837
+ activeObjectTop + activeObjectHeight / 2
838
+ )
839
+ ) {
840
+ horizontalInTheRange = true;
841
+ horizontalLines = [];
842
+ horizontalLines.push({
843
+ y: objectTop + objectHeight / 2,
844
+ x1:
845
+ objectLeft < activeObjectLeft
846
+ ? objectLeft -
847
+ objectWidth / 2 -
848
+ aligningLineOffset
849
+ : objectLeft +
850
+ objectWidth / 2 +
851
+ aligningLineOffset,
852
+ x2:
853
+ activeObjectLeft > objectLeft
854
+ ? activeObjectLeft +
855
+ activeObjectWidth / 2 +
856
+ aligningLineOffset
857
+ : activeObjectLeft -
858
+ activeObjectWidth / 2 -
859
+ aligningLineOffset,
860
+ });
861
+
862
+ let bottom = new Map([
863
+ ['mb', 1],
864
+ ['bl', 1],
865
+ ['br', 1],
866
+ ]);
867
+ if (bottom.get(e.transform.corner)) {
868
+ activeObject.set(
869
+ 'scaleY',
870
+ ((objectTop +
871
+ objectHeight / 2 -
872
+ (activeTop + activeHeight) +
873
+ activeHeight) *
874
+ activeObject.scaleY) /
875
+ activeObject.getScaledHeight()
876
+ );
877
+ break;
878
+ }
879
+ }
880
+
881
+ //左边线和右边线
882
+ if (
883
+ isInRange(
884
+ objectLeft - objectWidth / 2,
885
+ activeObjectLeft + activeObjectWidth / 2
886
+ )
887
+ ) {
888
+ verticalInTheRange = true;
889
+ verticalLines = [];
890
+ verticalLines.push({
891
+ x: objectLeft - objectWidth / 2,
892
+ y1:
893
+ objectTop < activeObjectTop
894
+ ? objectTop -
895
+ objectHeight / 2 -
896
+ aligningLineOffset
897
+ : objectTop +
898
+ objectHeight / 2 +
899
+ aligningLineOffset,
900
+ y2:
901
+ activeObjectTop > objectTop
902
+ ? activeObjectTop +
903
+ activeObjectHeight / 2 +
904
+ aligningLineOffset
905
+ : activeObjectTop -
906
+ activeObjectHeight / 2 -
907
+ aligningLineOffset,
908
+ });
909
+
910
+ let right = new Map([
911
+ ['mr', 1],
912
+ ['tr', 1],
913
+ ['br', 1],
914
+ ]);
915
+ if (right.get(e.transform.corner)) {
916
+ activeObject.set(
917
+ 'scaleX',
918
+ ((objectLeft -
919
+ objectWidth / 2 -
920
+ activeObject.left) *
921
+ activeObject.scaleX) /
922
+ activeObject.getScaledWidth()
923
+ );
924
+ break;
925
+ }
926
+ }
927
+ //右边线和左边线
928
+ if (
929
+ isInRange(
930
+ objectLeft + objectWidth / 2,
931
+ activeObjectLeft - activeObjectWidth / 2
932
+ )
933
+ ) {
934
+ verticalInTheRange = true;
935
+ verticalLines = [];
936
+ verticalLines.push({
937
+ x: objectLeft + objectWidth / 2,
938
+ y1:
939
+ objectTop < activeObjectTop
940
+ ? objectTop -
941
+ objectHeight / 2 -
942
+ aligningLineOffset
943
+ : objectTop +
944
+ objectHeight / 2 +
945
+ aligningLineOffset,
946
+ y2:
947
+ activeObjectTop > objectTop
948
+ ? activeObjectTop +
949
+ activeObjectHeight / 2 +
950
+ aligningLineOffset
951
+ : activeObjectTop -
952
+ activeObjectHeight / 2 -
953
+ aligningLineOffset,
954
+ });
955
+
956
+ let leftRight = new Map([
957
+ ['bl', 1],
958
+ ['ml', 1],
959
+ ['tl', 1],
960
+ ]);
961
+ if (leftRight.get(e.transform.corner)) {
962
+ activeObject.setPositionByOrigin(
963
+ new fabric.Point(
964
+ objectLeft +
965
+ objectWidth / 2 +
966
+ activeObjectWidth / 2,
967
+ activeObjectTop
968
+ ),
969
+ 'center',
970
+ 'center'
971
+ );
972
+
973
+ activeObject.set(
974
+ 'scaleX',
975
+ ((activeLeft +
976
+ activeWidth -
977
+ (objectLeft + objectWidth / 2)) *
978
+ activeObject.scaleX) /
979
+ activeObject.getScaledWidth()
980
+ );
981
+ break;
982
+ }
983
+ }
984
+ //上边线和下边线
985
+ if (
986
+ isInRange(
987
+ objectTop - objectHeight / 2,
988
+ activeObjectTop + activeObjectHeight / 2
989
+ )
990
+ ) {
991
+ horizontalInTheRange = true;
992
+ horizontalLines = [];
993
+ horizontalLines.push({
994
+ y: objectTop - objectHeight / 2,
995
+ x1:
996
+ objectLeft < activeObjectLeft
997
+ ? objectLeft -
998
+ objectWidth / 2 -
999
+ aligningLineOffset
1000
+ : objectLeft +
1001
+ objectWidth / 2 +
1002
+ aligningLineOffset,
1003
+ x2:
1004
+ activeObjectLeft > objectLeft
1005
+ ? activeObjectLeft +
1006
+ activeObjectWidth / 2 +
1007
+ aligningLineOffset
1008
+ : activeObjectLeft -
1009
+ activeObjectWidth / 2 -
1010
+ aligningLineOffset,
1011
+ });
1012
+
1013
+ let bottom = new Map([
1014
+ ['mb', 1],
1015
+ ['bl', 1],
1016
+ ['br', 1],
1017
+ ]);
1018
+ if (bottom.get(e.transform.corner)) {
1019
+ activeObject.set(
1020
+ 'scaleY',
1021
+ ((objectTop - objectHeight / 2 - activeObject.top) *
1022
+ activeObject.scaleY) /
1023
+ activeObject.getScaledHeight()
1024
+ );
1025
+ break;
1026
+ }
1027
+ }
1028
+ //下边线和上变线
1029
+ if (
1030
+ isInRange(
1031
+ objectTop + objectHeight / 2,
1032
+ activeObjectTop - activeObjectHeight / 2
1033
+ )
1034
+ ) {
1035
+ horizontalInTheRange = true;
1036
+ horizontalLines = [];
1037
+ horizontalLines.push({
1038
+ y: objectTop + objectHeight / 2,
1039
+ x1:
1040
+ objectLeft < activeObjectLeft
1041
+ ? objectLeft -
1042
+ objectWidth / 2 -
1043
+ aligningLineOffset
1044
+ : objectLeft +
1045
+ objectWidth / 2 +
1046
+ aligningLineOffset,
1047
+ x2:
1048
+ activeObjectLeft > objectLeft
1049
+ ? activeObjectLeft +
1050
+ activeObjectWidth / 2 +
1051
+ aligningLineOffset
1052
+ : activeObjectLeft -
1053
+ activeObjectWidth / 2 -
1054
+ aligningLineOffset,
1055
+ });
1056
+
1057
+ let bottomRight = new Map([
1058
+ ['tr', 1],
1059
+ ['tl', 1],
1060
+ ['mt', 1],
1061
+ ]);
1062
+
1063
+ if (bottomRight.get(e.transform.corner)) {
1064
+ activeObject.setPositionByOrigin(
1065
+ new fabric.Point(
1066
+ activeObjectLeft,
1067
+ objectTop +
1068
+ objectHeight / 2 +
1069
+ activeObjectHeight / 2
1070
+ ),
1071
+ 'center',
1072
+ 'center'
1073
+ );
1074
+
1075
+ activeObject.set(
1076
+ 'scaleY',
1077
+ ((activeTop +
1078
+ activeHeight -
1079
+ (objectTop + objectHeight / 2)) *
1080
+ activeObject.scaleY) /
1081
+ activeObject.getScaledHeight()
1082
+ );
1083
+
1084
+ break;
1085
+ }
1086
+ }
1087
+ }
1088
+
1089
+ if (!horizontalInTheRange) {
1090
+ horizontalLines.length = 0;
1091
+ }
1092
+
1093
+ if (!verticalInTheRange) {
1094
+ verticalLines.length = 0;
1095
+ }
1096
+ });
1097
+ canvas.on('after:render', () => {
1098
+ ctx.save();
1099
+ ctx.beginPath();
1100
+ ctx.lineWidth = This.defautOption.width;
1101
+ ctx.strokeStyle = This.defautOption.color;
1102
+
1103
+ for (let i = verticalLines.length; i--; ) {
1104
+ if (verticalLines[i]) {
1105
+ drawVerticalLine(verticalLines[i]);
1106
+ }
1107
+ }
1108
+ for (let j = horizontalLines.length; j--; ) {
1109
+ if (horizontalLines[j]) {
1110
+ drawHorizontalLine(horizontalLines[j]);
1111
+ }
1112
+ }
1113
+ ctx.stroke();
1114
+ ctx.restore();
1115
+
1116
+ // noinspection NestedAssignmentJS
1117
+ verticalLines.length = 0;
1118
+ horizontalLines.length = 0;
1119
+ });
1120
+
1121
+ canvas.on('mouse:up', (e) => {
1122
+ const activeObject = e.target;
1123
+ if (
1124
+ activeObject &&
1125
+ activeObject.selectable &&
1126
+ !activeObject.lockRotation
1127
+ ) {
1128
+ activeObject.set('hasControls', true);
1129
+ }
1130
+ verticalLines.length = 0;
1131
+ horizontalLines.length = 0;
1132
+ canvas.renderAll();
1133
+ });
1134
+ }
1135
+
1136
+ destroy() {
1137
+ console.log('pluginDestroy');
1138
+ }
1139
+ }
1140
+
1141
+ export default AlignGuidLinePlugin;