@plait/core 0.1.1 → 0.1.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 (60) hide show
  1. package/board/board.component.d.ts +8 -21
  2. package/board/board.component.interface.d.ts +0 -2
  3. package/constants/selection.d.ts +1 -0
  4. package/core/element/element.component.d.ts +1 -1
  5. package/core/element/plugin-element.d.ts +1 -1
  6. package/core/toolbar/toolbar.component.d.ts +1 -1
  7. package/esm2020/board/board.component.interface.mjs +1 -1
  8. package/esm2020/board/board.component.mjs +94 -279
  9. package/esm2020/constants/selection.mjs +2 -0
  10. package/esm2020/core/element/element.component.mjs +5 -5
  11. package/esm2020/core/element/plugin-element.mjs +9 -9
  12. package/esm2020/core/toolbar/toolbar.component.mjs +4 -4
  13. package/esm2020/interfaces/board.mjs +11 -2
  14. package/esm2020/interfaces/point.mjs +6 -2
  15. package/esm2020/interfaces/viewport.mjs +2 -2
  16. package/esm2020/plait.module.mjs +5 -5
  17. package/esm2020/plugins/create-board.mjs +2 -1
  18. package/esm2020/plugins/with-hand.mjs +6 -6
  19. package/esm2020/plugins/with-moving.mjs +91 -0
  20. package/esm2020/plugins/with-selection.mjs +48 -13
  21. package/esm2020/plugins/with-viewport.mjs +29 -0
  22. package/esm2020/public-api.mjs +2 -1
  23. package/esm2020/utils/board.mjs +7 -3
  24. package/esm2020/utils/common.mjs +15 -0
  25. package/esm2020/utils/element.mjs +3 -3
  26. package/esm2020/utils/helper.mjs +14 -1
  27. package/esm2020/utils/index.mjs +4 -2
  28. package/esm2020/utils/moving-element.mjs +15 -0
  29. package/esm2020/utils/selected-element.mjs +14 -1
  30. package/esm2020/utils/viewport.mjs +207 -0
  31. package/esm2020/utils/weak-maps.mjs +5 -1
  32. package/fesm2015/plait-core.mjs +689 -626
  33. package/fesm2015/plait-core.mjs.map +1 -1
  34. package/fesm2020/plait-core.mjs +710 -644
  35. package/fesm2020/plait-core.mjs.map +1 -1
  36. package/interfaces/board.d.ts +4 -10
  37. package/interfaces/custom-types.d.ts +2 -2
  38. package/interfaces/node.d.ts +1 -1
  39. package/interfaces/operation.d.ts +7 -7
  40. package/interfaces/path.d.ts +1 -1
  41. package/interfaces/plugin.d.ts +1 -1
  42. package/interfaces/point.d.ts +4 -1
  43. package/interfaces/viewport.d.ts +4 -3
  44. package/package.json +3 -3
  45. package/plugins/with-moving.d.ts +2 -0
  46. package/plugins/with-selection.d.ts +4 -1
  47. package/plugins/with-viewport.d.ts +2 -0
  48. package/public-api.d.ts +1 -0
  49. package/styles/styles.scss +3 -1
  50. package/utils/board.d.ts +2 -2
  51. package/utils/common.d.ts +1 -0
  52. package/utils/helper.d.ts +9 -0
  53. package/utils/index.d.ts +3 -1
  54. package/utils/moving-element.d.ts +5 -0
  55. package/utils/selected-element.d.ts +2 -0
  56. package/utils/viewport.d.ts +36 -0
  57. package/utils/weak-maps.d.ts +4 -0
  58. package/esm2020/utils/matrix.mjs +0 -170
  59. package/utils/matrix.d.ts +0 -82
  60. /package/{plait-core.d.ts → index.d.ts} +0 -0
@@ -1,16 +1,105 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Component, ChangeDetectionStrategy, Input, EventEmitter, HostBinding, Output, ElementRef, ViewChild, ContentChild, Directive, NgModule } from '@angular/core';
3
3
  import rough from 'roughjs/bin/rough';
4
- import { Subject, fromEvent } from 'rxjs';
5
- import { takeUntil, filter } from 'rxjs/operators';
4
+ import { timer, Subject, fromEvent } from 'rxjs';
5
+ import { takeUntil, filter, tap, debounceTime } from 'rxjs/operators';
6
6
  import produce, { createDraft, finishDraft, isDraft } from 'immer';
7
7
  import { isKeyHotkey, isHotkey } from 'is-hotkey';
8
8
  import * as i1 from '@angular/common';
9
9
  import { BrowserModule } from '@angular/platform-browser';
10
10
 
11
- const CLIP_BOARD_FORMAT_KEY = 'x-plait-fragment';
12
- const SCROLL_BAR_WIDTH = 20;
13
- const MAX_RADIUS = 16;
11
+ // record richtext type status
12
+ const FLUSHING = new WeakMap();
13
+ const IS_TEXT_EDITABLE = new WeakMap();
14
+ const BOARD_TO_ON_CHANGE = new WeakMap();
15
+ const BOARD_TO_COMPONENT = new WeakMap();
16
+ const BOARD_TO_ROUGH_SVG = new WeakMap();
17
+ const BOARD_TO_HOST = new WeakMap();
18
+ const BOARD_TO_ELEMENT_HOST = new WeakMap();
19
+ const BOARD_TO_SELECTED_ELEMENT = new WeakMap();
20
+ const BOARD_TO_MOVING_POINT = new WeakMap();
21
+ const BOARD_TO_VIEWPORT_ORIGINATION = new WeakMap();
22
+ const BOARD_TO_IS_SELECTION_MOVING = new WeakMap();
23
+ // save no standard selected elements
24
+ const BOARD_TO_TEMPORARY_ELEMENTS = new WeakMap();
25
+ const BOARD_TO_MOVING_ELEMENT = new WeakMap();
26
+ const BOARD_TO_SCROLLING = new WeakMap();
27
+
28
+ function depthFirstRecursion(node, callback) {
29
+ var _a;
30
+ (_a = node.children) === null || _a === void 0 ? void 0 : _a.forEach(child => {
31
+ depthFirstRecursion(child, callback);
32
+ });
33
+ callback(node);
34
+ }
35
+
36
+ function getRectangleByElements(board, elements, recursion) {
37
+ const boundaryBox = {
38
+ left: Number.MAX_VALUE,
39
+ top: Number.MAX_VALUE,
40
+ right: Number.NEGATIVE_INFINITY,
41
+ bottom: Number.NEGATIVE_INFINITY
42
+ };
43
+ const calcRectangleClient = (node) => {
44
+ const nodeRectangle = board.getRectangle(node);
45
+ if (nodeRectangle) {
46
+ boundaryBox.left = Math.min(boundaryBox.left, nodeRectangle.x);
47
+ boundaryBox.top = Math.min(boundaryBox.top, nodeRectangle.y);
48
+ boundaryBox.right = Math.max(boundaryBox.right, nodeRectangle.x + nodeRectangle.width);
49
+ boundaryBox.bottom = Math.max(boundaryBox.bottom, nodeRectangle.y + nodeRectangle.height);
50
+ }
51
+ };
52
+ elements.forEach(element => {
53
+ if (recursion) {
54
+ depthFirstRecursion(element, node => calcRectangleClient(node));
55
+ }
56
+ else {
57
+ calcRectangleClient(element);
58
+ }
59
+ });
60
+ return {
61
+ x: boundaryBox.left,
62
+ y: boundaryBox.top,
63
+ width: boundaryBox.right - boundaryBox.left,
64
+ height: boundaryBox.bottom - boundaryBox.top
65
+ };
66
+ }
67
+ function getBoardRectangle(board) {
68
+ return getRectangleByElements(board, board.children, true);
69
+ }
70
+
71
+ const PlaitBoard = {
72
+ getHost(board) {
73
+ return BOARD_TO_HOST.get(board);
74
+ },
75
+ getElementHost(board) {
76
+ return BOARD_TO_ELEMENT_HOST.get(board);
77
+ },
78
+ getRoughSVG(board) {
79
+ return BOARD_TO_ROUGH_SVG.get(board);
80
+ },
81
+ getComponent(board) {
82
+ return BOARD_TO_COMPONENT.get(board);
83
+ },
84
+ getBoardNativeElement(board) {
85
+ return PlaitBoard.getComponent(board).nativeElement;
86
+ },
87
+ getRectangle(board) {
88
+ return getRectangleByElements(board, board.children, true);
89
+ },
90
+ getViewportContainer(board) {
91
+ return PlaitBoard.getHost(board).parentElement;
92
+ },
93
+ isFocus(board) {
94
+ return !!board.selection;
95
+ },
96
+ isReadonly(board) {
97
+ return board.options.readonly;
98
+ },
99
+ hasBeenTextEditing(board) {
100
+ return !!IS_TEXT_EDITABLE.get(board);
101
+ }
102
+ };
14
103
 
15
104
  var PlaitPointerType;
16
105
  (function (PlaitPointerType) {
@@ -21,10 +110,23 @@ var PlaitPointerType;
21
110
  function isNullOrUndefined(value) {
22
111
  return value === null || value === undefined;
23
112
  }
113
+ /**
114
+ * 规范 point
115
+ * @param point
116
+ * @returns point
117
+ */
118
+ function normalizePoint(point) {
119
+ return Array.isArray(point)
120
+ ? {
121
+ x: point[0],
122
+ y: point[1]
123
+ }
124
+ : point;
125
+ }
24
126
 
25
127
  const Viewport = {
26
128
  isViewport: (value) => {
27
- return (!isNullOrUndefined(value.zoom) && !isNullOrUndefined(value.viewBackgroundColor) && !isNullOrUndefined(value.originationCoord));
129
+ return !isNullOrUndefined(value.zoom) && !isNullOrUndefined(value.viewBackgroundColor);
28
130
  }
29
131
  };
30
132
 
@@ -356,19 +458,6 @@ const NodeTransforms = {
356
458
  moveNode
357
459
  };
358
460
 
359
- // record richtext type status
360
- const FLUSHING = new WeakMap();
361
- const IS_TEXT_EDITABLE = new WeakMap();
362
- const BOARD_TO_ON_CHANGE = new WeakMap();
363
- const BOARD_TO_COMPONENT = new WeakMap();
364
- const BOARD_TO_ROUGH_SVG = new WeakMap();
365
- const BOARD_TO_HOST = new WeakMap();
366
- const BOARD_TO_ELEMENT_HOST = new WeakMap();
367
- const BOARD_TO_SELECTED_ELEMENT = new WeakMap();
368
- const BOARD_TO_MOVING_POINT = new WeakMap();
369
- // save no standard selected elements
370
- const BOARD_TO_TEMPORARY_ELEMENTS = new WeakMap();
371
-
372
461
  function setSelection(board, selection) {
373
462
  const operation = { type: 'set_selection', properties: board.selection, newProperties: selection };
374
463
  board.apply(operation);
@@ -384,80 +473,61 @@ function setSelectionWithTemporaryElements(board, elements) {
384
473
  });
385
474
  }
386
475
 
387
- function setViewport(board, viewport) {
476
+ function setViewport$1(board, viewport) {
388
477
  const operation = { type: 'set_viewport', properties: board.viewport, newProperties: viewport };
389
478
  board.apply(operation);
390
479
  }
391
480
  const ViewportTransforms = {
392
- setViewport
481
+ setViewport: setViewport$1
393
482
  };
394
483
 
395
- function depthFirstRecursion(node, callback) {
396
- var _a;
397
- (_a = node.children) === null || _a === void 0 ? void 0 : _a.forEach(child => {
398
- depthFirstRecursion(child, callback);
399
- });
400
- callback(node);
484
+ // https://stackoverflow.com/a/6853926/232122
485
+ function distanceBetweenPointAndSegment(x, y, x1, y1, x2, y2) {
486
+ const A = x - x1;
487
+ const B = y - y1;
488
+ const C = x2 - x1;
489
+ const D = y2 - y1;
490
+ const dot = A * C + B * D;
491
+ const lenSquare = C * C + D * D;
492
+ let param = -1;
493
+ if (lenSquare !== 0) {
494
+ // in case of 0 length line
495
+ param = dot / lenSquare;
496
+ }
497
+ let xx, yy;
498
+ if (param < 0) {
499
+ xx = x1;
500
+ yy = y1;
501
+ }
502
+ else if (param > 1) {
503
+ xx = x2;
504
+ yy = y2;
505
+ }
506
+ else {
507
+ xx = x1 + param * C;
508
+ yy = y1 + param * D;
509
+ }
510
+ const dx = x - xx;
511
+ const dy = y - yy;
512
+ return Math.hypot(dx, dy);
401
513
  }
402
-
403
- function getRectangleByElements(board, elements, recursion) {
404
- const boundaryBox = {
405
- left: Number.MAX_VALUE,
406
- top: Number.MAX_VALUE,
407
- right: Number.MIN_VALUE,
408
- bottom: Number.MIN_VALUE
409
- };
410
- const calcRectangleClient = (node) => {
411
- const nodeRectangle = board.getRectangle(node);
412
- if (nodeRectangle) {
413
- boundaryBox.left = Math.min(boundaryBox.left, nodeRectangle.x);
414
- boundaryBox.top = Math.min(boundaryBox.top, nodeRectangle.y);
415
- boundaryBox.right = Math.max(boundaryBox.right, nodeRectangle.x + nodeRectangle.width);
416
- boundaryBox.bottom = Math.max(boundaryBox.bottom, nodeRectangle.y + nodeRectangle.height);
417
- }
418
- };
419
- elements.forEach(element => {
420
- if (recursion) {
421
- depthFirstRecursion(element, node => calcRectangleClient(node));
422
- }
423
- else {
424
- calcRectangleClient(element);
425
- }
426
- });
427
- return {
428
- x: boundaryBox.left,
429
- y: boundaryBox.top,
430
- width: boundaryBox.right - boundaryBox.left,
431
- height: boundaryBox.bottom - boundaryBox.top
432
- };
514
+ function rotate(x1, y1, x2, y2, angle) {
515
+ // 𝑎′𝑥=(𝑎𝑥−𝑐𝑥)cos𝜃−(𝑎𝑦−𝑐𝑦)sin𝜃+𝑐𝑥
516
+ // 𝑎′𝑦=(𝑎𝑥−𝑐𝑥)sin𝜃+(𝑎𝑦−𝑐𝑦)cos𝜃+𝑐𝑦.
517
+ // https://math.stackexchange.com/questions/2204520/how-do-i-rotate-a-line-segment-in-a-specific-point-on-the-line
518
+ return [(x1 - x2) * Math.cos(angle) - (y1 - y2) * Math.sin(angle) + x2, (x1 - x2) * Math.sin(angle) + (y1 - y2) * Math.cos(angle) + y2];
433
519
  }
434
- function getBoardRectangle(board) {
435
- return getRectangleByElements(board, board.children, true);
520
+ function distanceBetweenPointAndPoint(x1, y1, x2, y2) {
521
+ const dx = x1 - x2;
522
+ const dy = y1 - y2;
523
+ return Math.hypot(dx, dy);
524
+ }
525
+ // https://stackoverflow.com/questions/5254838/calculating-distance-between-a-point-and-a-rectangular-box-nearest-point
526
+ function distanceBetweenPointAndRectangle(x, y, rect) {
527
+ var dx = Math.max(rect.x - x, 0, x - (rect.x + rect.width));
528
+ var dy = Math.max(rect.y - y, 0, y - (rect.y + rect.height));
529
+ return Math.sqrt(dx * dx + dy * dy);
436
530
  }
437
-
438
- const PlaitBoard = {
439
- getHost(board) {
440
- return BOARD_TO_HOST.get(board);
441
- },
442
- getElementHost(board) {
443
- return BOARD_TO_ELEMENT_HOST.get(board);
444
- },
445
- getRoughSVG(board) {
446
- return BOARD_TO_ROUGH_SVG.get(board);
447
- },
448
- getComponent(board) {
449
- return BOARD_TO_COMPONENT.get(board);
450
- },
451
- getBoardNativeElement(board) {
452
- return PlaitBoard.getComponent(board).nativeElement;
453
- },
454
- getRectangle(board) {
455
- return getRectangleByElements(board, board.children, true);
456
- },
457
- getViewportContainer(board) {
458
- return PlaitBoard.getHost(board).parentElement;
459
- }
460
- };
461
531
 
462
532
  function transformPoints(board, points) {
463
533
  const newPoints = points.map(point => {
@@ -473,9 +543,11 @@ function transformPoint(board, point) {
473
543
  const newPoint = [x, y];
474
544
  return newPoint;
475
545
  }
476
- function isNoSelectionElement(e) {
477
- var _a;
478
- return (_a = e.target) === null || _a === void 0 ? void 0 : _a.closest('.plait-board-attached');
546
+ function isInPlaitBoard(board, x, y) {
547
+ const plaitBoardElement = PlaitBoard.getBoardNativeElement(board);
548
+ const plaitBoardRect = plaitBoardElement.getBoundingClientRect();
549
+ const distances = distanceBetweenPointAndRectangle(x, y, plaitBoardRect);
550
+ return distances === 0;
479
551
  }
480
552
 
481
553
  const NS = 'http://www.w3.org/2000/svg';
@@ -612,6 +684,12 @@ const PlaitOperation = {
612
684
  inverse
613
685
  };
614
686
 
687
+ const Point = {
688
+ isEquals(point, otherPoint) {
689
+ return point && otherPoint && point[0] === otherPoint[0] && point[1] === otherPoint[1];
690
+ }
691
+ };
692
+
615
693
  const SELECTION_BORDER_COLOR = '#6698FF';
616
694
  const SELECTION_FILL_COLOR = '#6698FF19'; // 主色 0.1 透明度
617
695
  const Selection = {
@@ -775,241 +853,25 @@ const hotkeys = {
775
853
  isExtendLineBackward: create('extendLineBackward'),
776
854
  isExtendLineForward: create('extendLineForward'),
777
855
  isItalic: create('italic'),
778
- isMoveLineBackward: create('moveLineBackward'),
779
- isMoveLineForward: create('moveLineForward'),
780
- isMoveWordBackward: create('moveWordBackward'),
781
- isMoveWordForward: create('moveWordForward'),
782
- isRedo: create('redo'),
783
- isSplitBlock: create('splitBlock'),
784
- isTransposeCharacter: create('transposeCharacter'),
785
- isUndo: create('undo')
786
- };
787
-
788
- function idCreator(length = 5) {
789
- // remove numeral
790
- const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
791
- const maxPosition = $chars.length;
792
- let key = '';
793
- for (let i = 0; i < length; i++) {
794
- key += $chars.charAt(Math.floor(Math.random() * maxPosition));
795
- }
796
- return key;
797
- }
798
-
799
- // https://stackoverflow.com/a/6853926/232122
800
- function distanceBetweenPointAndSegment(x, y, x1, y1, x2, y2) {
801
- const A = x - x1;
802
- const B = y - y1;
803
- const C = x2 - x1;
804
- const D = y2 - y1;
805
- const dot = A * C + B * D;
806
- const lenSquare = C * C + D * D;
807
- let param = -1;
808
- if (lenSquare !== 0) {
809
- // in case of 0 length line
810
- param = dot / lenSquare;
811
- }
812
- let xx, yy;
813
- if (param < 0) {
814
- xx = x1;
815
- yy = y1;
816
- }
817
- else if (param > 1) {
818
- xx = x2;
819
- yy = y2;
820
- }
821
- else {
822
- xx = x1 + param * C;
823
- yy = y1 + param * D;
824
- }
825
- const dx = x - xx;
826
- const dy = y - yy;
827
- return Math.hypot(dx, dy);
828
- }
829
- function rotate(x1, y1, x2, y2, angle) {
830
- // 𝑎′𝑥=(𝑎𝑥−𝑐𝑥)cos𝜃−(𝑎𝑦−𝑐𝑦)sin𝜃+𝑐𝑥
831
- // 𝑎′𝑦=(𝑎𝑥−𝑐𝑥)sin𝜃+(𝑎𝑦−𝑐𝑦)cos𝜃+𝑐𝑦.
832
- // https://math.stackexchange.com/questions/2204520/how-do-i-rotate-a-line-segment-in-a-specific-point-on-the-line
833
- return [(x1 - x2) * Math.cos(angle) - (y1 - y2) * Math.sin(angle) + x2, (x1 - x2) * Math.sin(angle) + (y1 - y2) * Math.cos(angle) + y2];
834
- }
835
- function distanceBetweenPointAndPoint(x1, y1, x2, y2) {
836
- const dx = x1 - x2;
837
- const dy = y1 - y2;
838
- return Math.hypot(dx, dy);
839
- }
840
- // https://stackoverflow.com/questions/5254838/calculating-distance-between-a-point-and-a-rectangular-box-nearest-point
841
- function distanceBetweenPointAndRectangle(x, y, rect) {
842
- var dx = Math.max(rect.x - x, 0, x - (rect.x + rect.width));
843
- var dy = Math.max(rect.y - y, 0, y - (rect.y + rect.height));
844
- return Math.sqrt(dx * dx + dy * dy);
845
- }
846
-
847
- /**
848
- * 逆矩阵
849
- * [a c e]
850
- * [b d f]
851
- * [0 0 1]
852
- * @param newMatrix 输出返回矩阵
853
- * @param matrix 新矩阵
854
- * @returns 逆矩阵
855
- */
856
- function invertMatrix(newMatrix, matrix) {
857
- const [n, r, a, i, o, c, l, s, u] = matrix;
858
- const determinant = u * o - c * s;
859
- const h = -u * i + c * l;
860
- const f = s * i - o * l;
861
- const product = n * determinant + r * h + a * f;
862
- if (!product) {
863
- return null;
864
- }
865
- const reciprocal = 1 / product;
866
- newMatrix[0] = determinant * reciprocal;
867
- newMatrix[1] = (-u * r + a * s) * reciprocal;
868
- newMatrix[2] = (c * r - a * o) * reciprocal;
869
- newMatrix[3] = h * reciprocal;
870
- newMatrix[4] = (u * n - a * l) * reciprocal;
871
- newMatrix[5] = (-c * n + a * i) * reciprocal;
872
- newMatrix[6] = f * reciprocal;
873
- newMatrix[7] = (-s * n + r * l) * reciprocal;
874
- newMatrix[8] = (o * n - r * i) * reciprocal;
875
- return newMatrix;
876
- }
877
- /**
878
- * 将视图坐标与反转矩阵相乘,以得到原始坐标
879
- * 使用给定的矩阵进行转换
880
- * 矩阵与向量乘法,3 维向量与3x3矩阵的乘积
881
- * [m11 m12 m13][v1]
882
- * [m21 m22 m23][v2]
883
- * [m31 m32 m33][v3]
884
- * @param out 输出结果向量
885
- * @param t 要转换的向量
886
- * @param n 矩阵转换
887
- * @returns [v1 * m11 + v2 * m12 + v3 * m13, v1 * m21 + v2 * m22 + v3 * m23, v1 * m31 + v2 * m32 + v3 * m33];
888
- */
889
- function transformMat3(out, vector, matrix) {
890
- out = [
891
- vector[0] * matrix[0] + vector[1] * matrix[3] + vector[2] * matrix[6],
892
- vector[0] * matrix[1] + vector[1] * matrix[4] + vector[2] * matrix[7],
893
- vector[0] * matrix[2] + vector[1] * matrix[5] + vector[2] * matrix[8]
894
- ];
895
- return out;
896
- }
897
- /**
898
- * 规范 point
899
- * @param point
900
- * @returns point
901
- */
902
- function normalizePoint(point) {
903
- return Array.isArray(point)
904
- ? {
905
- x: point[0],
906
- y: point[1]
907
- }
908
- : point;
909
- }
910
- /**
911
- * 将一个点坐标反转回它的原始坐标
912
- * @param point 表示要反转的点的视图坐标,它是一个长度为 2 的数组,存储点的 x 和 y 坐标
913
- * @param matrix 表示视图矩阵,是在视图中对图形进行缩放和平移时使用的矩阵
914
- * @returns 最终结果是一个长度为 3 的数组,存储点的 x,y 和 w 坐标(w 坐标是点的齐次坐标)
915
- */
916
- function invertViewportCoordinates(point, matrix) {
917
- const { x, y } = normalizePoint(point);
918
- const invertedMatrix = invertMatrix([], matrix);
919
- return transformMat3([], [x, y, 1], invertedMatrix);
920
- }
921
- function convertToViewportCoordinates(point, matrix) {
922
- const { x, y } = normalizePoint(point);
923
- return transformMat3([], [x, y, 1], matrix);
924
- }
925
- /**
926
- * 获取 contentContainer 的 clientBox
927
- * @param board
928
- * @returns
929
- */
930
- function getViewportContainerBox(board) {
931
- const { hideScrollbar } = board.options;
932
- const scrollBarWidth = hideScrollbar ? SCROLL_BAR_WIDTH : 0;
933
- const container = PlaitBoard.getViewportContainer(board);
934
- const containerRect = container.getBoundingClientRect();
935
- const x = containerRect.x || containerRect.left;
936
- const y = containerRect.y || containerRect.top;
937
- const width = containerRect.width - scrollBarWidth;
938
- const height = containerRect.height - scrollBarWidth;
939
- return {
940
- minX: x,
941
- minY: y,
942
- maxX: x + width,
943
- maxY: y + height,
944
- x,
945
- y,
946
- width,
947
- height
948
- };
949
- }
950
- /**
951
- * 获取 board.plait-board 的 clientBox
952
- * @param board
953
- * @returns
954
- */
955
- function getBoardClientBox(board) {
956
- const { hideScrollbar } = board.options;
957
- const scrollBarWidth = hideScrollbar ? SCROLL_BAR_WIDTH : 0;
958
- const viewportRect = PlaitBoard.getViewportContainer(board).getBoundingClientRect();
959
- return {
960
- width: viewportRect.width + scrollBarWidth,
961
- height: viewportRect.height + scrollBarWidth
962
- };
963
- }
964
- /**
965
- * 获取 rootGroup 相对于当前 svg 空间的最小矩阵坐标
966
- */
967
- function getRootGroupBBox(board, zoom) {
968
- const elementHost = PlaitBoard.getElementHost(board);
969
- const rootGroupBox = elementHost.getBBox();
970
- const viewportContainerBox = getViewportContainerBox(board);
971
- const containerWidth = viewportContainerBox.width / zoom;
972
- const containerHeight = viewportContainerBox.height / zoom;
973
- let left;
974
- let right;
975
- let top;
976
- let bottom;
977
- if (rootGroupBox.width < containerWidth) {
978
- const offsetX = rootGroupBox.x + rootGroupBox.width / 2;
979
- const containerX = containerWidth / 2;
980
- left = offsetX - containerX;
981
- right = offsetX + containerX;
982
- }
983
- else {
984
- left = rootGroupBox.x;
985
- right = rootGroupBox.x + rootGroupBox.width;
986
- }
987
- if (rootGroupBox.height < containerHeight) {
988
- const offsetY = rootGroupBox.y + rootGroupBox.height / 2;
989
- const containerY = containerHeight / 2;
990
- top = offsetY - containerY;
991
- bottom = offsetY + containerY;
992
- }
993
- else {
994
- top = rootGroupBox.y;
995
- bottom = rootGroupBox.y + rootGroupBox.height;
856
+ isMoveLineBackward: create('moveLineBackward'),
857
+ isMoveLineForward: create('moveLineForward'),
858
+ isMoveWordBackward: create('moveWordBackward'),
859
+ isMoveWordForward: create('moveWordForward'),
860
+ isRedo: create('redo'),
861
+ isSplitBlock: create('splitBlock'),
862
+ isTransposeCharacter: create('transposeCharacter'),
863
+ isUndo: create('undo')
864
+ };
865
+
866
+ function idCreator(length = 5) {
867
+ // remove numeral
868
+ const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
869
+ const maxPosition = $chars.length;
870
+ let key = '';
871
+ for (let i = 0; i < length; i++) {
872
+ key += $chars.charAt(Math.floor(Math.random() * maxPosition));
996
873
  }
997
- return {
998
- left,
999
- right,
1000
- top,
1001
- bottom
1002
- };
1003
- }
1004
- /**
1005
- * 验证缩放比是否符合限制,如果超出限制,则返回合适的缩放比
1006
- * @param zoom 缩放比
1007
- * @param minZoom 最小缩放比
1008
- * @param maxZoom 最大缩放比
1009
- * @returns 正确的缩放比
1010
- */
1011
- function clampZoomLevel(zoom, minZoom = 0.2, maxZoom = 4) {
1012
- return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
874
+ return key;
1013
875
  }
1014
876
 
1015
877
  const calcElementIntersectionSelection = (board) => {
@@ -1025,6 +887,19 @@ const calcElementIntersectionSelection = (board) => {
1025
887
  });
1026
888
  return selectedElements;
1027
889
  };
890
+ const isIntersectionElements = (board, elements, ranges) => {
891
+ let isIntersectionElements = false;
892
+ if (elements.length) {
893
+ elements.map(item => {
894
+ if (!isIntersectionElements) {
895
+ isIntersectionElements = ranges.some(range => {
896
+ return board.isIntersectionSelection(item, range);
897
+ });
898
+ }
899
+ });
900
+ }
901
+ return isIntersectionElements;
902
+ };
1028
903
  const cacheSelectedElements = (board, selectedElements) => {
1029
904
  BOARD_TO_SELECTED_ELEMENT.set(board, selectedElements);
1030
905
  };
@@ -1045,6 +920,10 @@ const isSelectedElement = (board, element) => {
1045
920
  return !!selectedElements.find(value => value === element);
1046
921
  };
1047
922
 
923
+ const CLIP_BOARD_FORMAT_KEY = 'x-plait-fragment';
924
+ const SCROLL_BAR_WIDTH = 20;
925
+ const MAX_RADIUS = 16;
926
+
1048
927
  /**
1049
928
  * drawRoundRectangle
1050
929
  * @param rs RoughSVG
@@ -1097,6 +976,233 @@ function drawArrow(rs, start, end, options, maxHypotenuseLength = 10, degree = 4
1097
976
  return [arrowLineLeft, arrowLineRight];
1098
977
  }
1099
978
 
979
+ function getViewportContainerRect(board) {
980
+ const { hideScrollbar } = board.options;
981
+ const scrollBarWidth = hideScrollbar ? SCROLL_BAR_WIDTH : 0;
982
+ const viewportRect = PlaitBoard.getBoardNativeElement(board).getBoundingClientRect();
983
+ return {
984
+ width: viewportRect.width + scrollBarWidth,
985
+ height: viewportRect.height + scrollBarWidth
986
+ };
987
+ }
988
+ function getElementHostBBox(board, zoom) {
989
+ const childrenRect = getRectangleByElements(board, board.children, true);
990
+ const viewportContainerRect = getViewportContainerRect(board);
991
+ const containerWidth = viewportContainerRect.width / zoom;
992
+ const containerHeight = viewportContainerRect.height / zoom;
993
+ let left;
994
+ let right;
995
+ let top;
996
+ let bottom;
997
+ if (childrenRect.width < containerWidth) {
998
+ const centerX = childrenRect.x + childrenRect.width / 2;
999
+ const halfContainerWidth = containerWidth / 2;
1000
+ left = centerX - halfContainerWidth;
1001
+ right = centerX + halfContainerWidth;
1002
+ }
1003
+ else {
1004
+ left = childrenRect.x;
1005
+ right = childrenRect.x + childrenRect.width;
1006
+ }
1007
+ if (childrenRect.height < containerHeight) {
1008
+ const centerY = childrenRect.y + childrenRect.height / 2;
1009
+ const halfContainerHeight = containerHeight / 2;
1010
+ top = centerY - halfContainerHeight;
1011
+ bottom = centerY + halfContainerHeight;
1012
+ }
1013
+ else {
1014
+ top = childrenRect.y;
1015
+ bottom = childrenRect.y + childrenRect.height;
1016
+ }
1017
+ return {
1018
+ left,
1019
+ right,
1020
+ top,
1021
+ bottom
1022
+ };
1023
+ }
1024
+ /**
1025
+ * 验证缩放比是否符合限制,如果超出限制,则返回合适的缩放比
1026
+ * @param zoom 缩放比
1027
+ * @param minZoom 最小缩放比
1028
+ * @param maxZoom 最大缩放比
1029
+ * @returns 正确的缩放比
1030
+ */
1031
+ function clampZoomLevel(zoom, minZoom = 0.2, maxZoom = 4) {
1032
+ return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
1033
+ }
1034
+ function getViewBox(board, zoom) {
1035
+ const { hideScrollbar } = board.options;
1036
+ const scrollBarWidth = hideScrollbar ? SCROLL_BAR_WIDTH : 0;
1037
+ const viewportContainerRect = getViewportContainerRect(board);
1038
+ const elementHostBBox = getElementHostBBox(board, zoom);
1039
+ const horizontalPadding = viewportContainerRect.width / 2;
1040
+ const verticalPadding = viewportContainerRect.height / 2;
1041
+ const viewportWidth = (elementHostBBox.right - elementHostBBox.left) * zoom + 2 * horizontalPadding + scrollBarWidth;
1042
+ const viewportHeight = (elementHostBBox.bottom - elementHostBBox.top) * zoom + 2 * verticalPadding + scrollBarWidth;
1043
+ const viewBox = [
1044
+ elementHostBBox.left - horizontalPadding / zoom,
1045
+ elementHostBBox.top - verticalPadding / zoom,
1046
+ viewportWidth / zoom,
1047
+ viewportHeight / zoom
1048
+ ];
1049
+ return viewBox;
1050
+ }
1051
+ function setSVGViewBox(board, viewBox) {
1052
+ const zoom = board.viewport.zoom;
1053
+ const hostElement = PlaitBoard.getHost(board);
1054
+ hostElement.style.display = 'block';
1055
+ hostElement.style.width = `${viewBox[2] * zoom}px`;
1056
+ hostElement.style.height = `${viewBox[3] * zoom}px`;
1057
+ if (viewBox && viewBox[2] > 0 && viewBox[3] > 0) {
1058
+ hostElement.setAttribute('viewBox', viewBox.join(' '));
1059
+ }
1060
+ }
1061
+ function updateViewportOffset(board) {
1062
+ const origination = getViewportOrigination(board);
1063
+ if (!origination)
1064
+ return;
1065
+ const { zoom } = board.viewport;
1066
+ const viewBox = getViewBox(board, zoom);
1067
+ const scrollLeft = (origination[0] - viewBox[0]) * zoom;
1068
+ const scrollTop = (origination[1] - viewBox[1]) * zoom;
1069
+ updateViewportContainerScroll(board, scrollLeft, scrollTop);
1070
+ }
1071
+ function updateViewportContainerScroll(board, left, top) {
1072
+ const viewportContainer = PlaitBoard.getViewportContainer(board);
1073
+ if (viewportContainer.scrollLeft !== left || viewportContainer.scrollTop !== top) {
1074
+ viewportContainer.scrollLeft = left;
1075
+ viewportContainer.scrollTop = top;
1076
+ setViewportScrolling(board);
1077
+ }
1078
+ }
1079
+ function initializeViewportContainer(board) {
1080
+ const { width, height } = getViewportContainerRect(board);
1081
+ const viewportContainer = PlaitBoard.getViewportContainer(board);
1082
+ viewportContainer.style.width = `${width}px`;
1083
+ viewportContainer.style.height = `${height}px`;
1084
+ }
1085
+ function initializeViewBox(board) {
1086
+ const zoom = board.viewport.zoom;
1087
+ const viewBox = getViewBox(board, zoom);
1088
+ setSVGViewBox(board, viewBox);
1089
+ }
1090
+ function initializeViewportOffset(board) {
1091
+ var _a;
1092
+ if (!((_a = board.viewport) === null || _a === void 0 ? void 0 : _a.origination)) {
1093
+ const zoom = board.viewport.zoom;
1094
+ const viewportContainerRect = PlaitBoard.getBoardNativeElement(board).getBoundingClientRect();
1095
+ const viewBox = getViewBox(board, zoom);
1096
+ const centerX = viewBox[0] + viewBox[2] / 2;
1097
+ const centerY = viewBox[1] + viewBox[3] / 2;
1098
+ const origination = [centerX - viewportContainerRect.width / 2 / zoom, centerY - viewportContainerRect.height / 2 / zoom];
1099
+ updateViewportOrigination(board, origination);
1100
+ updateViewportOffset(board);
1101
+ return;
1102
+ }
1103
+ updateViewportOffset(board);
1104
+ }
1105
+ function setViewport(board, origination, zoom) {
1106
+ zoom = zoom !== null && zoom !== void 0 ? zoom : board.viewport.zoom;
1107
+ Transforms.setViewport(board, Object.assign(Object.assign({}, board.viewport), { zoom,
1108
+ origination }));
1109
+ clearViewportOrigination(board);
1110
+ }
1111
+ function changeZoom(board, newZoom, isCenter = true) {
1112
+ newZoom = clampZoomLevel(newZoom);
1113
+ const mousePoint = BOARD_TO_MOVING_POINT.get(board);
1114
+ const nativeElement = PlaitBoard.getBoardNativeElement(board);
1115
+ const rect = nativeElement.getBoundingClientRect();
1116
+ const viewportContainerRect = getViewportContainerRect(board);
1117
+ let focusPoint = [viewportContainerRect.width / 2, viewportContainerRect.height / 2];
1118
+ if (!isCenter && mousePoint && distanceBetweenPointAndRectangle(mousePoint[0], mousePoint[1], rect) === 0) {
1119
+ focusPoint = toPoint(mousePoint[0], mousePoint[1], nativeElement);
1120
+ }
1121
+ const zoom = board.viewport.zoom;
1122
+ const origination = getViewportOrigination(board);
1123
+ const centerX = origination[0] + focusPoint[0] / zoom;
1124
+ const centerY = origination[1] + focusPoint[1] / zoom;
1125
+ const newOrigination = [centerX - focusPoint[0] / newZoom, centerY - focusPoint[1] / newZoom];
1126
+ setViewport(board, newOrigination, newZoom);
1127
+ }
1128
+ function fitViewport(board) {
1129
+ const viewportContainerRect = getViewportContainerRect(board);
1130
+ const elementHostBox = getRectangleByElements(board, board.children, true);
1131
+ const zoom = board.viewport.zoom;
1132
+ const autoFitPadding = 8;
1133
+ const viewportWidth = viewportContainerRect.width - 2 * autoFitPadding;
1134
+ const viewportHeight = viewportContainerRect.height - 2 * autoFitPadding;
1135
+ let newZoom = zoom;
1136
+ if (viewportWidth < elementHostBox.width || viewportHeight < elementHostBox.height) {
1137
+ newZoom = Math.min(viewportWidth / elementHostBox.width, viewportHeight / elementHostBox.height);
1138
+ }
1139
+ else {
1140
+ newZoom = 1;
1141
+ }
1142
+ const viewBox = getViewBox(board, newZoom);
1143
+ const centerX = viewBox[0] + viewBox[2] / 2;
1144
+ const centerY = viewBox[1] + viewBox[3] / 2;
1145
+ const newOrigination = [
1146
+ centerX - viewportContainerRect.width / 2 / newZoom,
1147
+ centerY - viewportContainerRect.height / 2 / newZoom
1148
+ ];
1149
+ setViewport(board, newOrigination, newZoom);
1150
+ }
1151
+ const updateViewportOrigination = (board, origination) => {
1152
+ BOARD_TO_VIEWPORT_ORIGINATION.set(board, origination);
1153
+ };
1154
+ const clearViewportOrigination = (board) => {
1155
+ BOARD_TO_VIEWPORT_ORIGINATION.delete(board);
1156
+ };
1157
+ const getViewportOrigination = (board) => {
1158
+ const origination = BOARD_TO_VIEWPORT_ORIGINATION.get(board);
1159
+ if (origination) {
1160
+ return origination;
1161
+ }
1162
+ else {
1163
+ return board.viewport.origination;
1164
+ }
1165
+ };
1166
+ const isViewportScrolling = (board) => {
1167
+ return !!BOARD_TO_SCROLLING.get(board);
1168
+ };
1169
+ const setViewportScrolling = (board) => {
1170
+ BOARD_TO_SCROLLING.set(board, true);
1171
+ };
1172
+ const clearViewportScrolling = (board) => {
1173
+ BOARD_TO_SCROLLING.delete(board);
1174
+ };
1175
+ function scrollToRectangle(board, client) { }
1176
+
1177
+ let timerId = null;
1178
+ const throttleRAF = (fn) => {
1179
+ const scheduleFunc = () => {
1180
+ timerId = requestAnimationFrame(() => {
1181
+ timerId = null;
1182
+ fn();
1183
+ });
1184
+ };
1185
+ if (timerId !== null) {
1186
+ cancelAnimationFrame(timerId);
1187
+ timerId = null;
1188
+ }
1189
+ scheduleFunc();
1190
+ };
1191
+
1192
+ const getMovingElements = (board) => {
1193
+ return BOARD_TO_MOVING_ELEMENT.get(board) || [];
1194
+ };
1195
+ const addMovingElements = (board, elements) => {
1196
+ const movingElements = getMovingElements(board);
1197
+ cacheMovingElements(board, [...movingElements, ...elements]);
1198
+ };
1199
+ const removeMovingElements = (board) => {
1200
+ BOARD_TO_MOVING_ELEMENT.delete(board);
1201
+ };
1202
+ const cacheMovingElements = (board, elements) => {
1203
+ BOARD_TO_MOVING_ELEMENT.set(board, elements);
1204
+ };
1205
+
1100
1206
  const updatePointerType = (board, pointer) => {
1101
1207
  board.pointer = pointer;
1102
1208
  const boardComponent = BOARD_TO_COMPONENT.get(board);
@@ -1157,6 +1263,7 @@ function createBoard(children, options) {
1157
1263
  destroyElement: (context) => { },
1158
1264
  isWithinSelection: element => false,
1159
1265
  isIntersectionSelection: element => false,
1266
+ isMovable: element => false,
1160
1267
  getRectangle: element => null
1161
1268
  };
1162
1269
  return board;
@@ -1282,11 +1389,10 @@ function withHandPointer(board) {
1282
1389
  };
1283
1390
  board.mousemove = (event) => {
1284
1391
  if (board.pointer === PlaitPointerType.hand && board.selection && isMoving) {
1285
- const boardComponent = PlaitBoard.getComponent(board);
1286
- const left = event.x - plaitBoardMove.x;
1287
- const top = event.y - plaitBoardMove.y;
1288
- const { scrollLeft, scrollTop } = boardComponent.viewportState;
1289
- boardComponent.setScroll(scrollLeft - left, scrollTop - top);
1392
+ const viewportContainer = PlaitBoard.getViewportContainer(board);
1393
+ const left = viewportContainer.scrollLeft - (event.x - plaitBoardMove.x);
1394
+ const top = viewportContainer.scrollTop - (event.y - plaitBoardMove.y);
1395
+ updateViewportContainerScroll(board, left, top);
1290
1396
  plaitBoardMove.x = event.x;
1291
1397
  plaitBoardMove.y = event.y;
1292
1398
  }
@@ -1319,6 +1425,8 @@ function withHandPointer(board) {
1319
1425
  return board;
1320
1426
  }
1321
1427
 
1428
+ const ATTACHED_ELEMENT_CLASS_NAME = 'plait-board-attached';
1429
+
1322
1430
  function withSelection(board) {
1323
1431
  const { mousedown, globalMousemove, globalMouseup, onChange } = board;
1324
1432
  let start = null;
@@ -1326,12 +1434,26 @@ function withSelection(board) {
1326
1434
  let selectionMovingG;
1327
1435
  let selectionOuterG;
1328
1436
  board.mousedown = (event) => {
1329
- selectionOuterG === null || selectionOuterG === void 0 ? void 0 : selectionOuterG.remove();
1437
+ if (board.pointer === PlaitPointerType.hand && board.selection) {
1438
+ mousedown(event);
1439
+ return;
1440
+ }
1330
1441
  if (event.button === 0) {
1331
1442
  start = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1332
1443
  }
1333
1444
  if (start) {
1334
- Transforms.setSelection(board, { ranges: [{ anchor: start, focus: start }] });
1445
+ const ranges = [{ anchor: start, focus: start }];
1446
+ const selectedElements = getSelectedElements(board);
1447
+ const intersectionSelectedElement = isIntersectionElements(board, selectedElements, ranges);
1448
+ if (intersectionSelectedElement) {
1449
+ start = null;
1450
+ }
1451
+ else {
1452
+ Transforms.setSelection(board, { ranges: ranges });
1453
+ if (calcElementIntersectionSelection(board).length) {
1454
+ start = null;
1455
+ }
1456
+ }
1335
1457
  }
1336
1458
  mousedown(event);
1337
1459
  };
@@ -1339,13 +1461,11 @@ function withSelection(board) {
1339
1461
  if (start) {
1340
1462
  const movedTarget = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1341
1463
  const { x, y, width, height } = RectangleClient.toRectangleClient([start, movedTarget]);
1464
+ selectionMovingG === null || selectionMovingG === void 0 ? void 0 : selectionMovingG.remove();
1342
1465
  if (Math.hypot(width, height) > 5) {
1343
1466
  end = movedTarget;
1344
- if (end) {
1345
- Transforms.setSelection(board, { ranges: [{ anchor: start, focus: end }] });
1346
- }
1347
- PlaitBoard.getBoardNativeElement(board).classList.add('selection-moving');
1348
- selectionMovingG === null || selectionMovingG === void 0 ? void 0 : selectionMovingG.remove();
1467
+ Transforms.setSelection(board, { ranges: [{ anchor: start, focus: end }] });
1468
+ setSelectionMoving(board);
1349
1469
  const rough = PlaitBoard.getRoughSVG(board);
1350
1470
  selectionMovingG = rough.rectangle(x, y, width, height, {
1351
1471
  stroke: SELECTION_BORDER_COLOR,
@@ -1360,8 +1480,18 @@ function withSelection(board) {
1360
1480
  };
1361
1481
  board.globalMouseup = (event) => {
1362
1482
  if (start && end) {
1363
- PlaitBoard.getBoardNativeElement(board).classList.remove('selection-moving');
1364
1483
  selectionMovingG === null || selectionMovingG === void 0 ? void 0 : selectionMovingG.remove();
1484
+ clearSelectionMoving(board);
1485
+ Transforms.setSelection(board, { ranges: [{ anchor: start, focus: end }] });
1486
+ }
1487
+ if (PlaitBoard.isFocus(board)) {
1488
+ const isInBoard = event.target instanceof Node && PlaitBoard.getBoardNativeElement(board).contains(event.target);
1489
+ const isAttachedElement = event.target instanceof HTMLElement && event.target.closest(`.${ATTACHED_ELEMENT_CLASS_NAME}`);
1490
+ // Clear selection when mouse board outside area
1491
+ // The framework needs to determine whether the board is focused through selection
1492
+ if (!isInBoard && !start && !isAttachedElement) {
1493
+ Transforms.setSelection(board, null);
1494
+ }
1365
1495
  }
1366
1496
  start = null;
1367
1497
  end = null;
@@ -1370,6 +1500,7 @@ function withSelection(board) {
1370
1500
  board.onChange = () => {
1371
1501
  // calc selected elements entry
1372
1502
  try {
1503
+ selectionOuterG === null || selectionOuterG === void 0 ? void 0 : selectionOuterG.remove();
1373
1504
  if (board.operations.find(value => value.type === 'set_selection')) {
1374
1505
  const temporaryElements = getTemporaryElements(board);
1375
1506
  const elements = temporaryElements ? temporaryElements : calcElementIntersectionSelection(board);
@@ -1377,12 +1508,12 @@ function withSelection(board) {
1377
1508
  const { x, y, width, height } = getRectangleByElements(board, elements, false);
1378
1509
  if (width > 0 && height > 0) {
1379
1510
  const rough = PlaitBoard.getRoughSVG(board);
1380
- selectionOuterG === null || selectionOuterG === void 0 ? void 0 : selectionOuterG.remove();
1381
1511
  selectionOuterG = rough.rectangle(x - 2, y - 2, width + 4, height + 4, {
1382
1512
  stroke: SELECTION_BORDER_COLOR,
1383
1513
  strokeWidth: 1,
1384
1514
  fillStyle: 'solid'
1385
1515
  });
1516
+ selectionOuterG.classList.add('selection-outer');
1386
1517
  PlaitBoard.getHost(board).append(selectionOuterG);
1387
1518
  }
1388
1519
  }
@@ -1401,6 +1532,44 @@ function getTemporaryElements(board) {
1401
1532
  function deleteTemporaryElements(board) {
1402
1533
  BOARD_TO_TEMPORARY_ELEMENTS.delete(board);
1403
1534
  }
1535
+ function isSelectionMoving(board) {
1536
+ return !!BOARD_TO_IS_SELECTION_MOVING.get(board);
1537
+ }
1538
+ function setSelectionMoving(board) {
1539
+ PlaitBoard.getBoardNativeElement(board).classList.add('selection-moving');
1540
+ BOARD_TO_IS_SELECTION_MOVING.set(board, true);
1541
+ }
1542
+ function clearSelectionMoving(board) {
1543
+ PlaitBoard.getBoardNativeElement(board).classList.remove('selection-moving');
1544
+ BOARD_TO_IS_SELECTION_MOVING.delete(board);
1545
+ }
1546
+
1547
+ function withViewport(board) {
1548
+ const { onChange } = board;
1549
+ let timerSubscription;
1550
+ board.onChange = () => {
1551
+ const isSetViewport = board.operations.some(op => op.type === 'set_viewport');
1552
+ const isOnlySetSelection = board.operations.some(op => op.type === 'set_selection');
1553
+ if (isOnlySetSelection) {
1554
+ return onChange();
1555
+ }
1556
+ if (isSetViewport) {
1557
+ initializeViewBox(board);
1558
+ updateViewportOffset(board);
1559
+ }
1560
+ else {
1561
+ if (timerSubscription) {
1562
+ timerSubscription.unsubscribe();
1563
+ }
1564
+ timerSubscription = timer(500).subscribe(() => {
1565
+ initializeViewBox(board);
1566
+ updateViewportOffset(board);
1567
+ });
1568
+ }
1569
+ onChange();
1570
+ };
1571
+ return board;
1572
+ }
1404
1573
 
1405
1574
  class PlaitElementComponent {
1406
1575
  constructor(renderer2, viewContainerRef) {
@@ -1454,7 +1623,7 @@ class PlaitElementComponent {
1454
1623
  const current = {
1455
1624
  element: this.element,
1456
1625
  selection: this.selection,
1457
- board: this.board,
1626
+ board: this.board
1458
1627
  };
1459
1628
  if (this.context) {
1460
1629
  const previous = Object.assign({}, this.context);
@@ -1470,9 +1639,9 @@ class PlaitElementComponent {
1470
1639
  this.board.destroyElement(this.getContext().current);
1471
1640
  }
1472
1641
  }
1473
- PlaitElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitElementComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
1474
- PlaitElementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: PlaitElementComponent, selector: "plait-element", inputs: { index: "index", element: "element", board: "board", viewport: "viewport", selection: "selection" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1475
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitElementComponent, decorators: [{
1642
+ PlaitElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitElementComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
1643
+ PlaitElementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: PlaitElementComponent, selector: "plait-element", inputs: { index: "index", element: "element", board: "board", viewport: "viewport", selection: "selection" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1644
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitElementComponent, decorators: [{
1476
1645
  type: Component,
1477
1646
  args: [{
1478
1647
  selector: 'plait-element',
@@ -1527,9 +1696,9 @@ class PlaitToolbarComponent {
1527
1696
  this.resetZoomHandel.emit();
1528
1697
  }
1529
1698
  }
1530
- PlaitToolbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1531
- PlaitToolbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: PlaitToolbarComponent, selector: "plait-toolbar", inputs: { board: "board" }, outputs: { adaptHandle: "adaptHandle", zoomInHandle: "zoomInHandle", zoomOutHandle: "zoomOutHandle", resetZoomHandel: "resetZoomHandel" }, host: { properties: { "class": "this.hostClass" } }, ngImport: i0, template: "<div class=\"zoom-toolbar island plait-board-attached\">\n <a class=\"toolbar-item plait-action-icon\" [ngClass]=\"{ 'icon-active': isHand }\" (click)=\"activeHand()\">\n <ng-template [ngTemplateOutlet]=\"dragMoveTemplate\"></ng-template>\n </a>\n <div class=\"divider\"></div>\n <a class=\"toolbar-item plait-action-icon\" (mousedown)=\"adapt()\">\n <ng-template [ngTemplateOutlet]=\"adaptTemplate\"></ng-template>\n </a>\n <div class=\"divider\"></div>\n <a class=\"toolbar-item plait-action-icon\" (mousedown)=\"zoomOut()\">\n <ng-template [ngTemplateOutlet]=\"zoomOutTemplate\"></ng-template>\n </a>\n <div class=\"toolbar-item zoom-value\" (mousedown)=\"resetZoom()\">{{ zoom }}%</div>\n <a class=\"toolbar-item plait-action-icon\" (mousedown)=\"zoomIn()\">\n <ng-template [ngTemplateOutlet]=\"zoomInTemplate\"></ng-template>\n </a>\n</div>\n\n<ng-template #dragMoveTemplate>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/hand</title>\n <g id=\"1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/hand\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M8.44583468,0.500225887 C9.07406934,0.510185679 9.54739531,0.839591366 9.86192311,1.34305279 C9.89696656,1.39914649 9.92878401,1.45492964 9.9576026,1.50991157 L9.9576026,1.50991157 L10.0210033,1.64201027 L10.061978,1.62350755 C10.1972891,1.56834247 10.3444107,1.53218464 10.5027907,1.51755353 L10.5027907,1.51755353 L10.6649031,1.51019133 C11.4883708,1.51019133 12.0208782,1.99343346 12.3023042,2.66393278 C12.3903714,2.87392911 12.4344191,3.10047818 12.4339446,3.3257952 L12.4339446,3.3257952 L12.4360033,3.80501027 L12.5160535,3.78341501 C12.6124478,3.76124046 12.7138812,3.74739854 12.820201,3.74250274 L12.820201,3.74250274 L12.9833264,3.74194533 C13.6121166,3.7657478 14.0645887,4.0801724 14.3087062,4.56112689 C14.4521117,4.8436609 14.4987984,5.11349437 14.4999262,5.33449618 L14.4999262,5.33449618 L14.3922653,12.049414 C14.3784752,12.909177 14.0717787,13.7360948 13.5212406,14.3825228 C13.4055676,14.5183496 13.2843697,14.643961 13.1582361,14.7596335 C12.4634771,15.3967716 11.755103,15.6538706 11.1897396,15.7000055 L11.1897396,15.7000055 L7.4723083,15.6798158 C7.14276373,15.634268 6.81580098,15.5154267 6.49455235,15.3472501 C6.25643701,15.2225944 6.06881706,15.0975452 5.88705731,14.9494308 L5.88705731,14.9494308 L2.55198782,11.500873 C2.39559475,11.3769079 2.17626793,11.1748532 1.9548636,10.9139403 C1.57867502,10.4706225 1.33501976,10.0139923 1.30330257,9.52833025 C1.28093191,9.18578476 1.37200912,8.85641102 1.5826788,8.56872564 C1.82538833,8.23725279 2.12881965,8.02107162 2.47470569,7.92957033 C2.95807982,7.80169771 3.42705723,7.92468989 3.86509644,8.18731167 C4.04431391,8.29475961 4.1816109,8.40304483 4.26225571,8.47866867 L4.26225571,8.47866867 L4.61400328,8.79701027 L4.57247249,3.59275349 L4.57628524,3.46204923 C4.5897691,3.23444442 4.64087578,2.95701848 4.75937106,2.66961597 C5.01017272,2.06131302 5.49670227,1.64692543 6.21363856,1.60818786 C6.44223508,1.59583681 6.65042099,1.62176802 6.83696985,1.68057551 L6.83696985,1.68057551 L6.86400328,1.69001027 C6.88501862,1.63593052 6.90764242,1.58175442 6.9331867,1.52672633 L6.9331867,1.52672633 L7.01883595,1.35955614 C7.31549194,0.832047939 7.79476072,0.48993549 8.44583468,0.500225887 Z M8.42684173,1.70001476 C8.26825412,1.69756905 8.16339456,1.77242008 8.06478367,1.94776814 C8.03967773,1.99241107 8.01831703,2.03811495 8.00083464,2.07855067 L8.00083464,2.07855067 L7.94879157,2.2035905 L7.94354455,2.20731401 L7.943,3.161 L7.97170661,3.16123746 L7.97170661,7.60991883 L6.77170661,7.60991883 L6.771,3.338 L6.74362358,3.33880359 C6.74284189,3.29064626 6.73014163,3.20282206 6.7002616,3.11094408 L6.66446012,3.01903385 C6.58982025,2.85766739 6.49843292,2.79455071 6.27838133,2.80644008 C6.07001018,2.81769881 5.95642108,2.91444507 5.86877664,3.12702089 C5.79792279,3.29887224 5.77228127,3.48655908 5.77246879,3.58977183 L5.77246879,3.58977183 L5.83613619,11.5252021 L3.41863956,9.33477657 L3.31637296,9.25979571 L3.24805011,9.21651224 C3.06096922,9.10434987 2.89279975,9.06024641 2.78159879,9.0896637 C2.71007735,9.10858411 2.63607367,9.1613084 2.55086305,9.27768211 C2.51020424,9.33320478 2.49638061,9.38319687 2.50075171,9.4501283 C2.51206889,9.62341997 2.64503022,9.87260054 2.86983366,10.1375191 C3.03268834,10.3294345 3.19762053,10.4813781 3.35554956,10.6131022 L3.35554956,10.6131022 L6.68454317,14.0569073 C6.71106575,14.0773808 6.74806086,14.1037158 6.79369091,14.1335929 L6.79369091,14.1335929 L6.95464838,14.2315311 L7.05111031,14.2841211 C7.25978123,14.3933622 7.46253523,14.4670573 7.55685495,14.4854708 L7.55685495,14.4854708 L11.1407985,14.5022108 C11.1503576,14.5013899 11.1627905,14.4997539 11.1779002,14.4971772 L11.1779002,14.4971772 L11.2991076,14.4694224 C11.3491682,14.4557375 11.4083624,14.437284 11.4751158,14.4130563 C11.769383,14.3062543 12.066676,14.1324596 12.3471758,13.8752234 C12.4371203,13.7927386 12.5240597,13.7026333 12.607654,13.6044743 C12.9760464,13.1719172 13.183059,12.6137678 13.1924195,12.030173 L13.1924195,12.030173 L13.3000132,5.32832551 C13.2997939,5.29016685 13.2826117,5.19085946 13.2386527,5.10425262 C13.1843838,4.99733326 13.1129774,4.94771265 12.9379578,4.94108739 C12.6814739,4.93138871 12.534132,5.11189595 12.4756792,5.39480062 L12.4768718,7.52734922 L11.2768718,7.52734922 L11.276,5.688 L11.2462883,5.6883208 L11.2339541,3.32771285 C11.2341,3.2560396 11.2209054,3.18817621 11.1957482,3.12818892 C11.0820579,2.85732094 10.9199288,2.71019133 10.6649031,2.71019133 C10.456829,2.71019133 10.3197487,2.87378067 10.2524297,3.11264939 L10.2530225,7.512783 L9.05302254,7.512783 L9.053,3.288 L9.01554331,3.28724203 L8.98800328,2.29901027 L8.9629175,2.22263368 C8.94515567,2.17417174 8.92167756,2.11937748 8.8924232,2.06330056 L8.8924232,2.06330056 L8.84420197,1.9788544 C8.72758855,1.79219249 8.59915015,1.70280728 8.42684173,1.70001476 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n\n<ng-template #adaptTemplate>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/Fit canvas</title>\n <g id=\"1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/Fit-canvas\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M14.9971494,10.4 L14.9971494,13.4020516 C14.9971494,14.2366152 14.3581879,14.9219414 13.542782,14.9955129 L13.3971494,15.0020516 L10.4,15.0020516 L10.4,13.8020516 L13.3971494,13.8020516 C13.590449,13.8020516 13.7517243,13.6649388 13.7890228,13.4826656 L13.7971494,13.4020516 L13.7971494,10.4 L14.9971494,10.4 Z M2.2,10.4 L2.2,13.3971494 C2.2,13.590449 2.3371128,13.7517243 2.51938605,13.7890228 L2.6,13.7971494 L5.60205161,13.7971494 L5.60205161,14.9971494 L2.6,14.9971494 C1.76543638,14.9971494 1.08011021,14.3581879 1.00653868,13.542782 L1,13.3971494 L1,10.4 L2.2,10.4 Z M10.5024511,4.9 C11.3861067,4.9 12.1024511,5.6163444 12.1024511,6.5 L12.1024511,6.5 L12.1024511,9.5 C12.1024511,10.3836556 11.3861067,11.1 10.5024511,11.1 L10.5024511,11.1 L5.50245112,11.1 C4.61879552,11.1 3.90245112,10.3836556 3.90245112,9.5 L3.90245112,9.5 L3.90245112,6.5 C3.90245112,5.6163444 4.61879552,4.9 5.50245112,4.9 L5.50245112,4.9 Z M10.5024511,6.1 L5.50245112,6.1 C5.28153722,6.1 5.10245112,6.2790861 5.10245112,6.5 L5.10245112,6.5 L5.10245112,9.5 C5.10245112,9.7209139 5.28153722,9.9 5.50245112,9.9 L5.50245112,9.9 L10.5024511,9.9 C10.723365,9.9 10.9024511,9.7209139 10.9024511,9.5 L10.9024511,9.5 L10.9024511,6.5 C10.9024511,6.2790861 10.723365,6.1 10.5024511,6.1 L10.5024511,6.1 Z M5.59714938,1 L5.59714938,2.2 L2.6,2.2 C2.40670034,2.2 2.24542508,2.3371128 2.20812658,2.51938605 L2.2,2.6 L2.2,5.60205161 L1,5.60205161 L1,2.6 C1,1.76543638 1.63896152,1.08011021 2.45436739,1.00653868 L2.6,1 L5.59714938,1 Z M13.3971494,1 L13.542782,1.00653868 C14.3581879,1.08011021 14.9971494,1.76543638 14.9971494,2.6 L14.9971494,2.6 L14.9971494,5.60205161 L13.7971494,5.60205161 L13.7971494,2.6 L13.7890228,2.51938605 C13.7517243,2.3371128 13.590449,2.2 13.3971494,2.2 L13.3971494,2.2 L10.4,2.2 L10.4,1 L13.3971494,1 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n<ng-template #zoomOutTemplate>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>action/zoom-out</title>\n <desc>Created with Sketch.</desc>\n <g id=\"action/zoom-out\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M6.85,2.73225886e-13 C10.6331505,2.73225886e-13 13.7,3.06684946 13.7,6.85 C13.7,8.54194045 13.0865836,10.0906098 12.0700142,11.2857448 L15.4201976,14.5717081 C15.6567367,14.8037768 15.6603607,15.1836585 15.4282919,15.4201976 C15.1962232,15.6567367 14.8163415,15.6603607 14.5798024,15.4282919 L14.5798024,15.4282919 L11.2163456,12.128262 C10.0309427,13.1099691 8.50937591,13.7 6.85,13.7 C3.06684946,13.7 4.58522109e-14,10.6331505 4.58522109e-14,6.85 C4.58522109e-14,3.06684946 3.06684946,2.73225886e-13 6.85,2.73225886e-13 Z M6.85,1.2 C3.72959116,1.2 1.2,3.72959116 1.2,6.85 C1.2,9.97040884 3.72959116,12.5 6.85,12.5 C8.31753357,12.5 9.65438791,11.9404957 10.6588859,11.0231643 C10.6855412,10.9625408 10.7245275,10.9050898 10.7743982,10.8542584 C10.8288931,10.7987137 10.8915387,10.7560124 10.9585649,10.7261903 C11.9144009,9.71595758 12.5,8.35136579 12.5,6.85 C12.5,3.72959116 9.97040884,1.2 6.85,1.2 Z M4.6,6.2 L9.12944565,6.2 C9.4608165,6.2 9.72944565,6.46862915 9.72944565,6.8 C9.72944565,7.09823376 9.51185604,7.34564675 9.22676876,7.39214701 L9.12944565,7.4 L4.6,7.4 C4.26862915,7.4 4,7.13137085 4,6.8 C4,6.50176624 4.21758961,6.25435325 4.50267688,6.20785299 L4.6,6.2 L9.12944565,6.2 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n\n<ng-template #zoomInTemplate\n ><svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>action/zoom-in</title>\n <desc>Created with Sketch.</desc>\n <g id=\"action/zoom-in\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M6.85,-1.81188398e-13 C10.6331505,-1.81188398e-13 13.7,3.06684946 13.7,6.85 C13.7,8.54194045 13.0865836,10.0906098 12.0700142,11.2857448 L15.4201976,14.5717081 C15.6567367,14.8037768 15.6603607,15.1836585 15.4282919,15.4201976 C15.1962232,15.6567367 14.8163415,15.6603607 14.5798024,15.4282919 L14.5798024,15.4282919 L11.2163456,12.128262 C10.0309427,13.1099691 8.50937591,13.7 6.85,13.7 C3.06684946,13.7 4.61852778e-14,10.6331505 4.61852778e-14,6.85 C4.61852778e-14,3.06684946 3.06684946,-1.81188398e-13 6.85,-1.81188398e-13 Z M6.85,1.2 C3.72959116,1.2 1.2,3.72959116 1.2,6.85 C1.2,9.97040884 3.72959116,12.5 6.85,12.5 C8.31753357,12.5 9.65438791,11.9404957 10.6588859,11.0231643 C10.6855412,10.9625408 10.7245275,10.9050898 10.7743982,10.8542584 C10.8288931,10.7987137 10.8915387,10.7560124 10.9585649,10.7261903 C11.9144009,9.71595758 12.5,8.35136579 12.5,6.85 C12.5,3.72959116 9.97040884,1.2 6.85,1.2 Z M6.86472282,3.93527718 C7.16295659,3.93527718 7.41036958,4.15286679 7.45686984,4.43795406 L7.46472282,4.53527718 L7.464,6.19927718 L9.12944565,6.2 C9.42767941,6.2 9.6750924,6.41758961 9.72159266,6.70267688 L9.72944565,6.8 C9.72944565,7.09823376 9.51185604,7.34564675 9.22676876,7.39214701 L9.12944565,7.4 L7.464,7.39927718 L7.46472282,9.06472282 C7.46472282,9.36295659 7.24713321,9.61036958 6.96204594,9.65686984 L6.86472282,9.66472282 C6.56648906,9.66472282 6.31907607,9.44713321 6.27257581,9.16204594 L6.26472282,9.06472282 L6.264,7.39927718 L4.6,7.4 C4.30176624,7.4 4.05435325,7.18241039 4.00785299,6.89732312 L4,6.8 C4,6.50176624 4.21758961,6.25435325 4.50267688,6.20785299 L4.6,6.2 L6.264,6.19927718 L6.26472282,4.53527718 C6.26472282,4.2701805 6.43664548,4.0452385 6.67507642,3.96586557 L6.76739971,3.94313016 L6.86472282,3.93527718 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n", directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1532
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitToolbarComponent, decorators: [{
1699
+ PlaitToolbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1700
+ PlaitToolbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: PlaitToolbarComponent, selector: "plait-toolbar", inputs: { board: "board" }, outputs: { adaptHandle: "adaptHandle", zoomInHandle: "zoomInHandle", zoomOutHandle: "zoomOutHandle", resetZoomHandel: "resetZoomHandel" }, host: { properties: { "class": "this.hostClass" } }, ngImport: i0, template: "<div class=\"zoom-toolbar island plait-board-attached\">\n <a class=\"toolbar-item plait-action-icon\" [ngClass]=\"{ 'icon-active': isHand }\" (click)=\"activeHand()\">\n <ng-template [ngTemplateOutlet]=\"dragMoveTemplate\"></ng-template>\n </a>\n <div class=\"divider\"></div>\n <a class=\"toolbar-item plait-action-icon\" (mousedown)=\"adapt()\">\n <ng-template [ngTemplateOutlet]=\"adaptTemplate\"></ng-template>\n </a>\n <div class=\"divider\"></div>\n <a class=\"toolbar-item plait-action-icon\" (mousedown)=\"zoomOut()\">\n <ng-template [ngTemplateOutlet]=\"zoomOutTemplate\"></ng-template>\n </a>\n <div class=\"toolbar-item zoom-value\" (mousedown)=\"resetZoom()\">{{ zoom }}%</div>\n <a class=\"toolbar-item plait-action-icon\" (mousedown)=\"zoomIn()\">\n <ng-template [ngTemplateOutlet]=\"zoomInTemplate\"></ng-template>\n </a>\n</div>\n\n<ng-template #dragMoveTemplate>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/hand</title>\n <g id=\"1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/hand\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M8.44583468,0.500225887 C9.07406934,0.510185679 9.54739531,0.839591366 9.86192311,1.34305279 C9.89696656,1.39914649 9.92878401,1.45492964 9.9576026,1.50991157 L9.9576026,1.50991157 L10.0210033,1.64201027 L10.061978,1.62350755 C10.1972891,1.56834247 10.3444107,1.53218464 10.5027907,1.51755353 L10.5027907,1.51755353 L10.6649031,1.51019133 C11.4883708,1.51019133 12.0208782,1.99343346 12.3023042,2.66393278 C12.3903714,2.87392911 12.4344191,3.10047818 12.4339446,3.3257952 L12.4339446,3.3257952 L12.4360033,3.80501027 L12.5160535,3.78341501 C12.6124478,3.76124046 12.7138812,3.74739854 12.820201,3.74250274 L12.820201,3.74250274 L12.9833264,3.74194533 C13.6121166,3.7657478 14.0645887,4.0801724 14.3087062,4.56112689 C14.4521117,4.8436609 14.4987984,5.11349437 14.4999262,5.33449618 L14.4999262,5.33449618 L14.3922653,12.049414 C14.3784752,12.909177 14.0717787,13.7360948 13.5212406,14.3825228 C13.4055676,14.5183496 13.2843697,14.643961 13.1582361,14.7596335 C12.4634771,15.3967716 11.755103,15.6538706 11.1897396,15.7000055 L11.1897396,15.7000055 L7.4723083,15.6798158 C7.14276373,15.634268 6.81580098,15.5154267 6.49455235,15.3472501 C6.25643701,15.2225944 6.06881706,15.0975452 5.88705731,14.9494308 L5.88705731,14.9494308 L2.55198782,11.500873 C2.39559475,11.3769079 2.17626793,11.1748532 1.9548636,10.9139403 C1.57867502,10.4706225 1.33501976,10.0139923 1.30330257,9.52833025 C1.28093191,9.18578476 1.37200912,8.85641102 1.5826788,8.56872564 C1.82538833,8.23725279 2.12881965,8.02107162 2.47470569,7.92957033 C2.95807982,7.80169771 3.42705723,7.92468989 3.86509644,8.18731167 C4.04431391,8.29475961 4.1816109,8.40304483 4.26225571,8.47866867 L4.26225571,8.47866867 L4.61400328,8.79701027 L4.57247249,3.59275349 L4.57628524,3.46204923 C4.5897691,3.23444442 4.64087578,2.95701848 4.75937106,2.66961597 C5.01017272,2.06131302 5.49670227,1.64692543 6.21363856,1.60818786 C6.44223508,1.59583681 6.65042099,1.62176802 6.83696985,1.68057551 L6.83696985,1.68057551 L6.86400328,1.69001027 C6.88501862,1.63593052 6.90764242,1.58175442 6.9331867,1.52672633 L6.9331867,1.52672633 L7.01883595,1.35955614 C7.31549194,0.832047939 7.79476072,0.48993549 8.44583468,0.500225887 Z M8.42684173,1.70001476 C8.26825412,1.69756905 8.16339456,1.77242008 8.06478367,1.94776814 C8.03967773,1.99241107 8.01831703,2.03811495 8.00083464,2.07855067 L8.00083464,2.07855067 L7.94879157,2.2035905 L7.94354455,2.20731401 L7.943,3.161 L7.97170661,3.16123746 L7.97170661,7.60991883 L6.77170661,7.60991883 L6.771,3.338 L6.74362358,3.33880359 C6.74284189,3.29064626 6.73014163,3.20282206 6.7002616,3.11094408 L6.66446012,3.01903385 C6.58982025,2.85766739 6.49843292,2.79455071 6.27838133,2.80644008 C6.07001018,2.81769881 5.95642108,2.91444507 5.86877664,3.12702089 C5.79792279,3.29887224 5.77228127,3.48655908 5.77246879,3.58977183 L5.77246879,3.58977183 L5.83613619,11.5252021 L3.41863956,9.33477657 L3.31637296,9.25979571 L3.24805011,9.21651224 C3.06096922,9.10434987 2.89279975,9.06024641 2.78159879,9.0896637 C2.71007735,9.10858411 2.63607367,9.1613084 2.55086305,9.27768211 C2.51020424,9.33320478 2.49638061,9.38319687 2.50075171,9.4501283 C2.51206889,9.62341997 2.64503022,9.87260054 2.86983366,10.1375191 C3.03268834,10.3294345 3.19762053,10.4813781 3.35554956,10.6131022 L3.35554956,10.6131022 L6.68454317,14.0569073 C6.71106575,14.0773808 6.74806086,14.1037158 6.79369091,14.1335929 L6.79369091,14.1335929 L6.95464838,14.2315311 L7.05111031,14.2841211 C7.25978123,14.3933622 7.46253523,14.4670573 7.55685495,14.4854708 L7.55685495,14.4854708 L11.1407985,14.5022108 C11.1503576,14.5013899 11.1627905,14.4997539 11.1779002,14.4971772 L11.1779002,14.4971772 L11.2991076,14.4694224 C11.3491682,14.4557375 11.4083624,14.437284 11.4751158,14.4130563 C11.769383,14.3062543 12.066676,14.1324596 12.3471758,13.8752234 C12.4371203,13.7927386 12.5240597,13.7026333 12.607654,13.6044743 C12.9760464,13.1719172 13.183059,12.6137678 13.1924195,12.030173 L13.1924195,12.030173 L13.3000132,5.32832551 C13.2997939,5.29016685 13.2826117,5.19085946 13.2386527,5.10425262 C13.1843838,4.99733326 13.1129774,4.94771265 12.9379578,4.94108739 C12.6814739,4.93138871 12.534132,5.11189595 12.4756792,5.39480062 L12.4768718,7.52734922 L11.2768718,7.52734922 L11.276,5.688 L11.2462883,5.6883208 L11.2339541,3.32771285 C11.2341,3.2560396 11.2209054,3.18817621 11.1957482,3.12818892 C11.0820579,2.85732094 10.9199288,2.71019133 10.6649031,2.71019133 C10.456829,2.71019133 10.3197487,2.87378067 10.2524297,3.11264939 L10.2530225,7.512783 L9.05302254,7.512783 L9.053,3.288 L9.01554331,3.28724203 L8.98800328,2.29901027 L8.9629175,2.22263368 C8.94515567,2.17417174 8.92167756,2.11937748 8.8924232,2.06330056 L8.8924232,2.06330056 L8.84420197,1.9788544 C8.72758855,1.79219249 8.59915015,1.70280728 8.42684173,1.70001476 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n\n<ng-template #adaptTemplate>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/Fit canvas</title>\n <g id=\"1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/Fit-canvas\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M14.9971494,10.4 L14.9971494,13.4020516 C14.9971494,14.2366152 14.3581879,14.9219414 13.542782,14.9955129 L13.3971494,15.0020516 L10.4,15.0020516 L10.4,13.8020516 L13.3971494,13.8020516 C13.590449,13.8020516 13.7517243,13.6649388 13.7890228,13.4826656 L13.7971494,13.4020516 L13.7971494,10.4 L14.9971494,10.4 Z M2.2,10.4 L2.2,13.3971494 C2.2,13.590449 2.3371128,13.7517243 2.51938605,13.7890228 L2.6,13.7971494 L5.60205161,13.7971494 L5.60205161,14.9971494 L2.6,14.9971494 C1.76543638,14.9971494 1.08011021,14.3581879 1.00653868,13.542782 L1,13.3971494 L1,10.4 L2.2,10.4 Z M10.5024511,4.9 C11.3861067,4.9 12.1024511,5.6163444 12.1024511,6.5 L12.1024511,6.5 L12.1024511,9.5 C12.1024511,10.3836556 11.3861067,11.1 10.5024511,11.1 L10.5024511,11.1 L5.50245112,11.1 C4.61879552,11.1 3.90245112,10.3836556 3.90245112,9.5 L3.90245112,9.5 L3.90245112,6.5 C3.90245112,5.6163444 4.61879552,4.9 5.50245112,4.9 L5.50245112,4.9 Z M10.5024511,6.1 L5.50245112,6.1 C5.28153722,6.1 5.10245112,6.2790861 5.10245112,6.5 L5.10245112,6.5 L5.10245112,9.5 C5.10245112,9.7209139 5.28153722,9.9 5.50245112,9.9 L5.50245112,9.9 L10.5024511,9.9 C10.723365,9.9 10.9024511,9.7209139 10.9024511,9.5 L10.9024511,9.5 L10.9024511,6.5 C10.9024511,6.2790861 10.723365,6.1 10.5024511,6.1 L10.5024511,6.1 Z M5.59714938,1 L5.59714938,2.2 L2.6,2.2 C2.40670034,2.2 2.24542508,2.3371128 2.20812658,2.51938605 L2.2,2.6 L2.2,5.60205161 L1,5.60205161 L1,2.6 C1,1.76543638 1.63896152,1.08011021 2.45436739,1.00653868 L2.6,1 L5.59714938,1 Z M13.3971494,1 L13.542782,1.00653868 C14.3581879,1.08011021 14.9971494,1.76543638 14.9971494,2.6 L14.9971494,2.6 L14.9971494,5.60205161 L13.7971494,5.60205161 L13.7971494,2.6 L13.7890228,2.51938605 C13.7517243,2.3371128 13.590449,2.2 13.3971494,2.2 L13.3971494,2.2 L10.4,2.2 L10.4,1 L13.3971494,1 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n<ng-template #zoomOutTemplate>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>action/zoom-out</title>\n <desc>Created with Sketch.</desc>\n <g id=\"action/zoom-out\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M6.85,2.73225886e-13 C10.6331505,2.73225886e-13 13.7,3.06684946 13.7,6.85 C13.7,8.54194045 13.0865836,10.0906098 12.0700142,11.2857448 L15.4201976,14.5717081 C15.6567367,14.8037768 15.6603607,15.1836585 15.4282919,15.4201976 C15.1962232,15.6567367 14.8163415,15.6603607 14.5798024,15.4282919 L14.5798024,15.4282919 L11.2163456,12.128262 C10.0309427,13.1099691 8.50937591,13.7 6.85,13.7 C3.06684946,13.7 4.58522109e-14,10.6331505 4.58522109e-14,6.85 C4.58522109e-14,3.06684946 3.06684946,2.73225886e-13 6.85,2.73225886e-13 Z M6.85,1.2 C3.72959116,1.2 1.2,3.72959116 1.2,6.85 C1.2,9.97040884 3.72959116,12.5 6.85,12.5 C8.31753357,12.5 9.65438791,11.9404957 10.6588859,11.0231643 C10.6855412,10.9625408 10.7245275,10.9050898 10.7743982,10.8542584 C10.8288931,10.7987137 10.8915387,10.7560124 10.9585649,10.7261903 C11.9144009,9.71595758 12.5,8.35136579 12.5,6.85 C12.5,3.72959116 9.97040884,1.2 6.85,1.2 Z M4.6,6.2 L9.12944565,6.2 C9.4608165,6.2 9.72944565,6.46862915 9.72944565,6.8 C9.72944565,7.09823376 9.51185604,7.34564675 9.22676876,7.39214701 L9.12944565,7.4 L4.6,7.4 C4.26862915,7.4 4,7.13137085 4,6.8 C4,6.50176624 4.21758961,6.25435325 4.50267688,6.20785299 L4.6,6.2 L9.12944565,6.2 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n\n<ng-template #zoomInTemplate\n ><svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>action/zoom-in</title>\n <desc>Created with Sketch.</desc>\n <g id=\"action/zoom-in\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M6.85,-1.81188398e-13 C10.6331505,-1.81188398e-13 13.7,3.06684946 13.7,6.85 C13.7,8.54194045 13.0865836,10.0906098 12.0700142,11.2857448 L15.4201976,14.5717081 C15.6567367,14.8037768 15.6603607,15.1836585 15.4282919,15.4201976 C15.1962232,15.6567367 14.8163415,15.6603607 14.5798024,15.4282919 L14.5798024,15.4282919 L11.2163456,12.128262 C10.0309427,13.1099691 8.50937591,13.7 6.85,13.7 C3.06684946,13.7 4.61852778e-14,10.6331505 4.61852778e-14,6.85 C4.61852778e-14,3.06684946 3.06684946,-1.81188398e-13 6.85,-1.81188398e-13 Z M6.85,1.2 C3.72959116,1.2 1.2,3.72959116 1.2,6.85 C1.2,9.97040884 3.72959116,12.5 6.85,12.5 C8.31753357,12.5 9.65438791,11.9404957 10.6588859,11.0231643 C10.6855412,10.9625408 10.7245275,10.9050898 10.7743982,10.8542584 C10.8288931,10.7987137 10.8915387,10.7560124 10.9585649,10.7261903 C11.9144009,9.71595758 12.5,8.35136579 12.5,6.85 C12.5,3.72959116 9.97040884,1.2 6.85,1.2 Z M6.86472282,3.93527718 C7.16295659,3.93527718 7.41036958,4.15286679 7.45686984,4.43795406 L7.46472282,4.53527718 L7.464,6.19927718 L9.12944565,6.2 C9.42767941,6.2 9.6750924,6.41758961 9.72159266,6.70267688 L9.72944565,6.8 C9.72944565,7.09823376 9.51185604,7.34564675 9.22676876,7.39214701 L9.12944565,7.4 L7.464,7.39927718 L7.46472282,9.06472282 C7.46472282,9.36295659 7.24713321,9.61036958 6.96204594,9.65686984 L6.86472282,9.66472282 C6.56648906,9.66472282 6.31907607,9.44713321 6.27257581,9.16204594 L6.26472282,9.06472282 L6.264,7.39927718 L4.6,7.4 C4.30176624,7.4 4.05435325,7.18241039 4.00785299,6.89732312 L4,6.8 C4,6.50176624 4.21758961,6.25435325 4.50267688,6.20785299 L4.6,6.2 L6.264,6.19927718 L6.26472282,4.53527718 C6.26472282,4.2701805 6.43664548,4.0452385 6.67507642,3.96586557 L6.76739971,3.94313016 L6.86472282,3.93527718 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1701
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitToolbarComponent, decorators: [{
1533
1702
  type: Component,
1534
1703
  args: [{ selector: 'plait-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"zoom-toolbar island plait-board-attached\">\n <a class=\"toolbar-item plait-action-icon\" [ngClass]=\"{ 'icon-active': isHand }\" (click)=\"activeHand()\">\n <ng-template [ngTemplateOutlet]=\"dragMoveTemplate\"></ng-template>\n </a>\n <div class=\"divider\"></div>\n <a class=\"toolbar-item plait-action-icon\" (mousedown)=\"adapt()\">\n <ng-template [ngTemplateOutlet]=\"adaptTemplate\"></ng-template>\n </a>\n <div class=\"divider\"></div>\n <a class=\"toolbar-item plait-action-icon\" (mousedown)=\"zoomOut()\">\n <ng-template [ngTemplateOutlet]=\"zoomOutTemplate\"></ng-template>\n </a>\n <div class=\"toolbar-item zoom-value\" (mousedown)=\"resetZoom()\">{{ zoom }}%</div>\n <a class=\"toolbar-item plait-action-icon\" (mousedown)=\"zoomIn()\">\n <ng-template [ngTemplateOutlet]=\"zoomInTemplate\"></ng-template>\n </a>\n</div>\n\n<ng-template #dragMoveTemplate>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/hand</title>\n <g id=\"1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/hand\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M8.44583468,0.500225887 C9.07406934,0.510185679 9.54739531,0.839591366 9.86192311,1.34305279 C9.89696656,1.39914649 9.92878401,1.45492964 9.9576026,1.50991157 L9.9576026,1.50991157 L10.0210033,1.64201027 L10.061978,1.62350755 C10.1972891,1.56834247 10.3444107,1.53218464 10.5027907,1.51755353 L10.5027907,1.51755353 L10.6649031,1.51019133 C11.4883708,1.51019133 12.0208782,1.99343346 12.3023042,2.66393278 C12.3903714,2.87392911 12.4344191,3.10047818 12.4339446,3.3257952 L12.4339446,3.3257952 L12.4360033,3.80501027 L12.5160535,3.78341501 C12.6124478,3.76124046 12.7138812,3.74739854 12.820201,3.74250274 L12.820201,3.74250274 L12.9833264,3.74194533 C13.6121166,3.7657478 14.0645887,4.0801724 14.3087062,4.56112689 C14.4521117,4.8436609 14.4987984,5.11349437 14.4999262,5.33449618 L14.4999262,5.33449618 L14.3922653,12.049414 C14.3784752,12.909177 14.0717787,13.7360948 13.5212406,14.3825228 C13.4055676,14.5183496 13.2843697,14.643961 13.1582361,14.7596335 C12.4634771,15.3967716 11.755103,15.6538706 11.1897396,15.7000055 L11.1897396,15.7000055 L7.4723083,15.6798158 C7.14276373,15.634268 6.81580098,15.5154267 6.49455235,15.3472501 C6.25643701,15.2225944 6.06881706,15.0975452 5.88705731,14.9494308 L5.88705731,14.9494308 L2.55198782,11.500873 C2.39559475,11.3769079 2.17626793,11.1748532 1.9548636,10.9139403 C1.57867502,10.4706225 1.33501976,10.0139923 1.30330257,9.52833025 C1.28093191,9.18578476 1.37200912,8.85641102 1.5826788,8.56872564 C1.82538833,8.23725279 2.12881965,8.02107162 2.47470569,7.92957033 C2.95807982,7.80169771 3.42705723,7.92468989 3.86509644,8.18731167 C4.04431391,8.29475961 4.1816109,8.40304483 4.26225571,8.47866867 L4.26225571,8.47866867 L4.61400328,8.79701027 L4.57247249,3.59275349 L4.57628524,3.46204923 C4.5897691,3.23444442 4.64087578,2.95701848 4.75937106,2.66961597 C5.01017272,2.06131302 5.49670227,1.64692543 6.21363856,1.60818786 C6.44223508,1.59583681 6.65042099,1.62176802 6.83696985,1.68057551 L6.83696985,1.68057551 L6.86400328,1.69001027 C6.88501862,1.63593052 6.90764242,1.58175442 6.9331867,1.52672633 L6.9331867,1.52672633 L7.01883595,1.35955614 C7.31549194,0.832047939 7.79476072,0.48993549 8.44583468,0.500225887 Z M8.42684173,1.70001476 C8.26825412,1.69756905 8.16339456,1.77242008 8.06478367,1.94776814 C8.03967773,1.99241107 8.01831703,2.03811495 8.00083464,2.07855067 L8.00083464,2.07855067 L7.94879157,2.2035905 L7.94354455,2.20731401 L7.943,3.161 L7.97170661,3.16123746 L7.97170661,7.60991883 L6.77170661,7.60991883 L6.771,3.338 L6.74362358,3.33880359 C6.74284189,3.29064626 6.73014163,3.20282206 6.7002616,3.11094408 L6.66446012,3.01903385 C6.58982025,2.85766739 6.49843292,2.79455071 6.27838133,2.80644008 C6.07001018,2.81769881 5.95642108,2.91444507 5.86877664,3.12702089 C5.79792279,3.29887224 5.77228127,3.48655908 5.77246879,3.58977183 L5.77246879,3.58977183 L5.83613619,11.5252021 L3.41863956,9.33477657 L3.31637296,9.25979571 L3.24805011,9.21651224 C3.06096922,9.10434987 2.89279975,9.06024641 2.78159879,9.0896637 C2.71007735,9.10858411 2.63607367,9.1613084 2.55086305,9.27768211 C2.51020424,9.33320478 2.49638061,9.38319687 2.50075171,9.4501283 C2.51206889,9.62341997 2.64503022,9.87260054 2.86983366,10.1375191 C3.03268834,10.3294345 3.19762053,10.4813781 3.35554956,10.6131022 L3.35554956,10.6131022 L6.68454317,14.0569073 C6.71106575,14.0773808 6.74806086,14.1037158 6.79369091,14.1335929 L6.79369091,14.1335929 L6.95464838,14.2315311 L7.05111031,14.2841211 C7.25978123,14.3933622 7.46253523,14.4670573 7.55685495,14.4854708 L7.55685495,14.4854708 L11.1407985,14.5022108 C11.1503576,14.5013899 11.1627905,14.4997539 11.1779002,14.4971772 L11.1779002,14.4971772 L11.2991076,14.4694224 C11.3491682,14.4557375 11.4083624,14.437284 11.4751158,14.4130563 C11.769383,14.3062543 12.066676,14.1324596 12.3471758,13.8752234 C12.4371203,13.7927386 12.5240597,13.7026333 12.607654,13.6044743 C12.9760464,13.1719172 13.183059,12.6137678 13.1924195,12.030173 L13.1924195,12.030173 L13.3000132,5.32832551 C13.2997939,5.29016685 13.2826117,5.19085946 13.2386527,5.10425262 C13.1843838,4.99733326 13.1129774,4.94771265 12.9379578,4.94108739 C12.6814739,4.93138871 12.534132,5.11189595 12.4756792,5.39480062 L12.4768718,7.52734922 L11.2768718,7.52734922 L11.276,5.688 L11.2462883,5.6883208 L11.2339541,3.32771285 C11.2341,3.2560396 11.2209054,3.18817621 11.1957482,3.12818892 C11.0820579,2.85732094 10.9199288,2.71019133 10.6649031,2.71019133 C10.456829,2.71019133 10.3197487,2.87378067 10.2524297,3.11264939 L10.2530225,7.512783 L9.05302254,7.512783 L9.053,3.288 L9.01554331,3.28724203 L8.98800328,2.29901027 L8.9629175,2.22263368 C8.94515567,2.17417174 8.92167756,2.11937748 8.8924232,2.06330056 L8.8924232,2.06330056 L8.84420197,1.9788544 C8.72758855,1.79219249 8.59915015,1.70280728 8.42684173,1.70001476 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n\n<ng-template #adaptTemplate>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/Fit canvas</title>\n <g id=\"1.Base\u57FA\u7840/1.icon\u56FE\u6807/2.normal/Fit-canvas\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M14.9971494,10.4 L14.9971494,13.4020516 C14.9971494,14.2366152 14.3581879,14.9219414 13.542782,14.9955129 L13.3971494,15.0020516 L10.4,15.0020516 L10.4,13.8020516 L13.3971494,13.8020516 C13.590449,13.8020516 13.7517243,13.6649388 13.7890228,13.4826656 L13.7971494,13.4020516 L13.7971494,10.4 L14.9971494,10.4 Z M2.2,10.4 L2.2,13.3971494 C2.2,13.590449 2.3371128,13.7517243 2.51938605,13.7890228 L2.6,13.7971494 L5.60205161,13.7971494 L5.60205161,14.9971494 L2.6,14.9971494 C1.76543638,14.9971494 1.08011021,14.3581879 1.00653868,13.542782 L1,13.3971494 L1,10.4 L2.2,10.4 Z M10.5024511,4.9 C11.3861067,4.9 12.1024511,5.6163444 12.1024511,6.5 L12.1024511,6.5 L12.1024511,9.5 C12.1024511,10.3836556 11.3861067,11.1 10.5024511,11.1 L10.5024511,11.1 L5.50245112,11.1 C4.61879552,11.1 3.90245112,10.3836556 3.90245112,9.5 L3.90245112,9.5 L3.90245112,6.5 C3.90245112,5.6163444 4.61879552,4.9 5.50245112,4.9 L5.50245112,4.9 Z M10.5024511,6.1 L5.50245112,6.1 C5.28153722,6.1 5.10245112,6.2790861 5.10245112,6.5 L5.10245112,6.5 L5.10245112,9.5 C5.10245112,9.7209139 5.28153722,9.9 5.50245112,9.9 L5.50245112,9.9 L10.5024511,9.9 C10.723365,9.9 10.9024511,9.7209139 10.9024511,9.5 L10.9024511,9.5 L10.9024511,6.5 C10.9024511,6.2790861 10.723365,6.1 10.5024511,6.1 L10.5024511,6.1 Z M5.59714938,1 L5.59714938,2.2 L2.6,2.2 C2.40670034,2.2 2.24542508,2.3371128 2.20812658,2.51938605 L2.2,2.6 L2.2,5.60205161 L1,5.60205161 L1,2.6 C1,1.76543638 1.63896152,1.08011021 2.45436739,1.00653868 L2.6,1 L5.59714938,1 Z M13.3971494,1 L13.542782,1.00653868 C14.3581879,1.08011021 14.9971494,1.76543638 14.9971494,2.6 L14.9971494,2.6 L14.9971494,5.60205161 L13.7971494,5.60205161 L13.7971494,2.6 L13.7890228,2.51938605 C13.7517243,2.3371128 13.590449,2.2 13.3971494,2.2 L13.3971494,2.2 L10.4,2.2 L10.4,1 L13.3971494,1 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n<ng-template #zoomOutTemplate>\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>action/zoom-out</title>\n <desc>Created with Sketch.</desc>\n <g id=\"action/zoom-out\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M6.85,2.73225886e-13 C10.6331505,2.73225886e-13 13.7,3.06684946 13.7,6.85 C13.7,8.54194045 13.0865836,10.0906098 12.0700142,11.2857448 L15.4201976,14.5717081 C15.6567367,14.8037768 15.6603607,15.1836585 15.4282919,15.4201976 C15.1962232,15.6567367 14.8163415,15.6603607 14.5798024,15.4282919 L14.5798024,15.4282919 L11.2163456,12.128262 C10.0309427,13.1099691 8.50937591,13.7 6.85,13.7 C3.06684946,13.7 4.58522109e-14,10.6331505 4.58522109e-14,6.85 C4.58522109e-14,3.06684946 3.06684946,2.73225886e-13 6.85,2.73225886e-13 Z M6.85,1.2 C3.72959116,1.2 1.2,3.72959116 1.2,6.85 C1.2,9.97040884 3.72959116,12.5 6.85,12.5 C8.31753357,12.5 9.65438791,11.9404957 10.6588859,11.0231643 C10.6855412,10.9625408 10.7245275,10.9050898 10.7743982,10.8542584 C10.8288931,10.7987137 10.8915387,10.7560124 10.9585649,10.7261903 C11.9144009,9.71595758 12.5,8.35136579 12.5,6.85 C12.5,3.72959116 9.97040884,1.2 6.85,1.2 Z M4.6,6.2 L9.12944565,6.2 C9.4608165,6.2 9.72944565,6.46862915 9.72944565,6.8 C9.72944565,7.09823376 9.51185604,7.34564675 9.22676876,7.39214701 L9.12944565,7.4 L4.6,7.4 C4.26862915,7.4 4,7.13137085 4,6.8 C4,6.50176624 4.21758961,6.25435325 4.50267688,6.20785299 L4.6,6.2 L9.12944565,6.2 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n\n<ng-template #zoomInTemplate\n ><svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <title>action/zoom-in</title>\n <desc>Created with Sketch.</desc>\n <g id=\"action/zoom-in\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <path\n d=\"M6.85,-1.81188398e-13 C10.6331505,-1.81188398e-13 13.7,3.06684946 13.7,6.85 C13.7,8.54194045 13.0865836,10.0906098 12.0700142,11.2857448 L15.4201976,14.5717081 C15.6567367,14.8037768 15.6603607,15.1836585 15.4282919,15.4201976 C15.1962232,15.6567367 14.8163415,15.6603607 14.5798024,15.4282919 L14.5798024,15.4282919 L11.2163456,12.128262 C10.0309427,13.1099691 8.50937591,13.7 6.85,13.7 C3.06684946,13.7 4.61852778e-14,10.6331505 4.61852778e-14,6.85 C4.61852778e-14,3.06684946 3.06684946,-1.81188398e-13 6.85,-1.81188398e-13 Z M6.85,1.2 C3.72959116,1.2 1.2,3.72959116 1.2,6.85 C1.2,9.97040884 3.72959116,12.5 6.85,12.5 C8.31753357,12.5 9.65438791,11.9404957 10.6588859,11.0231643 C10.6855412,10.9625408 10.7245275,10.9050898 10.7743982,10.8542584 C10.8288931,10.7987137 10.8915387,10.7560124 10.9585649,10.7261903 C11.9144009,9.71595758 12.5,8.35136579 12.5,6.85 C12.5,3.72959116 9.97040884,1.2 6.85,1.2 Z M6.86472282,3.93527718 C7.16295659,3.93527718 7.41036958,4.15286679 7.45686984,4.43795406 L7.46472282,4.53527718 L7.464,6.19927718 L9.12944565,6.2 C9.42767941,6.2 9.6750924,6.41758961 9.72159266,6.70267688 L9.72944565,6.8 C9.72944565,7.09823376 9.51185604,7.34564675 9.22676876,7.39214701 L9.12944565,7.4 L7.464,7.39927718 L7.46472282,9.06472282 C7.46472282,9.36295659 7.24713321,9.61036958 6.96204594,9.65686984 L6.86472282,9.66472282 C6.56648906,9.66472282 6.31907607,9.44713321 6.27257581,9.16204594 L6.26472282,9.06472282 L6.264,7.39927718 L4.6,7.4 C4.30176624,7.4 4.05435325,7.18241039 4.00785299,6.89732312 L4,6.8 C4,6.50176624 4.21758961,6.25435325 4.50267688,6.20785299 L4.6,6.2 L6.264,6.19927718 L6.26472282,4.53527718 C6.26472282,4.2701805 6.43664548,4.0452385 6.67507642,3.96586557 L6.76739971,3.94313016 L6.86472282,3.93527718 Z\"\n id=\"\u5F62\u72B6\u7ED3\u5408\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n</ng-template>\n" }]
1535
1704
  }], propDecorators: { hostClass: [{
@@ -1549,28 +1718,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1549
1718
 
1550
1719
  const ElementHostClass = 'element-host';
1551
1720
  class PlaitBoardComponent {
1552
- constructor(cdr, renderer2, elementRef) {
1553
- this.cdr = cdr;
1554
- this.renderer2 = renderer2;
1555
- this.elementRef = elementRef;
1556
- this.hasInitialized = false;
1557
- this.destroy$ = new Subject();
1558
- this.viewportState = {
1559
- zoom: 1,
1560
- autoFitPadding: 8
1561
- };
1562
- this.plaitValue = [];
1563
- this.plaitPlugins = [];
1564
- this.plaitChange = new EventEmitter();
1565
- this.plaitBoardInitialized = new EventEmitter();
1566
- this.trackBy = (index, element) => {
1567
- return index;
1568
- };
1569
- }
1570
- get isFocused() {
1571
- var _a;
1572
- return (_a = this.board) === null || _a === void 0 ? void 0 : _a.selection;
1573
- }
1574
1721
  get host() {
1575
1722
  return this.svg.nativeElement;
1576
1723
  }
@@ -1580,21 +1727,38 @@ class PlaitBoardComponent {
1580
1727
  get readonly() {
1581
1728
  return this.board.options.readonly;
1582
1729
  }
1583
- get focused() {
1584
- return this.isFocused;
1730
+ get isFocused() {
1731
+ return PlaitBoard.isFocus(this.board);
1585
1732
  }
1586
1733
  get nativeElement() {
1587
1734
  return this.elementRef.nativeElement;
1588
1735
  }
1736
+ constructor(cdr, renderer2, elementRef, ngZone) {
1737
+ this.cdr = cdr;
1738
+ this.renderer2 = renderer2;
1739
+ this.elementRef = elementRef;
1740
+ this.ngZone = ngZone;
1741
+ this.hasInitialized = false;
1742
+ this.destroy$ = new Subject();
1743
+ this.plaitValue = [];
1744
+ this.plaitPlugins = [];
1745
+ this.plaitChange = new EventEmitter();
1746
+ this.plaitBoardInitialized = new EventEmitter();
1747
+ this.trackBy = (index, element) => {
1748
+ return index;
1749
+ };
1750
+ }
1589
1751
  ngOnInit() {
1590
1752
  const elementHost = this.host.querySelector(`.${ElementHostClass}`);
1591
1753
  const roughSVG = rough.svg(this.host, {
1592
1754
  options: { roughness: 0, strokeWidth: 1 }
1593
1755
  });
1756
+ this.roughSVG = roughSVG;
1594
1757
  this.initializePlugins();
1595
1758
  this.initializeEvents();
1596
1759
  this.viewportScrollListener();
1597
1760
  this.elementResizeListener();
1761
+ this.mouseLeaveListener();
1598
1762
  BOARD_TO_COMPONENT.set(this.board, this);
1599
1763
  BOARD_TO_ROUGH_SVG.set(this.board, roughSVG);
1600
1764
  BOARD_TO_HOST.set(this.board, this.host);
@@ -1611,13 +1775,19 @@ class PlaitBoardComponent {
1611
1775
  });
1612
1776
  this.hasInitialized = true;
1613
1777
  }
1778
+ mouseLeaveListener() {
1779
+ fromEvent(this.host, 'mouseleave')
1780
+ .pipe(takeUntil(this.destroy$))
1781
+ .subscribe((event) => {
1782
+ BOARD_TO_MOVING_POINT.delete(this.board);
1783
+ });
1784
+ }
1614
1785
  ngOnChanges(changes) {
1615
1786
  if (this.hasInitialized) {
1616
1787
  const valueChange = changes['plaitValue'];
1617
1788
  const options = changes['plaitOptions'];
1618
- if (valueChange) {
1789
+ if (valueChange)
1619
1790
  this.board.children = valueChange.currentValue;
1620
- }
1621
1791
  if (options)
1622
1792
  this.board.options = options.currentValue;
1623
1793
  this.cdr.markForCheck();
@@ -1625,22 +1795,18 @@ class PlaitBoardComponent {
1625
1795
  }
1626
1796
  ngAfterViewInit() {
1627
1797
  this.plaitBoardInitialized.emit(this.board);
1628
- this.initViewportContainer();
1629
- this.calcViewBox(this.viewportState.zoom);
1630
- this.initViewport();
1798
+ initializeViewportContainer(this.board);
1799
+ initializeViewBox(this.board);
1800
+ initializeViewportOffset(this.board);
1631
1801
  }
1632
1802
  initializePlugins() {
1633
- var _a, _b;
1634
- let board = withHandPointer(withHistory(withSelection(withBoard(createBoard(this.plaitValue, this.plaitOptions)))));
1803
+ let board = withHandPointer(withHistory(withSelection(withBoard(withViewport(createBoard(this.plaitValue, this.plaitOptions))))));
1635
1804
  this.plaitPlugins.forEach(plugin => {
1636
1805
  board = plugin(board);
1637
1806
  });
1638
1807
  this.board = board;
1639
1808
  if (this.plaitViewport) {
1640
1809
  this.board.viewport = this.plaitViewport;
1641
- this.updateViewportState({
1642
- zoom: (_b = (_a = this.plaitViewport) === null || _a === void 0 ? void 0 : _a.zoom) !== null && _b !== void 0 ? _b : 1
1643
- });
1644
1810
  }
1645
1811
  }
1646
1812
  initializeEvents() {
@@ -1676,34 +1842,34 @@ class PlaitBoardComponent {
1676
1842
  this.board.dblclick(event);
1677
1843
  });
1678
1844
  fromEvent(document, 'keydown')
1679
- .pipe(takeUntil(this.destroy$), filter(() => {
1680
- return !IS_TEXT_EDITABLE.get(this.board) && !!this.board.selection;
1681
- }))
1845
+ .pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board)))
1682
1846
  .subscribe((event) => {
1683
1847
  var _a;
1848
+ if (isHotkey(['mod+=', 'mod++'], { byKey: true })(event)) {
1849
+ event.preventDefault();
1850
+ this.zoomInHandle(false);
1851
+ }
1852
+ if (isHotkey('mod+-', { byKey: true })(event)) {
1853
+ this.zoomOutHandle();
1854
+ event.preventDefault();
1855
+ }
1684
1856
  (_a = this.board) === null || _a === void 0 ? void 0 : _a.keydown(event);
1685
1857
  });
1686
1858
  fromEvent(document, 'keyup')
1687
- .pipe(takeUntil(this.destroy$), filter(() => {
1688
- return !IS_TEXT_EDITABLE.get(this.board) && !!this.board.selection;
1689
- }))
1859
+ .pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board)))
1690
1860
  .subscribe((event) => {
1691
1861
  var _a;
1692
1862
  (_a = this.board) === null || _a === void 0 ? void 0 : _a.keyup(event);
1693
1863
  });
1694
1864
  fromEvent(document, 'copy')
1695
- .pipe(takeUntil(this.destroy$), filter(() => {
1696
- return !IS_TEXT_EDITABLE.get(this.board) && !!this.board.selection;
1697
- }))
1865
+ .pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board)))
1698
1866
  .subscribe((event) => {
1699
1867
  var _a;
1700
1868
  event.preventDefault();
1701
1869
  (_a = this.board) === null || _a === void 0 ? void 0 : _a.setFragment(event.clipboardData);
1702
1870
  });
1703
1871
  fromEvent(document, 'paste')
1704
- .pipe(takeUntil(this.destroy$), filter(() => {
1705
- return !IS_TEXT_EDITABLE.get(this.board) && !!this.board.selection && !this.readonly;
1706
- }))
1872
+ .pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.isReadonly(this.board) && !PlaitBoard.hasBeenTextEditing(this.board)))
1707
1873
  .subscribe((clipboardEvent) => {
1708
1874
  const mousePoint = BOARD_TO_MOVING_POINT.get(this.board);
1709
1875
  const rect = this.nativeElement.getBoundingClientRect();
@@ -1713,9 +1879,7 @@ class PlaitBoardComponent {
1713
1879
  }
1714
1880
  });
1715
1881
  fromEvent(document, 'cut')
1716
- .pipe(takeUntil(this.destroy$), filter(() => {
1717
- return !IS_TEXT_EDITABLE.get(this.board) && !!this.board.selection;
1718
- }))
1882
+ .pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.isReadonly(this.board) && !PlaitBoard.hasBeenTextEditing(this.board)))
1719
1883
  .subscribe((event) => {
1720
1884
  var _a, _b;
1721
1885
  event.preventDefault();
@@ -1724,207 +1888,56 @@ class PlaitBoardComponent {
1724
1888
  });
1725
1889
  }
1726
1890
  viewportScrollListener() {
1727
- fromEvent(this.viewportContainer.nativeElement, 'scroll')
1728
- .pipe(takeUntil(this.destroy$), filter(() => {
1729
- return !!this.isFocused;
1730
- }))
1731
- .subscribe((event) => {
1732
- const { scrollLeft, scrollTop } = event.target;
1733
- const left = this.viewportState.scrollLeft;
1734
- const top = this.viewportState.scrollTop;
1735
- if (Math.abs(left - scrollLeft) >= 1 || Math.abs(top - scrollTop) >= 1) {
1736
- this.setScrollLeft(scrollLeft);
1737
- this.setScrollTop(scrollTop);
1738
- this.setViewport();
1739
- }
1891
+ this.ngZone.runOutsideAngular(() => {
1892
+ fromEvent(this.viewportContainer.nativeElement, 'scroll')
1893
+ .pipe(takeUntil(this.destroy$), filter(() => {
1894
+ const isScrolling = isViewportScrolling(this.board);
1895
+ if (isScrolling) {
1896
+ clearViewportScrolling(this.board);
1897
+ }
1898
+ return !isScrolling && this.isFocused;
1899
+ }), tap((event) => {
1900
+ const { scrollLeft, scrollTop } = event.target;
1901
+ const zoom = this.board.viewport.zoom;
1902
+ const viewBox = getViewBox(this.board, zoom);
1903
+ const origination = [scrollLeft / zoom + viewBox[0], scrollTop / zoom + viewBox[1]];
1904
+ updateViewportOrigination(this.board, origination);
1905
+ return origination;
1906
+ }), debounceTime(500))
1907
+ .subscribe((event) => {
1908
+ const origination = getViewportOrigination(this.board);
1909
+ if (Point.isEquals(origination, this.board.viewport.origination)) {
1910
+ return;
1911
+ }
1912
+ setViewport(this.board, getViewportOrigination(this.board));
1913
+ });
1740
1914
  });
1741
1915
  }
1742
1916
  elementResizeListener() {
1743
1917
  this.resizeObserver = new ResizeObserver(() => {
1744
- this.initViewportContainer();
1745
- this.calcViewBox(this.board.viewport.zoom);
1746
- this.updateViewBoxStyles();
1747
- this.updateViewportScrolling();
1748
- this.setViewport();
1918
+ initializeViewportContainer(this.board);
1919
+ initializeViewBox(this.board);
1920
+ updateViewportOffset(this.board);
1749
1921
  });
1750
1922
  this.resizeObserver.observe(this.nativeElement);
1751
1923
  }
1752
- updateViewportState(state) {
1753
- this.viewportState = Object.assign(Object.assign({}, this.viewportState), state);
1754
- }
1755
- initViewportContainer() {
1756
- const { width, height } = getBoardClientBox(this.board);
1757
- this.renderer2.setStyle(this.viewportContainer.nativeElement, 'width', `${width}px`);
1758
- this.renderer2.setStyle(this.viewportContainer.nativeElement, 'height', `${height}px`);
1759
- }
1760
- initViewport(viewport = this.board.viewport) {
1761
- var _a;
1762
- const originationCoord = viewport === null || viewport === void 0 ? void 0 : viewport.originationCoord;
1763
- const zoom = (_a = viewport === null || viewport === void 0 ? void 0 : viewport.zoom) !== null && _a !== void 0 ? _a : this.viewportState.zoom;
1764
- if (originationCoord) {
1765
- const matrix = this.getMatrix();
1766
- const [pointX, pointY] = invertViewportCoordinates([0, 0], matrix);
1767
- const scrollLeft = this.viewportState.scrollLeft;
1768
- const scrollTop = this.viewportState.scrollTop;
1769
- const left = scrollLeft + (originationCoord[0] - pointX) * zoom;
1770
- const top = scrollTop + (originationCoord[1] - pointY) * zoom;
1771
- this.setScroll(left, top);
1772
- }
1773
- else {
1774
- this.adaptHandle();
1775
- }
1776
- }
1777
- calcViewBox(zoom = this.viewportState.zoom) {
1778
- var _a;
1779
- zoom = clampZoomLevel(zoom);
1780
- const scrollBarWidth = ((_a = this.plaitOptions) === null || _a === void 0 ? void 0 : _a.hideScrollbar) ? SCROLL_BAR_WIDTH : 0;
1781
- const viewportContainerBox = getViewportContainerBox(this.board);
1782
- const groupBBox = getRootGroupBBox(this.board, zoom);
1783
- const horizontalPadding = viewportContainerBox.width / 2;
1784
- const verticalPadding = viewportContainerBox.height / 2;
1785
- const viewportWidth = (groupBBox.right - groupBBox.left) * zoom + 2 * horizontalPadding + scrollBarWidth;
1786
- const viewportHeight = (groupBBox.bottom - groupBBox.top) * zoom + 2 * verticalPadding + scrollBarWidth;
1787
- const viewBox = [
1788
- groupBBox.left - horizontalPadding / zoom,
1789
- groupBBox.top - verticalPadding / zoom,
1790
- viewportWidth / zoom,
1791
- viewportHeight / zoom
1792
- ];
1793
- const matrix = this.getMatrix();
1794
- let scrollLeft;
1795
- let scrollTop;
1796
- if (matrix.length > 0) {
1797
- // focusPoint
1798
- const focusX = viewportContainerBox.x + viewportContainerBox.width / 2;
1799
- const focusY = viewportContainerBox.y + viewportContainerBox.height / 2;
1800
- const viewportContainerPoint = [focusX - viewportContainerBox.x, focusY - viewportContainerBox.y, 1];
1801
- const point = invertViewportCoordinates([viewportContainerPoint[0], viewportContainerPoint[1]], matrix);
1802
- const newMatrix = [zoom, 0, 0, 0, zoom, 0, -zoom * viewBox[0], -zoom * viewBox[1], 1];
1803
- const newPoint = transformMat3([], point, newMatrix);
1804
- scrollLeft = newPoint[0] - viewportContainerPoint[0];
1805
- scrollTop = newPoint[1] - viewportContainerPoint[1];
1806
- }
1807
- else {
1808
- scrollLeft = horizontalPadding;
1809
- scrollTop = verticalPadding;
1810
- }
1811
- this.updateViewportState({
1812
- viewportWidth,
1813
- viewportHeight,
1814
- zoom,
1815
- viewBox
1816
- });
1817
- this.setScrollLeft(scrollLeft);
1818
- this.setScrollTop(scrollTop);
1819
- }
1820
- getMatrix() {
1821
- const { viewBox, zoom, scrollLeft, scrollTop } = this.viewportState;
1822
- if (scrollLeft >= 0 && scrollTop >= 0) {
1823
- return [zoom, 0, 0, 0, zoom, 0, -scrollLeft - zoom * viewBox[0], -scrollTop - zoom * viewBox[1], 1];
1824
- }
1825
- return [];
1826
- }
1827
- setScrollLeft(left) {
1828
- var _a;
1829
- const viewportContainerBox = getViewportContainerBox(this.board);
1830
- const scrollBarWidth = ((_a = this.plaitOptions) === null || _a === void 0 ? void 0 : _a.hideScrollbar) ? SCROLL_BAR_WIDTH : 0;
1831
- const { viewportWidth } = this.viewportState;
1832
- const width = viewportWidth - viewportContainerBox.width + scrollBarWidth;
1833
- this.viewportState.scrollLeft = left < 0 ? 0 : left > width ? width : left;
1834
- }
1835
- setScrollTop(top) {
1836
- var _a;
1837
- const viewportContainerBox = getViewportContainerBox(this.board);
1838
- const scrollBarWidth = ((_a = this.plaitOptions) === null || _a === void 0 ? void 0 : _a.hideScrollbar) ? SCROLL_BAR_WIDTH : 0;
1839
- const { viewportHeight } = this.viewportState;
1840
- const height = viewportHeight - viewportContainerBox.height + scrollBarWidth;
1841
- this.viewportState.scrollTop = top < 0 ? 0 : top > height ? height : top;
1842
- }
1843
- setScroll(left, top) {
1844
- this.setScrollLeft(left);
1845
- this.setScrollTop(top);
1846
- this.updateViewBoxStyles();
1847
- this.updateViewportScrolling();
1848
- this.setViewport();
1849
- }
1850
- updateViewBoxStyles() {
1851
- const { host, viewportState } = this;
1852
- const { viewportWidth, viewportHeight, viewBox } = viewportState;
1853
- this.renderer2.setStyle(host, 'display', 'block');
1854
- this.renderer2.setStyle(host, 'width', `${viewportWidth}px`);
1855
- this.renderer2.setStyle(host, 'height', `${viewportHeight}px`);
1856
- if (viewBox && viewBox[2] > 0 && viewBox[3] > 0) {
1857
- this.renderer2.setAttribute(host, 'viewBox', viewBox.join(' '));
1858
- }
1859
- }
1860
- updateViewportScrolling() {
1861
- const { viewportContainer, viewportState } = this;
1862
- const { scrollLeft, scrollTop } = viewportState;
1863
- viewportContainer.nativeElement.scrollLeft = scrollLeft;
1864
- viewportContainer.nativeElement.scrollTop = scrollTop;
1865
- }
1866
- setViewport() {
1867
- var _a, _b;
1868
- const viewport = (_a = this.board) === null || _a === void 0 ? void 0 : _a.viewport;
1869
- const oldOriginationCoord = (_b = viewport === null || viewport === void 0 ? void 0 : viewport.originationCoord) !== null && _b !== void 0 ? _b : [];
1870
- const matrix = this.getMatrix();
1871
- const originationCoord = invertViewportCoordinates([0, 0], matrix);
1872
- if (!originationCoord.every((item, index) => item === oldOriginationCoord[index])) {
1873
- Transforms.setViewport(this.board, Object.assign(Object.assign({}, viewport), { zoom: this.viewportState.zoom, originationCoord }));
1874
- }
1875
- }
1876
1924
  adaptHandle() {
1877
- const containerBox = getViewportContainerBox(this.board);
1878
- const rootGroup = this.host.firstChild;
1879
- const matrix = this.getMatrix();
1880
- const rootGroupBox = rootGroup.getBBox();
1881
- const centerPoint = [containerBox.width / 2, containerBox.height / 2];
1882
- const rootGroupCenterX = rootGroupBox.x + rootGroupBox.width / 2;
1883
- const rootGroupCenterY = rootGroupBox.y + rootGroupBox.height / 2;
1884
- const transformedPoint = transformMat3([], [rootGroupCenterX, rootGroupCenterY, 1], matrix);
1885
- const offsetLeft = centerPoint[0] - transformedPoint[0];
1886
- const offsetTop = centerPoint[1] - transformedPoint[1];
1887
- const { autoFitPadding, zoom, scrollLeft, scrollTop } = this.viewportState;
1888
- const viewportWidth = containerBox.width - 2 * autoFitPadding;
1889
- const viewportHeight = containerBox.height - 2 * autoFitPadding;
1890
- let newZoom = zoom;
1891
- if (viewportWidth < rootGroupBox.width || viewportHeight < rootGroupBox.height) {
1892
- newZoom = Math.min(viewportWidth / rootGroupBox.width, viewportHeight / rootGroupBox.height);
1893
- }
1894
- else {
1895
- newZoom = 1;
1896
- }
1897
- this.setScrollLeft(scrollLeft - offsetLeft);
1898
- this.setScrollTop(scrollTop - offsetTop);
1899
- this.calcViewBox(newZoom);
1900
- this.updateViewBoxStyles();
1901
- this.updateViewportScrolling();
1902
- this.setViewport();
1925
+ fitViewport(this.board);
1903
1926
  }
1904
- zoomInHandle() {
1905
- this.calcViewBox(this.viewportState.zoom + 0.1);
1906
- this.updateViewBoxStyles();
1907
- this.updateViewportScrolling();
1908
- this.setViewport();
1927
+ zoomInHandle(isCenter = true) {
1928
+ changeZoom(this.board, this.board.viewport.zoom + 0.1, isCenter);
1909
1929
  }
1910
1930
  zoomOutHandle() {
1911
- this.calcViewBox(this.viewportState.zoom - 0.1);
1912
- this.updateViewBoxStyles();
1913
- this.updateViewportScrolling();
1914
- this.setViewport();
1931
+ changeZoom(this.board, this.board.viewport.zoom - 0.1);
1915
1932
  }
1916
1933
  resetZoomHandel() {
1917
- this.calcViewBox(1);
1918
- this.updateViewBoxStyles();
1919
- this.updateViewportScrolling();
1920
- this.setViewport();
1934
+ changeZoom(this.board, 1);
1921
1935
  }
1922
1936
  ngOnDestroy() {
1937
+ var _a;
1923
1938
  this.destroy$.next();
1924
1939
  this.destroy$.complete();
1925
- if (this.resizeObserver) {
1926
- this.resizeObserver.disconnect();
1927
- }
1940
+ this.resizeObserver && ((_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect());
1928
1941
  BOARD_TO_ROUGH_SVG.delete(this.board);
1929
1942
  BOARD_TO_COMPONENT.delete(this.board);
1930
1943
  BOARD_TO_ROUGH_SVG.delete(this.board);
@@ -1935,41 +1948,9 @@ class PlaitBoardComponent {
1935
1948
  markForCheck() {
1936
1949
  this.cdr.markForCheck();
1937
1950
  }
1938
- scrollToRectangle(client) {
1939
- var _a;
1940
- this.calcViewBox();
1941
- this.updateViewBoxStyles();
1942
- this.updateViewportScrolling();
1943
- this.setViewport();
1944
- const svgRect = this.host.getBoundingClientRect();
1945
- const viewportContainerBox = getViewportContainerBox(this.board);
1946
- if (svgRect.width > viewportContainerBox.width || svgRect.height > viewportContainerBox.height) {
1947
- const scrollBarWidth = ((_a = this.plaitOptions) === null || _a === void 0 ? void 0 : _a.hideScrollbar) ? SCROLL_BAR_WIDTH : 0;
1948
- const matrix = this.getMatrix();
1949
- const [nodePointX, nodePointY] = convertToViewportCoordinates([client.x, client.y], matrix);
1950
- const [fullNodePointX, fullNodePointY] = convertToViewportCoordinates([client.x + client.width, client.y + client.height], matrix);
1951
- let newLeft = this.viewportState.scrollLeft;
1952
- let newTop = this.viewportState.scrollTop;
1953
- if (nodePointX < 0) {
1954
- newLeft -= Math.abs(nodePointX);
1955
- }
1956
- if (nodePointX > 0 && fullNodePointX > viewportContainerBox.width) {
1957
- newLeft += fullNodePointX - viewportContainerBox.width + scrollBarWidth;
1958
- }
1959
- if (nodePointY < 0) {
1960
- newTop -= Math.abs(nodePointY);
1961
- }
1962
- if (nodePointY > 0 && fullNodePointY > viewportContainerBox.height) {
1963
- newTop += fullNodePointY - viewportContainerBox.height + scrollBarWidth;
1964
- }
1965
- if (newLeft !== this.viewportState.scrollLeft || newTop !== this.viewportState.scrollTop) {
1966
- this.setScroll(newLeft, newTop);
1967
- }
1968
- }
1969
- }
1970
1951
  }
1971
- PlaitBoardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitBoardComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
1972
- PlaitBoardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: PlaitBoardComponent, selector: "plait-board", inputs: { plaitValue: "plaitValue", plaitViewport: "plaitViewport", plaitPlugins: "plaitPlugins", plaitOptions: "plaitOptions" }, outputs: { plaitChange: "plaitChange", plaitBoardInitialized: "plaitBoardInitialized" }, host: { properties: { "class": "this.hostClass", "class.readonly": "this.readonly", "class.focused": "this.focused" } }, queries: [{ propertyName: "toolbarTemplateRef", first: true, predicate: ["plaitToolbar"], descendants: true }], viewQueries: [{ propertyName: "svg", first: true, predicate: ["svg"], descendants: true, static: true }, { propertyName: "viewportContainer", first: true, predicate: ["viewportContainer"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
1952
+ PlaitBoardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitBoardComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
1953
+ PlaitBoardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: PlaitBoardComponent, selector: "plait-board", inputs: { plaitValue: "plaitValue", plaitViewport: "plaitViewport", plaitPlugins: "plaitPlugins", plaitOptions: "plaitOptions" }, outputs: { plaitChange: "plaitChange", plaitBoardInitialized: "plaitBoardInitialized" }, host: { properties: { "class": "this.hostClass", "class.readonly": "this.readonly", "class.focused": "this.isFocused" } }, queries: [{ propertyName: "toolbarTemplateRef", first: true, predicate: ["plaitToolbar"], descendants: true }], viewQueries: [{ propertyName: "svg", first: true, predicate: ["svg"], descendants: true, static: true }, { propertyName: "viewportContainer", first: true, predicate: ["viewportContainer"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
1973
1954
  <div class="viewport-container" #viewportContainer>
1974
1955
  <svg #svg width="100%" height="100%" style="position: relative;"><g class="element-host"></g></svg>
1975
1956
  <plait-element
@@ -1989,8 +1970,8 @@ PlaitBoardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", ve
1989
1970
  (resetZoomHandel)="resetZoomHandel()"
1990
1971
  ></plait-toolbar>
1991
1972
  <ng-content></ng-content>
1992
- `, isInline: true, components: [{ type: PlaitElementComponent, selector: "plait-element", inputs: ["index", "element", "board", "viewport", "selection"] }, { type: PlaitToolbarComponent, selector: "plait-toolbar", inputs: ["board"], outputs: ["adaptHandle", "zoomInHandle", "zoomOutHandle", "resetZoomHandel"] }], directives: [{ type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1993
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitBoardComponent, decorators: [{
1973
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PlaitElementComponent, selector: "plait-element", inputs: ["index", "element", "board", "viewport", "selection"] }, { kind: "component", type: PlaitToolbarComponent, selector: "plait-toolbar", inputs: ["board"], outputs: ["adaptHandle", "zoomInHandle", "zoomOutHandle", "resetZoomHandel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1974
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitBoardComponent, decorators: [{
1994
1975
  type: Component,
1995
1976
  args: [{
1996
1977
  selector: 'plait-board',
@@ -2017,7 +1998,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
2017
1998
  `,
2018
1999
  changeDetection: ChangeDetectionStrategy.OnPush
2019
2000
  }]
2020
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i0.ElementRef }]; }, propDecorators: { plaitValue: [{
2001
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { plaitValue: [{
2021
2002
  type: Input
2022
2003
  }], plaitViewport: [{
2023
2004
  type: Input
@@ -2035,7 +2016,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
2035
2016
  }], readonly: [{
2036
2017
  type: HostBinding,
2037
2018
  args: ['class.readonly']
2038
- }], focused: [{
2019
+ }], isFocused: [{
2039
2020
  type: HostBinding,
2040
2021
  args: ['class.focused']
2041
2022
  }], svg: [{
@@ -2057,11 +2038,6 @@ function hasBeforeContextChange(value) {
2057
2038
  }
2058
2039
 
2059
2040
  class PlaitPluginElementComponent {
2060
- constructor(cdr) {
2061
- this.cdr = cdr;
2062
- this.initialized = false;
2063
- this.g = createG();
2064
- }
2065
2041
  set context(value) {
2066
2042
  if (hasBeforeContextChange(this)) {
2067
2043
  this.beforeContextChange(value);
@@ -2091,6 +2067,11 @@ class PlaitPluginElementComponent {
2091
2067
  get board() {
2092
2068
  return this.context && this.context.board;
2093
2069
  }
2070
+ constructor(cdr) {
2071
+ this.cdr = cdr;
2072
+ this.initialized = false;
2073
+ this.g = createG();
2074
+ }
2094
2075
  onContextChange() {
2095
2076
  if (!this.initialized) {
2096
2077
  return;
@@ -2109,9 +2090,9 @@ class PlaitPluginElementComponent {
2109
2090
  this.g.remove();
2110
2091
  }
2111
2092
  }
2112
- PlaitPluginElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitPluginElementComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
2113
- PlaitPluginElementComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: PlaitPluginElementComponent, inputs: { context: "context" }, ngImport: i0 });
2114
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitPluginElementComponent, decorators: [{
2093
+ PlaitPluginElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitPluginElementComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
2094
+ PlaitPluginElementComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: PlaitPluginElementComponent, inputs: { context: "context" }, ngImport: i0 });
2095
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitPluginElementComponent, decorators: [{
2115
2096
  type: Directive
2116
2097
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { context: [{
2117
2098
  type: Input
@@ -2121,10 +2102,10 @@ const ELEMENT_TO_PLUGIN_COMPONENT = new WeakMap();
2121
2102
  const COMPONENTS = [PlaitBoardComponent, PlaitElementComponent, PlaitToolbarComponent];
2122
2103
  class PlaitModule {
2123
2104
  }
2124
- PlaitModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2125
- PlaitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitModule, declarations: [PlaitBoardComponent, PlaitElementComponent, PlaitToolbarComponent], imports: [BrowserModule], exports: [PlaitBoardComponent, PlaitElementComponent, PlaitToolbarComponent] });
2126
- PlaitModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitModule, imports: [[BrowserModule]] });
2127
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitModule, decorators: [{
2105
+ PlaitModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2106
+ PlaitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, declarations: [PlaitBoardComponent, PlaitElementComponent, PlaitToolbarComponent], imports: [BrowserModule], exports: [PlaitBoardComponent, PlaitElementComponent, PlaitToolbarComponent] });
2107
+ PlaitModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, imports: [BrowserModule] });
2108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, decorators: [{
2128
2109
  type: NgModule,
2129
2110
  args: [{
2130
2111
  declarations: [...COMPONENTS],
@@ -2133,6 +2114,88 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
2133
2114
  }]
2134
2115
  }] });
2135
2116
 
2117
+ function withMoving(board) {
2118
+ const { mousedown, mousemove, globalMouseup, globalMousemove } = board;
2119
+ let offsetX = 0;
2120
+ let offsetY = 0;
2121
+ let isPreventDefault = false;
2122
+ let startPoint;
2123
+ let activeElements = [];
2124
+ board.mousedown = event => {
2125
+ const host = BOARD_TO_HOST.get(board);
2126
+ const point = transformPoint(board, toPoint(event.x, event.y, host));
2127
+ const ranges = [{ anchor: point, focus: point }];
2128
+ let movableElements = board.children.filter(item => PlaitElement.isElement(item) && board.isMovable(item));
2129
+ if (movableElements.length) {
2130
+ startPoint = point;
2131
+ const selectedRootElements = getSelectedElements(board).filter(item => movableElements.includes(item));
2132
+ const intersectionSelectedElement = isIntersectionElements(board, selectedRootElements, ranges);
2133
+ if (intersectionSelectedElement) {
2134
+ activeElements = selectedRootElements;
2135
+ }
2136
+ else {
2137
+ activeElements = movableElements.filter(item => ranges.some(range => {
2138
+ return board.isIntersectionSelection(item, range);
2139
+ }));
2140
+ }
2141
+ }
2142
+ mousedown(event);
2143
+ };
2144
+ board.mousemove = event => {
2145
+ if (startPoint && (activeElements === null || activeElements === void 0 ? void 0 : activeElements.length)) {
2146
+ if (!isPreventDefault) {
2147
+ isPreventDefault = true;
2148
+ }
2149
+ const host = BOARD_TO_HOST.get(board);
2150
+ const endPoint = transformPoint(board, toPoint(event.x, event.y, host));
2151
+ offsetX = endPoint[0] - startPoint[0];
2152
+ offsetY = endPoint[1] - startPoint[1];
2153
+ throttleRAF(() => {
2154
+ const currentElements = activeElements.map(activeElement => {
2155
+ const [x, y] = activeElement === null || activeElement === void 0 ? void 0 : activeElement.points[0];
2156
+ const index = board.children.findIndex(item => item.id === activeElement.id);
2157
+ Transforms.setNode(board, {
2158
+ points: [[x + offsetX, y + offsetY]]
2159
+ }, [index]);
2160
+ MERGING.set(board, true);
2161
+ return PlaitNode.get(board, [index]);
2162
+ });
2163
+ addMovingElements(board, currentElements);
2164
+ });
2165
+ }
2166
+ if (isPreventDefault) {
2167
+ // 阻止 move 过程中触发画布滚动行为
2168
+ event.preventDefault();
2169
+ }
2170
+ mousemove(event);
2171
+ };
2172
+ board.globalMousemove = event => {
2173
+ if (startPoint) {
2174
+ const inPliatBordElement = isInPlaitBoard(board, event.x, event.y);
2175
+ if (!inPliatBordElement) {
2176
+ cancelMove(board);
2177
+ }
2178
+ }
2179
+ globalMousemove(event);
2180
+ };
2181
+ board.globalMouseup = event => {
2182
+ isPreventDefault = false;
2183
+ if (startPoint) {
2184
+ cancelMove(board);
2185
+ }
2186
+ globalMouseup(event);
2187
+ };
2188
+ function cancelMove(board) {
2189
+ startPoint = null;
2190
+ offsetX = 0;
2191
+ offsetY = 0;
2192
+ activeElements = [];
2193
+ removeMovingElements(board);
2194
+ MERGING.set(board, false);
2195
+ }
2196
+ return board;
2197
+ }
2198
+
2136
2199
  /*
2137
2200
  * Public API Surface of plait
2138
2201
  */
@@ -2141,5 +2204,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
2141
2204
  * Generated bundle index. Do not edit.
2142
2205
  */
2143
2206
 
2144
- export { BOARD_TO_COMPONENT, BOARD_TO_ELEMENT_HOST, BOARD_TO_HOST, BOARD_TO_MOVING_POINT, BOARD_TO_ON_CHANGE, BOARD_TO_ROUGH_SVG, BOARD_TO_SELECTED_ELEMENT, BOARD_TO_TEMPORARY_ELEMENTS, BoardTransforms, CLIP_BOARD_FORMAT_KEY, ELEMENT_TO_PLUGIN_COMPONENT, FLUSHING, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_SAFARI, IS_TEXT_EDITABLE, MAX_RADIUS, MERGING, NS, Path, PlaitBoard, PlaitBoardComponent, PlaitElement, PlaitElementComponent, PlaitHistoryBoard, PlaitModule, PlaitNode, PlaitOperation, PlaitPluginElementComponent, PlaitPointerType, PlaitToolbarComponent, RectangleClient, SAVING, SCROLL_BAR_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, Selection, Transforms, Viewport, addSelectedElement, arrowPoints, cacheSelectedElements, calcElementIntersectionSelection, clampZoomLevel, convertToViewportCoordinates, createG, createSVG, createText, deleteTemporaryElements, depthFirstRecursion, distanceBetweenPointAndPoint, distanceBetweenPointAndRectangle, distanceBetweenPointAndSegment, drawArrow, drawRoundRectangle, getBoardClientBox, getBoardRectangle, getRectangleByElements, getRootGroupBBox, getSelectedElements, getTemporaryElements, getViewportContainerBox, hasBeforeContextChange, hotkeys, idCreator, inverse, invertMatrix, invertViewportCoordinates, isNoSelectionElement, isNullOrUndefined, isSelectedElement, isSetViewportOperation, normalizePoint, removeSelectedElement, rotate, shouldClear, shouldMerge, shouldSave, toPoint, transformMat3, transformPoint, transformPoints, withSelection };
2207
+ export { BOARD_TO_COMPONENT, BOARD_TO_ELEMENT_HOST, BOARD_TO_HOST, BOARD_TO_IS_SELECTION_MOVING, BOARD_TO_MOVING_ELEMENT, BOARD_TO_MOVING_POINT, BOARD_TO_ON_CHANGE, BOARD_TO_ROUGH_SVG, BOARD_TO_SCROLLING, BOARD_TO_SELECTED_ELEMENT, BOARD_TO_TEMPORARY_ELEMENTS, BOARD_TO_VIEWPORT_ORIGINATION, BoardTransforms, CLIP_BOARD_FORMAT_KEY, ELEMENT_TO_PLUGIN_COMPONENT, FLUSHING, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_SAFARI, IS_TEXT_EDITABLE, MAX_RADIUS, MERGING, NS, Path, PlaitBoard, PlaitBoardComponent, PlaitElement, PlaitElementComponent, PlaitHistoryBoard, PlaitModule, PlaitNode, PlaitOperation, PlaitPluginElementComponent, PlaitPointerType, PlaitToolbarComponent, Point, RectangleClient, SAVING, SCROLL_BAR_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, Selection, Transforms, Viewport, addMovingElements, addSelectedElement, arrowPoints, cacheMovingElements, cacheSelectedElements, calcElementIntersectionSelection, changeZoom, clampZoomLevel, clearSelectionMoving, clearViewportOrigination, clearViewportScrolling, createG, createSVG, createText, deleteTemporaryElements, depthFirstRecursion, distanceBetweenPointAndPoint, distanceBetweenPointAndRectangle, distanceBetweenPointAndSegment, drawArrow, drawRoundRectangle, fitViewport, getBoardRectangle, getElementHostBBox, getMovingElements, getRectangleByElements, getSelectedElements, getTemporaryElements, getViewBox, getViewportContainerRect, getViewportOrigination, hasBeforeContextChange, hotkeys, idCreator, initializeViewBox, initializeViewportContainer, initializeViewportOffset, inverse, isInPlaitBoard, isIntersectionElements, isNullOrUndefined, isSelectedElement, isSelectionMoving, isSetViewportOperation, isViewportScrolling, normalizePoint, removeMovingElements, removeSelectedElement, rotate, scrollToRectangle, setSVGViewBox, setSelectionMoving, setViewport, setViewportScrolling, shouldClear, shouldMerge, shouldSave, throttleRAF, toPoint, transformPoint, transformPoints, updateViewportContainerScroll, updateViewportOffset, updateViewportOrigination, withMoving, withSelection };
2145
2208
  //# sourceMappingURL=plait-core.mjs.map