@plait/core 0.2.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/board/board.component.d.ts +11 -10
  2. package/board/board.component.interface.d.ts +2 -1
  3. package/constants/index.d.ts +6 -0
  4. package/core/island/island-base.component.d.ts +16 -0
  5. package/esm2020/board/board.component.interface.mjs +1 -1
  6. package/esm2020/board/board.component.mjs +52 -55
  7. package/esm2020/constants/index.mjs +7 -1
  8. package/esm2020/core/element/plugin-element.mjs +2 -2
  9. package/esm2020/core/island/island-base.component.mjs +33 -0
  10. package/esm2020/interfaces/board.mjs +11 -2
  11. package/esm2020/interfaces/index.mjs +2 -1
  12. package/esm2020/interfaces/node.mjs +1 -1
  13. package/esm2020/interfaces/path-ref.mjs +15 -0
  14. package/esm2020/interfaces/plugin-key.mjs +5 -0
  15. package/esm2020/plait.module.mjs +3 -4
  16. package/esm2020/plugins/create-board.mjs +32 -3
  17. package/esm2020/plugins/with-hand.mjs +10 -15
  18. package/esm2020/plugins/with-options.mjs +13 -0
  19. package/esm2020/plugins/with-selection.mjs +27 -17
  20. package/esm2020/public-api.mjs +4 -2
  21. package/esm2020/testing/core/create-board.mjs +13 -0
  22. package/esm2020/testing/core/fake-weak-map.mjs +18 -0
  23. package/esm2020/testing/core/index.mjs +3 -0
  24. package/esm2020/testing/index.mjs +2 -0
  25. package/esm2020/transforms/board.mjs +63 -4
  26. package/esm2020/utils/dom/common.mjs +12 -1
  27. package/esm2020/utils/draw/line.mjs +21 -1
  28. package/esm2020/utils/selected-element.mjs +5 -3
  29. package/esm2020/utils/viewport.mjs +2 -55
  30. package/esm2020/utils/weak-maps.mjs +2 -1
  31. package/fesm2015/plait-core.mjs +621 -507
  32. package/fesm2015/plait-core.mjs.map +1 -1
  33. package/fesm2020/plait-core.mjs +635 -521
  34. package/fesm2020/plait-core.mjs.map +1 -1
  35. package/interfaces/board.d.ts +8 -2
  36. package/interfaces/index.d.ts +1 -0
  37. package/interfaces/node.d.ts +1 -1
  38. package/interfaces/path-ref.d.ts +13 -0
  39. package/interfaces/plugin-key.d.ts +3 -0
  40. package/package.json +3 -3
  41. package/plait.module.d.ts +2 -3
  42. package/plugins/create-board.d.ts +1 -1
  43. package/plugins/with-options.d.ts +9 -0
  44. package/plugins/with-selection.d.ts +4 -0
  45. package/public-api.d.ts +3 -1
  46. package/styles/styles.scss +0 -73
  47. package/testing/core/create-board.d.ts +6 -0
  48. package/testing/core/fake-weak-map.d.ts +4 -0
  49. package/testing/core/index.d.ts +2 -0
  50. package/testing/index.d.ts +1 -0
  51. package/transforms/board.d.ts +9 -2
  52. package/utils/dom/common.d.ts +3 -0
  53. package/utils/draw/line.d.ts +1 -0
  54. package/utils/selected-element.d.ts +2 -2
  55. package/utils/viewport.d.ts +0 -3
  56. package/utils/weak-maps.d.ts +2 -0
  57. package/core/toolbar/toolbar.component.d.ts +0 -21
  58. package/esm2020/core/toolbar/toolbar.component.mjs +0 -60
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, Input, Component, ChangeDetectionStrategy, EventEmitter, HostBinding, Output, ElementRef, ViewChild, ContentChild, NgModule } from '@angular/core';
2
+ import { Directive, Input, Component, ChangeDetectionStrategy, EventEmitter, ElementRef, Output, HostBinding, ViewChild, ContentChildren, NgModule } from '@angular/core';
3
3
  import rough from 'roughjs/bin/rough';
4
4
  import { timer, Subject, fromEvent } from 'rxjs';
5
- import { takeUntil, filter } from 'rxjs/operators';
5
+ import { takeUntil, filter, tap } 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';
@@ -26,6 +26,7 @@ const BOARD_TO_IS_SELECTION_MOVING = new WeakMap();
26
26
  // save no standard selected elements
27
27
  const BOARD_TO_TEMPORARY_ELEMENTS = new WeakMap();
28
28
  const BOARD_TO_MOVING_ELEMENT = new WeakMap();
29
+ const PATH_REFS = new WeakMap();
29
30
 
30
31
  function depthFirstRecursion(node, callback, recursion) {
31
32
  var _a;
@@ -133,6 +134,15 @@ const PlaitBoard = {
133
134
  },
134
135
  hasBeenTextEditing(board) {
135
136
  return !!IS_TEXT_EDITABLE.get(board);
137
+ },
138
+ getPointer(board) {
139
+ return board.pointer;
140
+ },
141
+ isPointer(board, pointer) {
142
+ return board.pointer === pointer;
143
+ },
144
+ getMovingPoint(board) {
145
+ return BOARD_TO_MOVING_POINT.get(board);
136
146
  }
137
147
  };
138
148
 
@@ -570,12 +580,74 @@ function setSelectionWithTemporaryElements(board, elements) {
570
580
  });
571
581
  }
572
582
 
573
- function setViewport$1(board, viewport) {
583
+ function setViewport(board, viewport) {
574
584
  const operation = { type: 'set_viewport', properties: board.viewport, newProperties: viewport };
575
585
  board.apply(operation);
576
586
  }
577
587
  const ViewportTransforms = {
578
- setViewport: setViewport$1
588
+ setViewport
589
+ };
590
+
591
+ const CLIP_BOARD_FORMAT_KEY = 'x-plait-fragment';
592
+ const SCROLL_BAR_WIDTH = 20;
593
+ const MAX_RADIUS = 16;
594
+ const POINTER_BUTTON = {
595
+ MAIN: 0,
596
+ WHEEL: 1,
597
+ SECONDARY: 2,
598
+ TOUCH: -1,
599
+ };
600
+
601
+ const NS = 'http://www.w3.org/2000/svg';
602
+ function toPoint(x, y, container) {
603
+ const rect = container.getBoundingClientRect();
604
+ return [x - rect.x, y - rect.y];
605
+ }
606
+ function createG() {
607
+ const newG = document.createElementNS(NS, 'g');
608
+ return newG;
609
+ }
610
+ function createPath() {
611
+ const newG = document.createElementNS(NS, 'path');
612
+ return newG;
613
+ }
614
+ function createSVG() {
615
+ const svg = document.createElementNS(NS, 'svg');
616
+ return svg;
617
+ }
618
+ function createText(x, y, fill, textContent) {
619
+ var text = document.createElementNS(NS, 'text');
620
+ text.setAttribute('x', `${x}`);
621
+ text.setAttribute('y', `${y}`);
622
+ text.setAttribute('fill', fill);
623
+ text.textContent = textContent;
624
+ return text;
625
+ }
626
+ /**
627
+ * Check if a DOM node is an element node.
628
+ */
629
+ const isDOMElement = (value) => {
630
+ return isDOMNode(value) && value.nodeType === 1;
631
+ };
632
+ /**
633
+ * Check if a value is a DOM node.
634
+ */
635
+ const isDOMNode = (value) => {
636
+ return value instanceof window.Node;
637
+ };
638
+ const hasInputOrTextareaTarget = (target) => {
639
+ if (isDOMElement(target)) {
640
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
641
+ return true;
642
+ }
643
+ }
644
+ return false;
645
+ };
646
+ const isSecondaryPointer = (event) => {
647
+ return event.button === POINTER_BUTTON.SECONDARY;
648
+ };
649
+ const isMainPointer = (event) => {
650
+ return event.button === POINTER_BUTTON.MAIN;
579
651
  };
580
652
 
581
653
  // https://stackoverflow.com/a/6853926/232122
@@ -626,108 +698,15 @@ function distanceBetweenPointAndRectangle(x, y, rect) {
626
698
  return Math.sqrt(dx * dx + dy * dy);
627
699
  }
628
700
 
629
- function transformPoints(board, points) {
630
- const newPoints = points.map(point => {
631
- return transformPoint(board, point);
632
- });
633
- return newPoints;
634
- }
635
- function transformPoint(board, point) {
636
- const { width, height } = PlaitBoard.getHost(board).getBoundingClientRect();
637
- const viewBox = PlaitBoard.getHost(board).viewBox.baseVal;
638
- const x = (point[0] / width) * viewBox.width + viewBox.x;
639
- const y = (point[1] / height) * viewBox.height + viewBox.y;
640
- const newPoint = [x, y];
641
- return newPoint;
642
- }
643
- function isInPlaitBoard(board, x, y) {
644
- const plaitBoardElement = PlaitBoard.getBoardNativeElement(board);
645
- const plaitBoardRect = plaitBoardElement.getBoundingClientRect();
646
- const distances = distanceBetweenPointAndRectangle(x, y, plaitBoardRect);
647
- return distances === 0;
648
- }
649
-
650
- const NS = 'http://www.w3.org/2000/svg';
651
- function toPoint(x, y, container) {
652
- const rect = container.getBoundingClientRect();
653
- return [x - rect.x, y - rect.y];
654
- }
655
- function createG() {
656
- const newG = document.createElementNS(NS, 'g');
657
- return newG;
658
- }
659
- function createSVG() {
660
- const svg = document.createElementNS(NS, 'svg');
661
- return svg;
662
- }
663
- function createText(x, y, fill, textContent) {
664
- var text = document.createElementNS(NS, 'text');
665
- text.setAttribute('x', `${x}`);
666
- text.setAttribute('y', `${y}`);
667
- text.setAttribute('fill', fill);
668
- text.textContent = textContent;
669
- return text;
670
- }
671
- /**
672
- * Check if a DOM node is an element node.
673
- */
674
- const isDOMElement = (value) => {
675
- return isDOMNode(value) && value.nodeType === 1;
676
- };
677
- /**
678
- * Check if a value is a DOM node.
679
- */
680
- const isDOMNode = (value) => {
681
- return value instanceof window.Node;
682
- };
683
- const hasInputOrTextareaTarget = (target) => {
684
- if (isDOMElement(target)) {
685
- if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
686
- return true;
687
- }
688
- }
689
- return false;
690
- };
691
-
692
- function createForeignObject(x, y, width, height) {
693
- var newForeignObject = document.createElementNS(NS, 'foreignObject');
694
- newForeignObject.setAttribute('x', `${x}`);
695
- newForeignObject.setAttribute('y', `${y}`);
696
- newForeignObject.setAttribute('width', `${width}`);
697
- newForeignObject.setAttribute('height', `${height}`);
698
- return newForeignObject;
699
- }
700
- function updateForeignObject(g, width, height, x, y) {
701
- const foreignObject = g.querySelector('foreignObject');
702
- if (foreignObject) {
703
- foreignObject.setAttribute('width', `${width}`);
704
- foreignObject.setAttribute('height', `${height}`);
705
- foreignObject.setAttribute('x', `${x}`);
706
- foreignObject.setAttribute('y', `${y}`);
707
- }
708
- }
709
-
710
- const IS_IOS = typeof navigator !== 'undefined' &&
711
- typeof window !== 'undefined' &&
712
- /iPad|iPhone|iPod/.test(navigator.userAgent) &&
713
- !window.MSStream;
714
- const IS_APPLE = typeof navigator !== 'undefined' && /Mac OS X/.test(navigator.userAgent);
715
- const IS_FIREFOX = typeof navigator !== 'undefined' && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
716
- const IS_SAFARI = typeof navigator !== 'undefined' && /Version\/[\d\.]+.*Safari/.test(navigator.userAgent);
717
- // "modern" Edge was released at 79.x
718
- const IS_EDGE_LEGACY = typeof navigator !== 'undefined' && /Edge?\/(?:[0-6][0-9]|[0-7][0-8])/i.test(navigator.userAgent);
719
- const IS_CHROME = typeof navigator !== 'undefined' && /Chrome/i.test(navigator.userAgent);
720
- // Native beforeInput events don't work well with react on Chrome 75 and older, Chrome 76+ can use beforeInput
721
- const IS_CHROME_LEGACY = typeof navigator !== 'undefined' && /Chrome?\/(?:[0-7][0-5]|[0-6][0-9])/i.test(navigator.userAgent);
722
-
723
- const getHitElements = (board) => {
701
+ const getHitElements = (board, selection) => {
702
+ const realSelection = selection || board.selection;
724
703
  const selectedElements = [];
725
704
  depthFirstRecursion(board, node => {
726
- var _a;
727
705
  if (!PlaitBoard.isBoard(node) &&
728
- ((_a = board.selection) === null || _a === void 0 ? void 0 : _a.ranges.some(range => {
706
+ realSelection &&
707
+ realSelection.ranges.some(range => {
729
708
  return board.isHitSelection(node, range);
730
- }))) {
709
+ })) {
731
710
  selectedElements.push(node);
732
711
  }
733
712
  }, node => {
@@ -806,7 +785,7 @@ class PlaitPluginElementComponent {
806
785
  }
807
786
  }
808
787
  else {
809
- if (PlaitElement.isRootElement(this.element) && this.element.children && this.element.children.length > 0) {
788
+ if (PlaitElement.isRootElement(this.element) && this.element.children) {
810
789
  this.g = createG();
811
790
  this.rootG = createG();
812
791
  this.rootG.append(this.g);
@@ -858,158 +837,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
858
837
  }] } });
859
838
  const ELEMENT_TO_COMPONENT = new WeakMap();
860
839
 
861
- const PlaitElement = {
862
- isRootElement(value) {
863
- const parent = NODE_TO_PARENT.get(value);
864
- if (parent && PlaitBoard.isBoard(parent)) {
865
- return true;
866
- }
867
- else {
868
- return false;
869
- }
870
- },
871
- getComponent(value) {
872
- return ELEMENT_TO_COMPONENT.get(value);
840
+ function transformPoints(board, points) {
841
+ const newPoints = points.map(point => {
842
+ return transformPoint(board, point);
843
+ });
844
+ return newPoints;
845
+ }
846
+ function transformPoint(board, point) {
847
+ const { width, height } = PlaitBoard.getHost(board).getBoundingClientRect();
848
+ const viewBox = PlaitBoard.getHost(board).viewBox.baseVal;
849
+ const x = (point[0] / width) * viewBox.width + viewBox.x;
850
+ const y = (point[1] / height) * viewBox.height + viewBox.y;
851
+ const newPoint = [x, y];
852
+ return newPoint;
853
+ }
854
+ function isInPlaitBoard(board, x, y) {
855
+ const plaitBoardElement = PlaitBoard.getBoardNativeElement(board);
856
+ const plaitBoardRect = plaitBoardElement.getBoundingClientRect();
857
+ const distances = distanceBetweenPointAndRectangle(x, y, plaitBoardRect);
858
+ return distances === 0;
859
+ }
860
+
861
+ function createForeignObject(x, y, width, height) {
862
+ var newForeignObject = document.createElementNS(NS, 'foreignObject');
863
+ newForeignObject.setAttribute('x', `${x}`);
864
+ newForeignObject.setAttribute('y', `${y}`);
865
+ newForeignObject.setAttribute('width', `${width}`);
866
+ newForeignObject.setAttribute('height', `${height}`);
867
+ return newForeignObject;
868
+ }
869
+ function updateForeignObject(g, width, height, x, y) {
870
+ const foreignObject = g.querySelector('foreignObject');
871
+ if (foreignObject) {
872
+ foreignObject.setAttribute('width', `${width}`);
873
+ foreignObject.setAttribute('height', `${height}`);
874
+ foreignObject.setAttribute('x', `${x}`);
875
+ foreignObject.setAttribute('y', `${y}`);
873
876
  }
874
- };
877
+ }
875
878
 
876
- const RectangleClient = {
877
- isHit: (origin, target) => {
878
- const minX = origin.x < target.x ? origin.x : target.x;
879
- const maxX = origin.x + origin.width > target.x + target.width ? origin.x + origin.width : target.x + target.width;
880
- const minY = origin.y < target.y ? origin.y : target.y;
881
- const maxY = origin.y + origin.height > target.y + target.height ? origin.y + origin.height : target.y + target.height;
882
- // float calculate error( eg: 1.4210854715202004e-14 > 0)
883
- if (Math.floor(maxX - minX - origin.width - target.width) <= 0 && Math.floor(maxY - minY - origin.height - target.height) <= 0) {
884
- return true;
885
- }
886
- else {
887
- return false;
888
- }
889
- },
890
- toRectangleClient: (points) => {
891
- const xArray = points.map(ele => ele[0]);
892
- const yArray = points.map(ele => ele[1]);
893
- const xMin = Math.min(...xArray);
894
- const xMax = Math.max(...xArray);
895
- const yMin = Math.min(...yArray);
896
- const yMax = Math.max(...yArray);
897
- const rect = { x: xMin, y: yMin, width: xMax - xMin, height: yMax - yMin };
898
- return rect;
899
- },
900
- getOutlineRectangle: (rectangle, offset) => {
901
- return {
902
- x: rectangle.x + offset,
903
- y: rectangle.y + offset,
904
- width: rectangle.width + Math.abs(offset) * 2,
905
- height: rectangle.height + Math.abs(offset) * 2
906
- };
907
- },
908
- isEqual: (rectangle, otherRectangle) => {
909
- return (rectangle.x === otherRectangle.x &&
910
- rectangle.y === otherRectangle.y &&
911
- rectangle.width === otherRectangle.width &&
912
- rectangle.height === otherRectangle.height);
879
+ const IS_IOS = typeof navigator !== 'undefined' &&
880
+ typeof window !== 'undefined' &&
881
+ /iPad|iPhone|iPod/.test(navigator.userAgent) &&
882
+ !window.MSStream;
883
+ const IS_APPLE = typeof navigator !== 'undefined' && /Mac OS X/.test(navigator.userAgent);
884
+ const IS_FIREFOX = typeof navigator !== 'undefined' && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
885
+ const IS_SAFARI = typeof navigator !== 'undefined' && /Version\/[\d\.]+.*Safari/.test(navigator.userAgent);
886
+ // "modern" Edge was released at 79.x
887
+ const IS_EDGE_LEGACY = typeof navigator !== 'undefined' && /Edge?\/(?:[0-6][0-9]|[0-7][0-8])/i.test(navigator.userAgent);
888
+ const IS_CHROME = typeof navigator !== 'undefined' && /Chrome/i.test(navigator.userAgent);
889
+ // Native beforeInput events don't work well with react on Chrome 75 and older, Chrome 76+ can use beforeInput
890
+ const IS_CHROME_LEGACY = typeof navigator !== 'undefined' && /Chrome?\/(?:[0-7][0-5]|[0-6][0-9])/i.test(navigator.userAgent);
891
+
892
+ /**
893
+ * Check whether to merge an operation into the previous operation.
894
+ */
895
+ const shouldMerge = (op, prev) => {
896
+ if (op.type === 'set_viewport' && op.type === (prev === null || prev === void 0 ? void 0 : prev.type)) {
897
+ return true;
913
898
  }
914
- };
915
-
916
- const isSetViewportOperation = (value) => {
917
- return value.type === 'set_viewport';
918
- };
919
- const inverse = (op) => {
920
- switch (op.type) {
921
- case 'insert_node': {
922
- return Object.assign(Object.assign({}, op), { type: 'remove_node' });
923
- }
924
- case 'remove_node': {
925
- return Object.assign(Object.assign({}, op), { type: 'insert_node' });
926
- }
927
- case 'move_node': {
928
- const { newPath, path } = op;
929
- // PERF: in this case the move operation is a no-op anyways.
930
- if (Path.equals(newPath, path)) {
931
- return op;
932
- }
933
- // when operation path is [0,0] -> [0,2], should exec Path.transform to get [0,1] -> [0,0]
934
- // shoud not return [0,2] -> [0,0] #WIK-8981
935
- // if (Path.isSibling(path, newPath)) {
936
- // return { ...op, path: newPath, newPath: path };
937
- // }
938
- // If the move does not happen within a single parent it is possible
939
- // for the move to impact the true path to the location where the node
940
- // was removed from and where it was inserted. We have to adjust for this
941
- // and find the original path. We can accomplish this (only in non-sibling)
942
- // moves by looking at the impact of the move operation on the node
943
- // after the original move path.
944
- const inversePath = Path.transform(path, op);
945
- const inverseNewPath = Path.transform(Path.next(path), op);
946
- return Object.assign(Object.assign({}, op), { path: inversePath, newPath: inverseNewPath });
947
- }
948
- case 'set_node': {
949
- const { properties, newProperties } = op;
950
- return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
951
- }
952
- case 'set_selection': {
953
- const { properties, newProperties } = op;
954
- if (properties == null) {
955
- return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: null });
956
- }
957
- else if (newProperties == null) {
958
- return Object.assign(Object.assign({}, op), { properties: null, newProperties: properties });
959
- }
960
- else {
961
- return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
962
- }
963
- }
964
- case 'set_viewport': {
965
- const { properties, newProperties } = op;
966
- if (properties == null) {
967
- return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: newProperties });
968
- }
969
- else if (newProperties == null) {
970
- return Object.assign(Object.assign({}, op), { properties: properties, newProperties: properties });
971
- }
972
- else {
973
- return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
974
- }
975
- }
976
- }
977
- };
978
- const PlaitOperation = {
979
- isSetViewportOperation,
980
- inverse
981
- };
982
-
983
- const Point = {
984
- isEquals(point, otherPoint) {
985
- return point && otherPoint && point[0] === otherPoint[0] && point[1] === otherPoint[1];
986
- }
987
- };
988
-
989
- const SELECTION_BORDER_COLOR = '#6698FF';
990
- const SELECTION_FILL_COLOR = '#6698FF19'; // 主色 0.1 透明度
991
- const Selection = {
992
- isCollapsed(selection) {
993
- if (selection.anchor[0] == selection.focus[0] && selection.anchor[1] === selection.focus[1]) {
994
- return true;
995
- }
996
- else {
997
- return false;
998
- }
999
- }
1000
- };
1001
-
1002
- const SAVING = new WeakMap();
1003
- const MERGING = new WeakMap();
1004
-
1005
- /**
1006
- * Check whether to merge an operation into the previous operation.
1007
- */
1008
- const shouldMerge = (op, prev) => {
1009
- if (op.type === 'set_viewport' && op.type === (prev === null || prev === void 0 ? void 0 : prev.type)) {
1010
- return true;
1011
- }
1012
- return false;
899
+ return false;
1013
900
  };
1014
901
  /**
1015
902
  * Check whether an operation needs to be saved to the history.
@@ -1170,10 +1057,6 @@ function idCreator(length = 5) {
1170
1057
  return key;
1171
1058
  }
1172
1059
 
1173
- const CLIP_BOARD_FORMAT_KEY = 'x-plait-fragment';
1174
- const SCROLL_BAR_WIDTH = 20;
1175
- const MAX_RADIUS = 16;
1176
-
1177
1060
  /**
1178
1061
  * drawRoundRectangle
1179
1062
  */
@@ -1236,37 +1119,252 @@ function drawAbstractRoundRectangle(rs, x1, y1, x2, y2, isHorizontal, options) {
1236
1119
  l0,-${handleSideLine}
1237
1120
  a${radius},${radius},0,0,1,${radius},-${radius}`, options);
1238
1121
  }
1239
- }
1122
+ }
1123
+
1124
+ function arrowPoints(start, end, maxHypotenuseLength = 10, degree = 40) {
1125
+ const width = Math.abs(start[0] - end[0]);
1126
+ const height = Math.abs(start[1] - end[1]);
1127
+ let hypotenuse = Math.hypot(width, height); // 斜边
1128
+ const realRotateLine = hypotenuse > maxHypotenuseLength * 2 ? maxHypotenuseLength : hypotenuse / 2;
1129
+ const rotateWidth = (realRotateLine / hypotenuse) * width;
1130
+ const rotateHeight = (realRotateLine / hypotenuse) * height;
1131
+ const rotatePoint = [
1132
+ end[0] > start[0] ? end[0] - rotateWidth : end[0] + rotateWidth,
1133
+ end[1] > start[1] ? end[1] - rotateHeight : end[1] + rotateHeight
1134
+ ];
1135
+ const pointRight = rotate(rotatePoint[0], rotatePoint[1], end[0], end[1], (degree * Math.PI) / 180);
1136
+ const pointLeft = rotate(rotatePoint[0], rotatePoint[1], end[0], end[1], (-degree * Math.PI) / 180);
1137
+ return { pointLeft, pointRight };
1138
+ }
1139
+ function drawArrow(rs, start, end, options, maxHypotenuseLength = 10, degree = 40) {
1140
+ const { pointLeft, pointRight } = arrowPoints(start, end, maxHypotenuseLength, degree);
1141
+ const arrowLineLeft = rs.linearPath([pointLeft, end], options);
1142
+ const arrowLineRight = rs.linearPath([pointRight, end], options);
1143
+ return [arrowLineLeft, arrowLineRight];
1144
+ }
1145
+
1146
+ function drawCircle(roughSVG, point, diameter, options) {
1147
+ return roughSVG.circle(point[0], point[1], diameter, options);
1148
+ }
1149
+
1150
+ function drawLine(rs, start, end, options) {
1151
+ return rs.linearPath([start, end], options);
1152
+ }
1153
+ function drawLinearPath(points, options) {
1154
+ const g = createG();
1155
+ const path = createPath();
1156
+ let polylinePath = '';
1157
+ points.forEach((point, index) => {
1158
+ if (index === 0) {
1159
+ polylinePath += `M ${point[0]} ${point[1]} `;
1160
+ }
1161
+ else {
1162
+ polylinePath += `L ${point[0]} ${point[1]} `;
1163
+ }
1164
+ });
1165
+ path.setAttribute('d', polylinePath);
1166
+ path.setAttribute('stroke', `${options === null || options === void 0 ? void 0 : options.stroke}`);
1167
+ path.setAttribute('stroke-width', `${options === null || options === void 0 ? void 0 : options.strokeWidth}`);
1168
+ path.setAttribute('fill', `none`);
1169
+ g.appendChild(path);
1170
+ return g;
1171
+ }
1172
+
1173
+ let timerId = null;
1174
+ const throttleRAF = (fn) => {
1175
+ const scheduleFunc = () => {
1176
+ timerId = requestAnimationFrame(() => {
1177
+ timerId = null;
1178
+ fn();
1179
+ });
1180
+ };
1181
+ if (timerId !== null) {
1182
+ cancelAnimationFrame(timerId);
1183
+ timerId = null;
1184
+ }
1185
+ scheduleFunc();
1186
+ };
1187
+ const debounce = (func, wait, options) => {
1188
+ let timerSubscription = null;
1189
+ return () => {
1190
+ if (timerSubscription && !timerSubscription.closed) {
1191
+ timerSubscription.unsubscribe();
1192
+ timerSubscription = timer(wait).subscribe(() => {
1193
+ func();
1194
+ });
1195
+ }
1196
+ else {
1197
+ if (options === null || options === void 0 ? void 0 : options.leading) {
1198
+ func();
1199
+ }
1200
+ timerSubscription = timer(wait).subscribe();
1201
+ }
1202
+ };
1203
+ };
1204
+
1205
+ const getMovingElements = (board) => {
1206
+ return BOARD_TO_MOVING_ELEMENT.get(board) || [];
1207
+ };
1208
+ const addMovingElements = (board, elements) => {
1209
+ const movingElements = getMovingElements(board);
1210
+ const newElements = elements.filter(item => !movingElements.find(movingElement => movingElement.key === item.key));
1211
+ cacheMovingElements(board, [...movingElements, ...newElements]);
1212
+ };
1213
+ const removeMovingElements = (board) => {
1214
+ BOARD_TO_MOVING_ELEMENT.delete(board);
1215
+ };
1216
+ const cacheMovingElements = (board, elements) => {
1217
+ BOARD_TO_MOVING_ELEMENT.set(board, elements);
1218
+ };
1219
+
1220
+ const PlaitElement = {
1221
+ isRootElement(value) {
1222
+ const parent = NODE_TO_PARENT.get(value);
1223
+ if (parent && PlaitBoard.isBoard(parent)) {
1224
+ return true;
1225
+ }
1226
+ else {
1227
+ return false;
1228
+ }
1229
+ },
1230
+ getComponent(value) {
1231
+ return ELEMENT_TO_COMPONENT.get(value);
1232
+ }
1233
+ };
1234
+
1235
+ const RectangleClient = {
1236
+ isHit: (origin, target) => {
1237
+ const minX = origin.x < target.x ? origin.x : target.x;
1238
+ const maxX = origin.x + origin.width > target.x + target.width ? origin.x + origin.width : target.x + target.width;
1239
+ const minY = origin.y < target.y ? origin.y : target.y;
1240
+ const maxY = origin.y + origin.height > target.y + target.height ? origin.y + origin.height : target.y + target.height;
1241
+ // float calculate error( eg: 1.4210854715202004e-14 > 0)
1242
+ if (Math.floor(maxX - minX - origin.width - target.width) <= 0 && Math.floor(maxY - minY - origin.height - target.height) <= 0) {
1243
+ return true;
1244
+ }
1245
+ else {
1246
+ return false;
1247
+ }
1248
+ },
1249
+ toRectangleClient: (points) => {
1250
+ const xArray = points.map(ele => ele[0]);
1251
+ const yArray = points.map(ele => ele[1]);
1252
+ const xMin = Math.min(...xArray);
1253
+ const xMax = Math.max(...xArray);
1254
+ const yMin = Math.min(...yArray);
1255
+ const yMax = Math.max(...yArray);
1256
+ const rect = { x: xMin, y: yMin, width: xMax - xMin, height: yMax - yMin };
1257
+ return rect;
1258
+ },
1259
+ getOutlineRectangle: (rectangle, offset) => {
1260
+ return {
1261
+ x: rectangle.x + offset,
1262
+ y: rectangle.y + offset,
1263
+ width: rectangle.width + Math.abs(offset) * 2,
1264
+ height: rectangle.height + Math.abs(offset) * 2
1265
+ };
1266
+ },
1267
+ isEqual: (rectangle, otherRectangle) => {
1268
+ return (rectangle.x === otherRectangle.x &&
1269
+ rectangle.y === otherRectangle.y &&
1270
+ rectangle.width === otherRectangle.width &&
1271
+ rectangle.height === otherRectangle.height);
1272
+ }
1273
+ };
1274
+
1275
+ const isSetViewportOperation = (value) => {
1276
+ return value.type === 'set_viewport';
1277
+ };
1278
+ const inverse = (op) => {
1279
+ switch (op.type) {
1280
+ case 'insert_node': {
1281
+ return Object.assign(Object.assign({}, op), { type: 'remove_node' });
1282
+ }
1283
+ case 'remove_node': {
1284
+ return Object.assign(Object.assign({}, op), { type: 'insert_node' });
1285
+ }
1286
+ case 'move_node': {
1287
+ const { newPath, path } = op;
1288
+ // PERF: in this case the move operation is a no-op anyways.
1289
+ if (Path.equals(newPath, path)) {
1290
+ return op;
1291
+ }
1292
+ // when operation path is [0,0] -> [0,2], should exec Path.transform to get [0,1] -> [0,0]
1293
+ // shoud not return [0,2] -> [0,0] #WIK-8981
1294
+ // if (Path.isSibling(path, newPath)) {
1295
+ // return { ...op, path: newPath, newPath: path };
1296
+ // }
1297
+ // If the move does not happen within a single parent it is possible
1298
+ // for the move to impact the true path to the location where the node
1299
+ // was removed from and where it was inserted. We have to adjust for this
1300
+ // and find the original path. We can accomplish this (only in non-sibling)
1301
+ // moves by looking at the impact of the move operation on the node
1302
+ // after the original move path.
1303
+ const inversePath = Path.transform(path, op);
1304
+ const inverseNewPath = Path.transform(Path.next(path), op);
1305
+ return Object.assign(Object.assign({}, op), { path: inversePath, newPath: inverseNewPath });
1306
+ }
1307
+ case 'set_node': {
1308
+ const { properties, newProperties } = op;
1309
+ return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
1310
+ }
1311
+ case 'set_selection': {
1312
+ const { properties, newProperties } = op;
1313
+ if (properties == null) {
1314
+ return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: null });
1315
+ }
1316
+ else if (newProperties == null) {
1317
+ return Object.assign(Object.assign({}, op), { properties: null, newProperties: properties });
1318
+ }
1319
+ else {
1320
+ return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
1321
+ }
1322
+ }
1323
+ case 'set_viewport': {
1324
+ const { properties, newProperties } = op;
1325
+ if (properties == null) {
1326
+ return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: newProperties });
1327
+ }
1328
+ else if (newProperties == null) {
1329
+ return Object.assign(Object.assign({}, op), { properties: properties, newProperties: properties });
1330
+ }
1331
+ else {
1332
+ return Object.assign(Object.assign({}, op), { properties: newProperties, newProperties: properties });
1333
+ }
1334
+ }
1335
+ }
1336
+ };
1337
+ const PlaitOperation = {
1338
+ isSetViewportOperation,
1339
+ inverse
1340
+ };
1341
+
1342
+ const Point = {
1343
+ isEquals(point, otherPoint) {
1344
+ return point && otherPoint && point[0] === otherPoint[0] && point[1] === otherPoint[1];
1345
+ }
1346
+ };
1240
1347
 
1241
- function arrowPoints(start, end, maxHypotenuseLength = 10, degree = 40) {
1242
- const width = Math.abs(start[0] - end[0]);
1243
- const height = Math.abs(start[1] - end[1]);
1244
- let hypotenuse = Math.hypot(width, height); // 斜边
1245
- const realRotateLine = hypotenuse > maxHypotenuseLength * 2 ? maxHypotenuseLength : hypotenuse / 2;
1246
- const rotateWidth = (realRotateLine / hypotenuse) * width;
1247
- const rotateHeight = (realRotateLine / hypotenuse) * height;
1248
- const rotatePoint = [
1249
- end[0] > start[0] ? end[0] - rotateWidth : end[0] + rotateWidth,
1250
- end[1] > start[1] ? end[1] - rotateHeight : end[1] + rotateHeight
1251
- ];
1252
- const pointRight = rotate(rotatePoint[0], rotatePoint[1], end[0], end[1], (degree * Math.PI) / 180);
1253
- const pointLeft = rotate(rotatePoint[0], rotatePoint[1], end[0], end[1], (-degree * Math.PI) / 180);
1254
- return { pointLeft, pointRight };
1255
- }
1256
- function drawArrow(rs, start, end, options, maxHypotenuseLength = 10, degree = 40) {
1257
- const { pointLeft, pointRight } = arrowPoints(start, end, maxHypotenuseLength, degree);
1258
- const arrowLineLeft = rs.linearPath([pointLeft, end], options);
1259
- const arrowLineRight = rs.linearPath([pointRight, end], options);
1260
- return [arrowLineLeft, arrowLineRight];
1261
- }
1348
+ const SELECTION_BORDER_COLOR = '#6698FF';
1349
+ const SELECTION_FILL_COLOR = '#6698FF19'; // 主色 0.1 透明度
1350
+ const Selection = {
1351
+ isCollapsed(selection) {
1352
+ if (selection.anchor[0] == selection.focus[0] && selection.anchor[1] === selection.focus[1]) {
1353
+ return true;
1354
+ }
1355
+ else {
1356
+ return false;
1357
+ }
1358
+ }
1359
+ };
1262
1360
 
1263
- function drawCircle(roughSVG, point, diameter, options) {
1264
- return roughSVG.circle(point[0], point[1], diameter, options);
1265
- }
1361
+ const SAVING = new WeakMap();
1362
+ const MERGING = new WeakMap();
1266
1363
 
1267
- function drawLine(rs, start, end, options) {
1268
- return rs.linearPath([start, end], options);
1269
- }
1364
+ var PlaitPluginKey;
1365
+ (function (PlaitPluginKey) {
1366
+ PlaitPluginKey["withSelection"] = "withSelection";
1367
+ })(PlaitPluginKey || (PlaitPluginKey = {}));
1270
1368
 
1271
1369
  const IS_FROM_SCROLLING = new WeakMap();
1272
1370
  const IS_FROM_VIEWPORT_CHANGE = new WeakMap();
@@ -1396,15 +1494,49 @@ function initializeViewportOffset(board) {
1396
1494
  }
1397
1495
  updateViewportOffset(board);
1398
1496
  }
1399
- function setViewport(board, origination, zoom) {
1497
+ const updateViewportOrigination = (board, origination) => {
1498
+ BOARD_TO_VIEWPORT_ORIGINATION.set(board, origination);
1499
+ };
1500
+ const clearViewportOrigination = (board) => {
1501
+ BOARD_TO_VIEWPORT_ORIGINATION.delete(board);
1502
+ };
1503
+ const getViewportOrigination = (board) => {
1504
+ const origination = BOARD_TO_VIEWPORT_ORIGINATION.get(board);
1505
+ if (origination) {
1506
+ return origination;
1507
+ }
1508
+ else {
1509
+ return board.viewport.origination;
1510
+ }
1511
+ };
1512
+ const isFromScrolling = (board) => {
1513
+ return !!IS_FROM_SCROLLING.get(board);
1514
+ };
1515
+ const setIsFromScrolling = (board, state) => {
1516
+ IS_FROM_SCROLLING.set(board, state);
1517
+ };
1518
+ const isFromViewportChange = (board) => {
1519
+ return !!IS_FROM_VIEWPORT_CHANGE.get(board);
1520
+ };
1521
+ const setIsFromViewportChange = (board, state) => {
1522
+ IS_FROM_VIEWPORT_CHANGE.set(board, state);
1523
+ };
1524
+ function scrollToRectangle(board, client) { }
1525
+
1526
+ function updateViewport(board, origination, zoom) {
1400
1527
  zoom = zoom !== null && zoom !== void 0 ? zoom : board.viewport.zoom;
1401
- Transforms.setViewport(board, Object.assign(Object.assign({}, board.viewport), { zoom,
1528
+ setViewport(board, Object.assign(Object.assign({}, board.viewport), { zoom,
1402
1529
  origination }));
1403
1530
  clearViewportOrigination(board);
1404
1531
  }
1405
- function changeZoom(board, newZoom, isCenter = true) {
1532
+ const updatePointerType = (board, pointer) => {
1533
+ board.pointer = pointer;
1534
+ const boardComponent = BOARD_TO_COMPONENT.get(board);
1535
+ boardComponent === null || boardComponent === void 0 ? void 0 : boardComponent.markForCheck();
1536
+ };
1537
+ function updateZoom(board, newZoom, isCenter = true) {
1406
1538
  newZoom = clampZoomLevel(newZoom);
1407
- const mousePoint = BOARD_TO_MOVING_POINT.get(board);
1539
+ const mousePoint = PlaitBoard.getMovingPoint(board);
1408
1540
  const nativeElement = PlaitBoard.getBoardNativeElement(board);
1409
1541
  const nativeElementRect = nativeElement.getBoundingClientRect();
1410
1542
  const viewportContainerRect = getViewportContainerRect(board);
@@ -1417,7 +1549,7 @@ function changeZoom(board, newZoom, isCenter = true) {
1417
1549
  const centerX = origination[0] + focusPoint[0] / zoom;
1418
1550
  const centerY = origination[1] + focusPoint[1] / zoom;
1419
1551
  const newOrigination = [centerX - focusPoint[0] / newZoom, centerY - focusPoint[1] / newZoom];
1420
- setViewport(board, newOrigination, newZoom);
1552
+ updateViewport(board, newOrigination, newZoom);
1421
1553
  }
1422
1554
  function fitViewport(board) {
1423
1555
  const nativeElementRect = PlaitBoard.getBoardNativeElement(board).getBoundingClientRect();
@@ -1441,95 +1573,31 @@ function fitViewport(board) {
1441
1573
  centerX - viewportContainerRect.width / 2 / newZoom,
1442
1574
  centerY - viewportContainerRect.height / 2 / newZoom
1443
1575
  ];
1444
- setViewport(board, newOrigination, newZoom);
1576
+ updateViewport(board, newOrigination, newZoom);
1445
1577
  }
1446
- const updateViewportOrigination = (board, origination) => {
1447
- BOARD_TO_VIEWPORT_ORIGINATION.set(board, origination);
1448
- };
1449
- const clearViewportOrigination = (board) => {
1450
- BOARD_TO_VIEWPORT_ORIGINATION.delete(board);
1451
- };
1452
- const getViewportOrigination = (board) => {
1453
- const origination = BOARD_TO_VIEWPORT_ORIGINATION.get(board);
1454
- if (origination) {
1455
- return origination;
1456
- }
1457
- else {
1458
- return board.viewport.origination;
1459
- }
1460
- };
1461
- const isFromScrolling = (board) => {
1462
- return !!IS_FROM_SCROLLING.get(board);
1463
- };
1464
- const setIsFromScrolling = (board, state) => {
1465
- IS_FROM_SCROLLING.set(board, state);
1466
- };
1467
- const isFromViewportChange = (board) => {
1468
- return !!IS_FROM_VIEWPORT_CHANGE.get(board);
1469
- };
1470
- const setIsFromViewportChange = (board, state) => {
1471
- IS_FROM_VIEWPORT_CHANGE.set(board, state);
1578
+ const BoardTransforms = {
1579
+ updatePointerType,
1580
+ updateViewport,
1581
+ fitViewport,
1582
+ updateZoom
1472
1583
  };
1473
- function scrollToRectangle(board, client) { }
1474
1584
 
1475
- let timerId = null;
1476
- const throttleRAF = (fn) => {
1477
- const scheduleFunc = () => {
1478
- timerId = requestAnimationFrame(() => {
1479
- timerId = null;
1480
- fn();
1481
- });
1482
- };
1483
- if (timerId !== null) {
1484
- cancelAnimationFrame(timerId);
1485
- timerId = null;
1486
- }
1487
- scheduleFunc();
1488
- };
1489
- const debounce = (func, wait, options) => {
1490
- let timerSubscription = null;
1491
- return () => {
1492
- if (timerSubscription && !timerSubscription.closed) {
1493
- timerSubscription.unsubscribe();
1494
- timerSubscription = timer(wait).subscribe(() => {
1495
- func();
1496
- });
1585
+ const Transforms = Object.assign(Object.assign(Object.assign(Object.assign({}, GeneralTransforms), ViewportTransforms), SelectionTransforms), NodeTransforms);
1586
+
1587
+ const PathRef = {
1588
+ transform(ref, op) {
1589
+ const { current } = ref;
1590
+ if (current == null) {
1591
+ return;
1497
1592
  }
1498
- else {
1499
- if (options === null || options === void 0 ? void 0 : options.leading) {
1500
- func();
1501
- }
1502
- timerSubscription = timer(wait).subscribe();
1593
+ const path = Path.transform(current, op);
1594
+ ref.current = path;
1595
+ if (path == null) {
1596
+ ref.unref();
1503
1597
  }
1504
- };
1505
- };
1506
-
1507
- const getMovingElements = (board) => {
1508
- return BOARD_TO_MOVING_ELEMENT.get(board) || [];
1509
- };
1510
- const addMovingElements = (board, elements) => {
1511
- const movingElements = getMovingElements(board);
1512
- const newElements = elements.filter(item => !movingElements.find(movingElement => movingElement.key === item.key));
1513
- cacheMovingElements(board, [...movingElements, ...newElements]);
1514
- };
1515
- const removeMovingElements = (board) => {
1516
- BOARD_TO_MOVING_ELEMENT.delete(board);
1517
- };
1518
- const cacheMovingElements = (board, elements) => {
1519
- BOARD_TO_MOVING_ELEMENT.set(board, elements);
1520
- };
1521
-
1522
- const updatePointerType = (board, pointer) => {
1523
- board.pointer = pointer;
1524
- const boardComponent = BOARD_TO_COMPONENT.get(board);
1525
- boardComponent === null || boardComponent === void 0 ? void 0 : boardComponent.markForCheck();
1526
- };
1527
- const BoardTransforms = {
1528
- updatePointerType
1598
+ }
1529
1599
  };
1530
1600
 
1531
- const Transforms = Object.assign(Object.assign(Object.assign(Object.assign({}, GeneralTransforms), ViewportTransforms), SelectionTransforms), NodeTransforms);
1532
-
1533
1601
  function createBoard(children, options) {
1534
1602
  const board = {
1535
1603
  viewport: {
@@ -1543,14 +1611,17 @@ function createBoard(children, options) {
1543
1611
  undos: []
1544
1612
  },
1545
1613
  selection: null,
1546
- pointer: PlaitPointerType.selection,
1547
1614
  options: options || {
1548
1615
  readonly: false,
1549
1616
  hideScrollbar: false
1550
1617
  },
1618
+ pointer: (options === null || options === void 0 ? void 0 : options.readonly) ? PlaitPointerType.hand : PlaitPointerType.selection,
1551
1619
  undo: () => { },
1552
1620
  redo: () => { },
1553
1621
  apply: (operation) => {
1622
+ for (const ref of board.pathRefs()) {
1623
+ PathRef.transform(ref, operation);
1624
+ }
1554
1625
  board.operations.push(operation);
1555
1626
  Transforms.transform(board, operation);
1556
1627
  if (!FLUSHING.get(board)) {
@@ -1562,6 +1633,31 @@ function createBoard(children, options) {
1562
1633
  });
1563
1634
  }
1564
1635
  },
1636
+ pathRef: (path, options) => {
1637
+ const affinity = (options === null || options === void 0 ? void 0 : options.affinity) || 'forward';
1638
+ const ref = {
1639
+ current: path,
1640
+ affinity,
1641
+ unref() {
1642
+ const { current } = ref;
1643
+ const pathRefs = board.pathRefs();
1644
+ pathRefs.delete(ref);
1645
+ ref.current = null;
1646
+ return current;
1647
+ }
1648
+ };
1649
+ const refs = board.pathRefs();
1650
+ refs.add(ref);
1651
+ return ref;
1652
+ },
1653
+ pathRefs: () => {
1654
+ let refs = PATH_REFS.get(board);
1655
+ if (!refs) {
1656
+ refs = new Set();
1657
+ PATH_REFS.set(board, refs);
1658
+ }
1659
+ return refs;
1660
+ },
1565
1661
  onChange: () => { },
1566
1662
  mousedown: (event) => { },
1567
1663
  mousemove: (event) => { },
@@ -1690,13 +1786,7 @@ function withHandPointer(board) {
1690
1786
  y: 0
1691
1787
  };
1692
1788
  board.mousedown = (event) => {
1693
- if (board.options.readonly) {
1694
- updatePointerType(board, PlaitPointerType.hand);
1695
- }
1696
- else if (!board.selection) {
1697
- updatePointerType(board, PlaitPointerType.selection);
1698
- }
1699
- if (board.pointer === PlaitPointerType.hand && board.selection) {
1789
+ if (PlaitBoard.isPointer(board, PlaitPointerType.hand) && isMainPointer(event)) {
1700
1790
  isMoving = true;
1701
1791
  PlaitBoard.getBoardNativeElement(board).classList.add('viewport-moving');
1702
1792
  plaitBoardMove.x = event.x;
@@ -1705,7 +1795,7 @@ function withHandPointer(board) {
1705
1795
  mousedown(event);
1706
1796
  };
1707
1797
  board.mousemove = (event) => {
1708
- if (board.pointer === PlaitPointerType.hand && board.selection && isMoving) {
1798
+ if (PlaitBoard.isPointer(board, PlaitPointerType.hand) && board.selection && isMoving) {
1709
1799
  const viewportContainer = PlaitBoard.getViewportContainer(board);
1710
1800
  const left = viewportContainer.scrollLeft - (event.x - plaitBoardMove.x);
1711
1801
  const top = viewportContainer.scrollTop - (event.y - plaitBoardMove.y);
@@ -1725,17 +1815,17 @@ function withHandPointer(board) {
1725
1815
  globalMouseup(event);
1726
1816
  };
1727
1817
  board.keydown = (event) => {
1728
- if (board.selection && event.code === 'Space') {
1729
- if (board.pointer !== PlaitPointerType.hand) {
1730
- updatePointerType(board, PlaitPointerType.hand);
1818
+ if (event.code === 'Space') {
1819
+ if (!PlaitBoard.isPointer(board, PlaitPointerType.hand)) {
1820
+ BoardTransforms.updatePointerType(board, PlaitPointerType.hand);
1731
1821
  }
1732
1822
  event.preventDefault();
1733
1823
  }
1734
1824
  keydown(event);
1735
1825
  };
1736
1826
  board.keyup = (event) => {
1737
- if (board.selection && !board.options.readonly && event.code === 'Space') {
1738
- updatePointerType(board, PlaitPointerType.selection);
1827
+ if (!board.options.readonly && event.code === 'Space') {
1828
+ BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1739
1829
  }
1740
1830
  keyup(event);
1741
1831
  };
@@ -1752,22 +1842,26 @@ function withSelection(board) {
1752
1842
  let selectionOuterG;
1753
1843
  let previousSelectedElements;
1754
1844
  board.mousedown = (event) => {
1755
- if (event.button === 0) {
1756
- start = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1845
+ if (!isMainPointer(event)) {
1846
+ mousedown(event);
1847
+ return;
1757
1848
  }
1758
- if (start) {
1759
- const ranges = [{ anchor: start, focus: start }];
1760
- const selectedElements = getSelectedElements(board);
1761
- if (isIntersectionElements(board, selectedElements, ranges)) {
1762
- start = null;
1763
- mousedown(event);
1764
- return;
1765
- }
1766
- Transforms.setSelection(board, { ranges: ranges });
1767
- if (board.pointer === PlaitPointerType.hand || getHitElements(board).length) {
1768
- start = null;
1769
- }
1849
+ const options = board.getPluginOptions(PlaitPluginKey.withSelection);
1850
+ const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1851
+ const ranges = [{ anchor: point, focus: point }];
1852
+ const selectedElements = getSelectedElements(board);
1853
+ if (isIntersectionElements(board, selectedElements, ranges)) {
1854
+ mousedown(event);
1855
+ return;
1770
1856
  }
1857
+ const range = { anchor: point, focus: point };
1858
+ if (PlaitBoard.isPointer(board, PlaitPointerType.selection) &&
1859
+ PlaitBoard.isFocus(board) &&
1860
+ getHitElements(board, { ranges: [range] }).length === 0 &&
1861
+ options.isMultiple) {
1862
+ start = point;
1863
+ }
1864
+ Transforms.setSelection(board, { ranges: ranges });
1771
1865
  mousedown(event);
1772
1866
  };
1773
1867
  board.globalMousemove = (event) => {
@@ -1822,7 +1916,11 @@ function withSelection(board) {
1822
1916
  if (board.operations.find(value => value.type === 'set_selection')) {
1823
1917
  selectionOuterG === null || selectionOuterG === void 0 ? void 0 : selectionOuterG.remove();
1824
1918
  const temporaryElements = getTemporaryElements(board);
1825
- const elements = temporaryElements ? temporaryElements : getHitElements(board);
1919
+ let elements = temporaryElements ? temporaryElements : getHitElements(board);
1920
+ const options = board.getPluginOptions(PlaitPluginKey.withSelection);
1921
+ if (!options.isMultiple && elements.length > 1) {
1922
+ elements = [elements[0]];
1923
+ }
1826
1924
  cacheSelectedElements(board, elements);
1827
1925
  previousSelectedElements = elements;
1828
1926
  const { width, height } = getRectangleByElements(board, elements, false);
@@ -1858,6 +1956,7 @@ function withSelection(board) {
1858
1956
  }
1859
1957
  onChange();
1860
1958
  };
1959
+ board.setPluginOptions(PlaitPluginKey.withSelection, { isMultiple: true });
1861
1960
  return board;
1862
1961
  }
1863
1962
  function getTemporaryElements(board) {
@@ -1999,6 +2098,50 @@ function withMoving(board) {
1999
2098
  return board;
2000
2099
  }
2001
2100
 
2101
+ const withOptions = (board) => {
2102
+ const pluginOptions = new Map();
2103
+ const newBoard = board;
2104
+ newBoard.getPluginOptions = key => {
2105
+ return pluginOptions.get(key);
2106
+ };
2107
+ newBoard.setPluginOptions = (key, options) => {
2108
+ const oldOptions = newBoard.getPluginOptions(key) || {};
2109
+ pluginOptions.set(key, Object.assign(Object.assign({}, oldOptions), options));
2110
+ };
2111
+ return newBoard;
2112
+ };
2113
+
2114
+ class PlaitIslandBaseComponent {
2115
+ constructor(cdr) {
2116
+ this.cdr = cdr;
2117
+ }
2118
+ initialize(board) {
2119
+ this.board = board;
2120
+ this.markForCheck();
2121
+ }
2122
+ markForCheck() {
2123
+ this.cdr.markForCheck();
2124
+ }
2125
+ }
2126
+ PlaitIslandBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitIslandBaseComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
2127
+ PlaitIslandBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.5", type: PlaitIslandBaseComponent, host: { classAttribute: "plait-island-container" }, ngImport: i0 });
2128
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitIslandBaseComponent, decorators: [{
2129
+ type: Directive,
2130
+ args: [{
2131
+ host: {
2132
+ class: 'plait-island-container'
2133
+ }
2134
+ }]
2135
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
2136
+ const hasOnBoardChange = (value) => {
2137
+ if (value.onBoardChange) {
2138
+ return true;
2139
+ }
2140
+ else {
2141
+ return false;
2142
+ }
2143
+ };
2144
+
2002
2145
  class PlaitElementComponent {
2003
2146
  constructor(renderer2, viewContainerRef) {
2004
2147
  this.renderer2 = renderer2;
@@ -2149,69 +2292,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
2149
2292
  type: Input
2150
2293
  }] } });
2151
2294
 
2152
- class PlaitToolbarComponent {
2153
- constructor() {
2154
- this.PlaitPointerType = PlaitPointerType;
2155
- this.hostClass = `plait-board-toolbar`;
2156
- this.adaptHandle = new EventEmitter();
2157
- this.zoomInHandle = new EventEmitter();
2158
- this.zoomOutHandle = new EventEmitter();
2159
- this.resetZoomHandel = new EventEmitter();
2160
- }
2161
- get zoom() {
2162
- var _a;
2163
- const zoom = ((_a = this.board) === null || _a === void 0 ? void 0 : _a.viewport.zoom) || 1;
2164
- return Number((zoom * 100).toFixed(0));
2165
- }
2166
- get isHand() {
2167
- return this.board.pointer === PlaitPointerType.hand;
2168
- }
2169
- activeHand() {
2170
- updatePointerType(this.board, this.isHand ? PlaitPointerType.selection : PlaitPointerType.hand);
2171
- }
2172
- // 适应画布
2173
- adapt() {
2174
- this.adaptHandle.emit();
2175
- }
2176
- // 放大
2177
- zoomIn() {
2178
- this.zoomInHandle.emit();
2179
- }
2180
- // 缩小
2181
- zoomOut() {
2182
- this.zoomOutHandle.emit();
2183
- }
2184
- resetZoom() {
2185
- this.resetZoomHandel.emit();
2186
- }
2187
- }
2188
- PlaitToolbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2189
- 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 });
2190
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitToolbarComponent, decorators: [{
2191
- type: Component,
2192
- 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" }]
2193
- }], propDecorators: { hostClass: [{
2194
- type: HostBinding,
2195
- args: ['class']
2196
- }], board: [{
2197
- type: Input
2198
- }], adaptHandle: [{
2199
- type: Output
2200
- }], zoomInHandle: [{
2201
- type: Output
2202
- }], zoomOutHandle: [{
2203
- type: Output
2204
- }], resetZoomHandel: [{
2205
- type: Output
2206
- }] } });
2207
-
2208
2295
  const ElementHostClass = 'element-host';
2209
2296
  class PlaitBoardComponent {
2210
2297
  get host() {
2211
2298
  return this.svg.nativeElement;
2212
2299
  }
2213
2300
  get hostClass() {
2214
- return `plait-board-container ${this.board.pointer}`;
2301
+ return `plait-board-container pointer-${this.board.pointer}`;
2215
2302
  }
2216
2303
  get readonly() {
2217
2304
  return this.board.options.readonly;
@@ -2222,8 +2309,9 @@ class PlaitBoardComponent {
2222
2309
  get nativeElement() {
2223
2310
  return this.elementRef.nativeElement;
2224
2311
  }
2225
- constructor(cdr, elementRef, ngZone) {
2312
+ constructor(cdr, viewContainerRef, elementRef, ngZone) {
2226
2313
  this.cdr = cdr;
2314
+ this.viewContainerRef = viewContainerRef;
2227
2315
  this.elementRef = elementRef;
2228
2316
  this.ngZone = ngZone;
2229
2317
  this.hasInitialized = false;
@@ -2263,11 +2351,15 @@ class PlaitBoardComponent {
2263
2351
  viewport: this.board.viewport,
2264
2352
  selection: this.board.selection
2265
2353
  };
2354
+ this.updateIslands();
2266
2355
  this.plaitChange.emit(changeEvent);
2267
2356
  });
2268
2357
  });
2269
2358
  this.hasInitialized = true;
2270
2359
  }
2360
+ ngAfterContentInit() {
2361
+ this.initializeIslands();
2362
+ }
2271
2363
  detect() {
2272
2364
  this.effect = {};
2273
2365
  this.cdr.detectChanges();
@@ -2290,7 +2382,7 @@ class PlaitBoardComponent {
2290
2382
  initializeViewportOffset(this.board);
2291
2383
  }
2292
2384
  initializePlugins() {
2293
- let board = withHandPointer(withHistory(withSelection(withMoving(withBoard(withViewport(createBoard(this.plaitValue, this.plaitOptions)))))));
2385
+ let board = withHandPointer(withHistory(withSelection(withMoving(withBoard(withViewport(withOptions(createBoard(this.plaitValue, this.plaitOptions))))))));
2294
2386
  this.plaitPlugins.forEach(plugin => {
2295
2387
  board = plugin(board);
2296
2388
  });
@@ -2327,22 +2419,25 @@ class PlaitBoardComponent {
2327
2419
  this.board.globalMouseup(event);
2328
2420
  });
2329
2421
  fromEvent(this.host, 'dblclick')
2330
- .pipe(takeUntil(this.destroy$))
2422
+ .pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board)))
2331
2423
  .subscribe((event) => {
2332
2424
  this.board.dblclick(event);
2333
2425
  });
2334
2426
  fromEvent(document, 'keydown')
2335
- .pipe(takeUntil(this.destroy$), filter(event => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board) && !hasInputOrTextareaTarget(event.target)))
2427
+ .pipe(takeUntil(this.destroy$), tap((event) => {
2428
+ if (PlaitBoard.getMovingPoint(this.board)) {
2429
+ if (isHotkey(['mod+=', 'mod++'], { byKey: true })(event)) {
2430
+ event.preventDefault();
2431
+ BoardTransforms.updateZoom(this.board, this.board.viewport.zoom + 0.1, false);
2432
+ }
2433
+ if (isHotkey('mod+-', { byKey: true })(event)) {
2434
+ event.preventDefault();
2435
+ BoardTransforms.updateZoom(this.board, this.board.viewport.zoom - 0.1);
2436
+ }
2437
+ }
2438
+ }), filter(event => this.isFocused && !PlaitBoard.hasBeenTextEditing(this.board) && !hasInputOrTextareaTarget(event.target)))
2336
2439
  .subscribe((event) => {
2337
2440
  var _a;
2338
- if (isHotkey(['mod+=', 'mod++'], { byKey: true })(event)) {
2339
- event.preventDefault();
2340
- this.zoomInHandle(false);
2341
- }
2342
- if (isHotkey('mod+-', { byKey: true })(event)) {
2343
- this.zoomOutHandle();
2344
- event.preventDefault();
2345
- }
2346
2441
  (_a = this.board) === null || _a === void 0 ? void 0 : _a.keydown(event);
2347
2442
  });
2348
2443
  fromEvent(document, 'keyup')
@@ -2361,7 +2456,7 @@ class PlaitBoardComponent {
2361
2456
  fromEvent(document, 'paste')
2362
2457
  .pipe(takeUntil(this.destroy$), filter(() => this.isFocused && !PlaitBoard.isReadonly(this.board) && !PlaitBoard.hasBeenTextEditing(this.board)))
2363
2458
  .subscribe((clipboardEvent) => {
2364
- const mousePoint = BOARD_TO_MOVING_POINT.get(this.board);
2459
+ const mousePoint = PlaitBoard.getMovingPoint(this.board);
2365
2460
  const rect = this.nativeElement.getBoundingClientRect();
2366
2461
  if (mousePoint && distanceBetweenPointAndRectangle(mousePoint[0], mousePoint[1], rect) === 0) {
2367
2462
  const targetPoint = transformPoint(this.board, toPoint(mousePoint[0], mousePoint[1], this.host));
@@ -2395,7 +2490,7 @@ class PlaitBoardComponent {
2395
2490
  if (Point.isEquals(origination, this.board.viewport.origination)) {
2396
2491
  return;
2397
2492
  }
2398
- setViewport(this.board, origination);
2493
+ BoardTransforms.updateViewport(this.board, origination);
2399
2494
  setIsFromScrolling(this.board, true);
2400
2495
  });
2401
2496
  });
@@ -2415,17 +2510,20 @@ class PlaitBoardComponent {
2415
2510
  BOARD_TO_MOVING_POINT.delete(this.board);
2416
2511
  });
2417
2512
  }
2418
- adaptHandle() {
2419
- fitViewport(this.board);
2420
- }
2421
- zoomInHandle(isCenter = true) {
2422
- changeZoom(this.board, this.board.viewport.zoom + 0.1, isCenter);
2423
- }
2424
- zoomOutHandle() {
2425
- changeZoom(this.board, this.board.viewport.zoom - 0.1);
2513
+ initializeIslands() {
2514
+ var _a;
2515
+ (_a = this.islands) === null || _a === void 0 ? void 0 : _a.forEach(island => {
2516
+ island.initialize(this.board);
2517
+ });
2426
2518
  }
2427
- resetZoomHandel() {
2428
- changeZoom(this.board, 1);
2519
+ updateIslands() {
2520
+ var _a;
2521
+ (_a = this.islands) === null || _a === void 0 ? void 0 : _a.forEach(island => {
2522
+ if (hasOnBoardChange(island)) {
2523
+ island.onBoardChange();
2524
+ }
2525
+ island.markForCheck();
2526
+ });
2429
2527
  }
2430
2528
  ngOnDestroy() {
2431
2529
  var _a;
@@ -2441,24 +2539,19 @@ class PlaitBoardComponent {
2441
2539
  }
2442
2540
  markForCheck() {
2443
2541
  this.cdr.markForCheck();
2542
+ this.ngZone.run(() => {
2543
+ this.updateIslands();
2544
+ });
2444
2545
  }
2445
2546
  }
2446
- PlaitBoardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitBoardComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2447
- 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: `
2547
+ PlaitBoardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitBoardComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2548
+ 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: "islands", predicate: PlaitIslandBaseComponent, 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: `
2448
2549
  <div class="viewport-container" #viewportContainer>
2449
2550
  <svg #svg width="100%" height="100%" style="position: relative;"><g class="element-host"></g></svg>
2450
2551
  <plait-children [board]="board" [effect]="effect"></plait-children>
2451
2552
  </div>
2452
- <plait-toolbar
2453
- *ngIf="isFocused && !toolbarTemplateRef"
2454
- [board]="board"
2455
- (adaptHandle)="adaptHandle()"
2456
- (zoomInHandle)="zoomInHandle()"
2457
- (zoomOutHandle)="zoomOutHandle()"
2458
- (resetZoomHandel)="resetZoomHandel()"
2459
- ></plait-toolbar>
2460
2553
  <ng-content></ng-content>
2461
- `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PlaitChildrenElement, selector: "plait-children", inputs: ["board", "parent", "effect", "parentG"] }, { kind: "component", type: PlaitToolbarComponent, selector: "plait-toolbar", inputs: ["board"], outputs: ["adaptHandle", "zoomInHandle", "zoomOutHandle", "resetZoomHandel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2554
+ `, isInline: true, dependencies: [{ kind: "component", type: PlaitChildrenElement, selector: "plait-children", inputs: ["board", "parent", "effect", "parentG"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2462
2555
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitBoardComponent, decorators: [{
2463
2556
  type: Component,
2464
2557
  args: [{
@@ -2468,19 +2561,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
2468
2561
  <svg #svg width="100%" height="100%" style="position: relative;"><g class="element-host"></g></svg>
2469
2562
  <plait-children [board]="board" [effect]="effect"></plait-children>
2470
2563
  </div>
2471
- <plait-toolbar
2472
- *ngIf="isFocused && !toolbarTemplateRef"
2473
- [board]="board"
2474
- (adaptHandle)="adaptHandle()"
2475
- (zoomInHandle)="zoomInHandle()"
2476
- (zoomOutHandle)="zoomOutHandle()"
2477
- (resetZoomHandel)="resetZoomHandel()"
2478
- ></plait-toolbar>
2479
2564
  <ng-content></ng-content>
2480
2565
  `,
2481
2566
  changeDetection: ChangeDetectionStrategy.OnPush
2482
2567
  }]
2483
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { plaitValue: [{
2568
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { plaitValue: [{
2484
2569
  type: Input
2485
2570
  }], plaitViewport: [{
2486
2571
  type: Input
@@ -2504,19 +2589,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
2504
2589
  }], svg: [{
2505
2590
  type: ViewChild,
2506
2591
  args: ['svg', { static: true }]
2507
- }], toolbarTemplateRef: [{
2508
- type: ContentChild,
2509
- args: ['plaitToolbar']
2510
2592
  }], viewportContainer: [{
2511
2593
  type: ViewChild,
2512
2594
  args: ['viewportContainer', { read: ElementRef, static: true }]
2595
+ }], islands: [{
2596
+ type: ContentChildren,
2597
+ args: [PlaitIslandBaseComponent, { descendants: true }]
2513
2598
  }] } });
2514
2599
 
2515
- const COMPONENTS = [PlaitBoardComponent, PlaitChildrenElement, PlaitElementComponent, PlaitToolbarComponent];
2600
+ const COMPONENTS = [PlaitBoardComponent, PlaitChildrenElement, PlaitElementComponent];
2516
2601
  class PlaitModule {
2517
2602
  }
2518
2603
  PlaitModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2519
- PlaitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, declarations: [PlaitBoardComponent, PlaitChildrenElement, PlaitElementComponent, PlaitToolbarComponent], imports: [CommonModule], exports: [PlaitBoardComponent, PlaitChildrenElement, PlaitElementComponent, PlaitToolbarComponent] });
2604
+ PlaitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, declarations: [PlaitBoardComponent, PlaitChildrenElement, PlaitElementComponent], imports: [CommonModule], exports: [PlaitBoardComponent, PlaitChildrenElement, PlaitElementComponent] });
2520
2605
  PlaitModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, imports: [CommonModule] });
2521
2606
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: PlaitModule, decorators: [{
2522
2607
  type: NgModule,
@@ -2527,6 +2612,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
2527
2612
  }]
2528
2613
  }] });
2529
2614
 
2615
+ /**
2616
+ * 1.create board instance
2617
+ * 2.build fake node weak map
2618
+ */
2619
+ const createTestingBoard = (plugins, children, options = { readonly: false, hideScrollbar: true }) => {
2620
+ let board = createBoard(children, options);
2621
+ plugins.forEach(plugin => {
2622
+ board = plugin(board);
2623
+ });
2624
+ return board;
2625
+ };
2626
+
2627
+ const fakeNodeWeakMap = (object) => {
2628
+ const children = object.children || [];
2629
+ children.forEach((value, index) => {
2630
+ NODE_TO_PARENT.set(value, object);
2631
+ NODE_TO_INDEX.set(value, index);
2632
+ fakeNodeWeakMap(value);
2633
+ });
2634
+ };
2635
+ const clearNodeWeakMap = (object) => {
2636
+ const children = object.children || [];
2637
+ children.forEach(value => {
2638
+ NODE_TO_PARENT.delete(value);
2639
+ NODE_TO_INDEX.delete(value);
2640
+ clearNodeWeakMap(value);
2641
+ });
2642
+ };
2643
+
2530
2644
  /*
2531
2645
  * Public API Surface of plait
2532
2646
  */
@@ -2535,5 +2649,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImpor
2535
2649
  * Generated bundle index. Do not edit.
2536
2650
  */
2537
2651
 
2538
- 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_SELECTED_ELEMENT, BOARD_TO_TEMPORARY_ELEMENTS, BOARD_TO_VIEWPORT_ORIGINATION, BoardTransforms, CLIP_BOARD_FORMAT_KEY, ELEMENT_TO_COMPONENT, FLUSHING, IS_APPLE, IS_BOARD_CACHE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_SAFARI, IS_TEXT_EDITABLE, MAX_RADIUS, MERGING, NODE_TO_INDEX, NODE_TO_PARENT, NS, Path, PlaitBoard, PlaitBoardComponent, PlaitChildrenElement, 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, changeZoom, clampZoomLevel, clearSelectedElement, clearSelectionMoving, clearViewportOrigination, createForeignObject, createG, createSVG, createSelectionOuterG, createText, debounce, deleteTemporaryElements, depthFirstRecursion, distanceBetweenPointAndPoint, distanceBetweenPointAndRectangle, distanceBetweenPointAndSegment, drawAbstractRoundRectangle, drawArrow, drawCircle, drawLine, drawRoundRectangle, fitViewport, getBoardRectangle, getElementHostBBox, getHitElements, getMovingElements, getRectangleByElements, getSelectedElements, getTemporaryElements, getViewBox, getViewportContainerRect, getViewportOrigination, hasBeforeContextChange, hasInputOrTextareaTarget, hasOnContextChanged, hotkeys, idCreator, initializeViewBox, initializeViewportContainer, initializeViewportOffset, inverse, isDOMElement, isDOMNode, isFromScrolling, isFromViewportChange, isInPlaitBoard, isIntersectionElements, isNullOrUndefined, isSelectedElement, isSelectionMoving, isSetViewportOperation, normalizePoint, removeMovingElements, removeSelectedElement, rotate, scrollToRectangle, setIsFromScrolling, setIsFromViewportChange, setSVGViewBox, setSelectionMoving, setViewport, shouldClear, shouldMerge, shouldSave, throttleRAF, toPoint, transformPoint, transformPoints, updateForeignObject, updateViewportContainerScroll, updateViewportOffset, updateViewportOrigination, withMoving, withSelection };
2652
+ 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_SELECTED_ELEMENT, BOARD_TO_TEMPORARY_ELEMENTS, BOARD_TO_VIEWPORT_ORIGINATION, BoardTransforms, CLIP_BOARD_FORMAT_KEY, ELEMENT_TO_COMPONENT, FLUSHING, IS_APPLE, IS_BOARD_CACHE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_SAFARI, IS_TEXT_EDITABLE, MAX_RADIUS, MERGING, NODE_TO_INDEX, NODE_TO_PARENT, NS, PATH_REFS, POINTER_BUTTON, Path, PlaitBoard, PlaitBoardComponent, PlaitChildrenElement, PlaitElement, PlaitElementComponent, PlaitHistoryBoard, PlaitIslandBaseComponent, PlaitModule, PlaitNode, PlaitOperation, PlaitPluginElementComponent, PlaitPluginKey, PlaitPointerType, Point, RectangleClient, SAVING, SCROLL_BAR_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, Selection, Transforms, Viewport, addMovingElements, addSelectedElement, arrowPoints, cacheMovingElements, cacheSelectedElements, clampZoomLevel, clearNodeWeakMap, clearSelectedElement, clearSelectionMoving, clearViewportOrigination, createForeignObject, createG, createPath, createSVG, createSelectionOuterG, createTestingBoard, createText, debounce, deleteTemporaryElements, depthFirstRecursion, distanceBetweenPointAndPoint, distanceBetweenPointAndRectangle, distanceBetweenPointAndSegment, drawAbstractRoundRectangle, drawArrow, drawCircle, drawLine, drawLinearPath, drawRoundRectangle, fakeNodeWeakMap, getBoardRectangle, getElementHostBBox, getHitElements, getMovingElements, getRectangleByElements, getSelectedElements, getTemporaryElements, getViewBox, getViewportContainerRect, getViewportOrigination, hasBeforeContextChange, hasInputOrTextareaTarget, hasOnBoardChange, hasOnContextChanged, hotkeys, idCreator, initializeViewBox, initializeViewportContainer, initializeViewportOffset, inverse, isDOMElement, isDOMNode, isFromScrolling, isFromViewportChange, isInPlaitBoard, isIntersectionElements, isMainPointer, isNullOrUndefined, isSecondaryPointer, isSelectedElement, isSelectionMoving, isSetViewportOperation, normalizePoint, removeMovingElements, removeSelectedElement, rotate, scrollToRectangle, setIsFromScrolling, setIsFromViewportChange, setSVGViewBox, setSelectionMoving, shouldClear, shouldMerge, shouldSave, throttleRAF, toPoint, transformPoint, transformPoints, updateForeignObject, updateViewportContainerScroll, updateViewportOffset, updateViewportOrigination, withMoving, withOptions, withSelection };
2539
2653
  //# sourceMappingURL=plait-core.mjs.map