@hprint/plugins 0.0.1-alpha.1 → 0.0.1-alpha.3

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