@plait/core 0.0.49 → 0.0.50

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.
@@ -15,6 +15,7 @@ var BaseCursorStatus;
15
15
  (function (BaseCursorStatus) {
16
16
  BaseCursorStatus["move"] = "move";
17
17
  BaseCursorStatus["select"] = "select";
18
+ BaseCursorStatus["drag"] = "drag";
18
19
  })(BaseCursorStatus || (BaseCursorStatus = {}));
19
20
 
20
21
  const Path = {
@@ -510,6 +511,33 @@ function withBoard(board) {
510
511
  return board;
511
512
  }
512
513
 
514
+ function transformPoints(board, points) {
515
+ const newPoints = points.map(point => {
516
+ return transformPoint(board, point);
517
+ });
518
+ return newPoints;
519
+ }
520
+ function transformPoint(board, point) {
521
+ const { width, height } = board.host.getBoundingClientRect();
522
+ const viewBox = board.host.viewBox.baseVal;
523
+ const x = (point[0] / width) * viewBox.width + viewBox.x;
524
+ const y = (point[1] / height) * viewBox.height + viewBox.y;
525
+ const newPoint = [x, y];
526
+ return newPoint;
527
+ }
528
+ function calculateZoom(zoom, minZoom = 0.2, maxZoom = 4) {
529
+ return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
530
+ }
531
+ function isNoSelectionElement(e) {
532
+ var _a;
533
+ return (_a = e.target) === null || _a === void 0 ? void 0 : _a.closest('.plait-board-attached');
534
+ }
535
+ const updateCursorStatus = (board, cursor) => {
536
+ if (cursor) {
537
+ board.cursor = cursor;
538
+ }
539
+ };
540
+
513
541
  const NS = 'http://www.w3.org/2000/svg';
514
542
  function toPoint(x, y, container) {
515
543
  const rect = container.getBoundingClientRect();
@@ -556,6 +584,68 @@ function toRectangleClient(points) {
556
584
  return rect;
557
585
  }
558
586
 
587
+ /**
588
+ * Check whether to merge an operation into the previous operation.
589
+ */
590
+ const shouldMerge = (op, prev) => {
591
+ if (op.type === 'set_viewport' && op.type === (prev === null || prev === void 0 ? void 0 : prev.type)) {
592
+ return true;
593
+ }
594
+ return false;
595
+ };
596
+ /**
597
+ * Check whether an operation needs to be saved to the history.
598
+ */
599
+ const shouldSave = (op, prev) => {
600
+ if (op.type === 'set_selection' || op.type === 'set_viewport') {
601
+ return false;
602
+ }
603
+ return true;
604
+ };
605
+ /**
606
+ * Check whether an operation should clear the redos stack.
607
+ */
608
+ const shouldClear = (op) => {
609
+ if (op.type === 'set_selection') {
610
+ return false;
611
+ }
612
+ return true;
613
+ };
614
+ const PlaitHistoryBoard = {
615
+ /**
616
+ * Get the saving flag's current value.
617
+ */
618
+ isSaving(board) {
619
+ return SAVING.get(board);
620
+ },
621
+ /**
622
+ * Get the merge flag's current value.
623
+ */
624
+ isMerging(board) {
625
+ return MERGING.get(board);
626
+ },
627
+ /**
628
+ * Apply a series of changes inside a synchronous `fn`, without merging any of
629
+ * the new operations into previous save point in the history.
630
+ */
631
+ withoutMerging(board, fn) {
632
+ const prev = PlaitHistoryBoard.isMerging(board);
633
+ MERGING.set(board, false);
634
+ fn();
635
+ MERGING.set(board, prev);
636
+ },
637
+ /**
638
+ * Apply a series of changes inside a synchronous `fn`, without saving any of
639
+ * their operations into the history.
640
+ */
641
+ withoutSaving(board, fn) {
642
+ const prev = PlaitHistoryBoard.isSaving(board);
643
+ SAVING.set(board, false);
644
+ fn();
645
+ SAVING.set(board, prev);
646
+ }
647
+ };
648
+
559
649
  /**
560
650
  * Hotkey mappings for each platform.
561
651
  */
@@ -704,32 +794,27 @@ function distanceBetweenPointAndPoint(x1, y1, x2, y2) {
704
794
  return Math.hypot(dx, dy);
705
795
  }
706
796
 
707
- function transformPoints(board, points) {
708
- const newPoints = points.map(point => {
709
- return transformPoint(board, point);
710
- });
711
- return newPoints;
797
+ function invert(oldMatrix, newMatrix) {
798
+ let n = newMatrix[0], r = newMatrix[1], a = newMatrix[2], i = newMatrix[3], o = newMatrix[4], c = newMatrix[5], l = newMatrix[6], s = newMatrix[7], u = newMatrix[8], d = u * o - c * s, h = -u * i + c * l, f = s * i - o * l, p = n * d + r * h + a * f;
799
+ return p
800
+ ? ((p = 1 / p),
801
+ (oldMatrix[0] = d * p),
802
+ (oldMatrix[1] = (-u * r + a * s) * p),
803
+ (oldMatrix[2] = (c * r - a * o) * p),
804
+ (oldMatrix[3] = h * p),
805
+ (oldMatrix[4] = (u * n - a * l) * p),
806
+ (oldMatrix[5] = (-c * n + a * i) * p),
807
+ (oldMatrix[6] = f * p),
808
+ (oldMatrix[7] = (-s * n + r * l) * p),
809
+ (oldMatrix[8] = (o * n - r * i) * p),
810
+ oldMatrix)
811
+ : null;
712
812
  }
713
- function transformPoint(board, point) {
714
- const { width, height } = board.host.getBoundingClientRect();
715
- const viewBox = board.host.viewBox.baseVal;
716
- const x = (point[0] / width) * viewBox.width + viewBox.x;
717
- const y = (point[1] / height) * viewBox.height + viewBox.y;
718
- const newPoint = [x, y];
719
- return newPoint;
720
- }
721
- function getViewBox(board) {
722
- const viewportBox = getViewportClientBox(board);
723
- const rootGroupBBox = calculateBBox(board);
724
- const padding = [viewportBox.height / 2, viewportBox.width / 2];
725
- const zoom = board.viewport.zoom;
726
- const minX = rootGroupBBox.left - padding[1] / zoom;
727
- const minY = rootGroupBBox.top - padding[0] / zoom;
728
- const viewportWidth = (rootGroupBBox.right - rootGroupBBox.left) * zoom + 2 * padding[1];
729
- const viewportHeight = (rootGroupBBox.bottom - rootGroupBBox.top) * zoom + 2 * padding[0];
730
- const width = viewportWidth / zoom;
731
- const height = viewportHeight / zoom;
732
- return { minX, minY, width, height, viewportWidth, viewportHeight };
813
+ function transformMat3(e, t, n) {
814
+ const r = t[0];
815
+ const a = t[1];
816
+ const i = t[2];
817
+ return (e[0] = r * n[0] + a * n[3] + i * n[6]), (e[1] = r * n[1] + a * n[4] + i * n[7]), (e[2] = r * n[2] + a * n[5] + i * n[8]), e;
733
818
  }
734
819
  function getViewportClientBox(board) {
735
820
  var _a;
@@ -739,9 +824,13 @@ function getViewportClientBox(board) {
739
824
  const containerRect = container === null || container === void 0 ? void 0 : container.getBoundingClientRect();
740
825
  const width = containerRect.width - scrollBarWidth;
741
826
  const height = containerRect.height - scrollBarWidth;
827
+ const x = containerRect.x || containerRect.left;
828
+ const y = containerRect.y || containerRect.top;
742
829
  return {
743
830
  width,
744
- height
831
+ height,
832
+ x,
833
+ y
745
834
  };
746
835
  }
747
836
  function calculateBBox(board) {
@@ -775,80 +864,19 @@ function calculateBBox(board) {
775
864
  // 在新的缩放比容器宽高下的内容盒子位置
776
865
  return box;
777
866
  }
778
- function calculateZoom(zoom, minZoom = 0.2, maxZoom = 4) {
779
- return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
780
- }
781
- function isNoSelectionElement(e) {
782
- var _a;
783
- return (_a = e.target) === null || _a === void 0 ? void 0 : _a.closest('.plait-board-attached');
867
+ function getViewBox(board) {
868
+ const viewportBox = getViewportClientBox(board);
869
+ const rootGroupBBox = calculateBBox(board);
870
+ const padding = [viewportBox.height / 2, viewportBox.width / 2];
871
+ const zoom = board.viewport.zoom;
872
+ const minX = rootGroupBBox.left - padding[1] / zoom;
873
+ const minY = rootGroupBBox.top - padding[0] / zoom;
874
+ const viewportWidth = (rootGroupBBox.right - rootGroupBBox.left) * zoom + 2 * padding[1];
875
+ const viewportHeight = (rootGroupBBox.bottom - rootGroupBBox.top) * zoom + 2 * padding[0];
876
+ const width = viewportWidth / zoom;
877
+ const height = viewportHeight / zoom;
878
+ return { minX, minY, width, height, viewportWidth, viewportHeight };
784
879
  }
785
- const updateCursorStatus = (board, cursor) => {
786
- if (cursor) {
787
- board.cursor = cursor;
788
- }
789
- };
790
-
791
- /**
792
- * Check whether to merge an operation into the previous operation.
793
- */
794
- const shouldMerge = (op, prev) => {
795
- if (op.type === 'set_viewport' && op.type === (prev === null || prev === void 0 ? void 0 : prev.type)) {
796
- return true;
797
- }
798
- return false;
799
- };
800
- /**
801
- * Check whether an operation needs to be saved to the history.
802
- */
803
- const shouldSave = (op, prev) => {
804
- if (op.type === 'set_selection' || op.type === 'set_viewport') {
805
- return false;
806
- }
807
- return true;
808
- };
809
- /**
810
- * Check whether an operation should clear the redos stack.
811
- */
812
- const shouldClear = (op) => {
813
- if (op.type === 'set_selection') {
814
- return false;
815
- }
816
- return true;
817
- };
818
- const PlaitHistoryBoard = {
819
- /**
820
- * Get the saving flag's current value.
821
- */
822
- isSaving(board) {
823
- return SAVING.get(board);
824
- },
825
- /**
826
- * Get the merge flag's current value.
827
- */
828
- isMerging(board) {
829
- return MERGING.get(board);
830
- },
831
- /**
832
- * Apply a series of changes inside a synchronous `fn`, without merging any of
833
- * the new operations into previous save point in the history.
834
- */
835
- withoutMerging(board, fn) {
836
- const prev = PlaitHistoryBoard.isMerging(board);
837
- MERGING.set(board, false);
838
- fn();
839
- MERGING.set(board, prev);
840
- },
841
- /**
842
- * Apply a series of changes inside a synchronous `fn`, without saving any of
843
- * their operations into the history.
844
- */
845
- withoutSaving(board, fn) {
846
- const prev = PlaitHistoryBoard.isSaving(board);
847
- SAVING.set(board, false);
848
- fn();
849
- SAVING.set(board, prev);
850
- }
851
- };
852
880
 
853
881
  function withHistory(board) {
854
882
  const { apply, keydown } = board;
@@ -1168,6 +1196,8 @@ class PlaitBoardComponent {
1168
1196
  this.destroy$ = new Subject();
1169
1197
  this.autoFitPadding = 8;
1170
1198
  this.isMoving = false;
1199
+ this.focusPoint = [];
1200
+ this.matrix = [];
1171
1201
  this.plaitValue = [];
1172
1202
  this.plaitPlugins = [];
1173
1203
  this.plaitChange = new EventEmitter();
@@ -1215,10 +1245,18 @@ class PlaitBoardComponent {
1215
1245
  if (this.board.operations.some(op => PlaitOperation.isSetViewportOperation(op))) {
1216
1246
  this.updateViewport();
1217
1247
  }
1248
+ if (this.board.operations.some(op => ['set_node', 'remove_node'].includes(op.type))) {
1249
+ this.calculateViewport();
1250
+ }
1218
1251
  this.plaitChange.emit(changeEvent);
1219
1252
  });
1220
1253
  this.hasInitialized = true;
1221
1254
  }
1255
+ setMatrix() {
1256
+ const viewBox = getViewBox(this.board);
1257
+ const zoom = this.board.viewport.zoom;
1258
+ this.matrix = [zoom, 0, 0, 0, zoom, 0, -this.scrollLeft - zoom * viewBox.minX, -this.scrollTop - zoom * viewBox.minY, 1];
1259
+ }
1222
1260
  ngOnChanges(changes) {
1223
1261
  if (this.hasInitialized) {
1224
1262
  const valueChange = changes['plaitValue'];
@@ -1364,6 +1402,39 @@ class PlaitBoardComponent {
1364
1402
  offsetYRatio: scrollTopRatio
1365
1403
  });
1366
1404
  }
1405
+ updateScroll() {
1406
+ const container = this.contentContainer.nativeElement;
1407
+ container.scrollTo({
1408
+ top: this.scrollTop,
1409
+ left: this.scrollLeft
1410
+ });
1411
+ }
1412
+ calculateViewport() {
1413
+ const viewBox = getViewBox(this.board);
1414
+ const { minX, minY, viewportWidth } = viewBox;
1415
+ const viewportBox = getViewportClientBox(this.board);
1416
+ const nweHhBox = calculateBBox(this.board);
1417
+ let scrollLeft = this.scrollLeft;
1418
+ let scrollTop = this.scrollTop;
1419
+ const zoom = this.board.viewport.zoom;
1420
+ const matrix = this.matrix;
1421
+ const focusPoint = this.focusPoint;
1422
+ if (matrix) {
1423
+ const g = [focusPoint[0] - viewportBox.x, focusPoint[1] - viewportBox.y, 1];
1424
+ const b = invert([], matrix);
1425
+ const x = transformMat3([], [g[0], g[1], 1], b);
1426
+ const k = [zoom, 0, 0, 0, zoom, 0, -zoom * minX, -zoom * minY, 1];
1427
+ const c = transformMat3([], x, k);
1428
+ scrollLeft = c[0] - g[0];
1429
+ scrollTop = c[1] - g[1];
1430
+ }
1431
+ else {
1432
+ scrollLeft = (viewportWidth - viewportBox.width) / 2;
1433
+ scrollTop = viewportBox.height / 2 - nweHhBox.top;
1434
+ }
1435
+ this.setScroll(scrollLeft, scrollTop);
1436
+ this.updateViewport();
1437
+ }
1367
1438
  viewportChange() {
1368
1439
  const viewBox = getViewBox(this.board);
1369
1440
  const offsetXRatio = this.board.viewport.offsetXRatio;
@@ -1379,15 +1450,13 @@ class PlaitBoardComponent {
1379
1450
  if (width > 0 && height > 0) {
1380
1451
  this.renderer2.setAttribute(this.host, 'viewBox', box.join());
1381
1452
  }
1382
- const container = this.contentContainer.nativeElement;
1383
- container.scrollTo({
1384
- top: this.scrollTop,
1385
- left: this.scrollLeft
1386
- });
1453
+ this.focusPoint = [viewportBox.x, viewportBox.y];
1454
+ this.setMatrix();
1387
1455
  }
1388
1456
  updateViewport() {
1389
1457
  this.resizeViewport();
1390
1458
  this.viewportChange();
1459
+ this.updateScroll();
1391
1460
  }
1392
1461
  // 拖拽模式
1393
1462
  changeMoveMode(cursorStatus) {
@@ -1562,5 +1631,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1562
1631
  * Generated bundle index. Do not edit.
1563
1632
  */
1564
1633
 
1565
- export { BOARD_TO_ON_CHANGE, BaseCursorStatus, CLIP_BOARD_FORMAT_KEY, FLUSHING, HOST_TO_ROUGH_SVG, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_SAFARI, IS_TEXT_EDITABLE, MERGING, NS, PLAIT_BOARD_TO_COMPONENT, Path, PlaitBoardComponent, PlaitElementComponent, PlaitHistoryBoard, PlaitModule, PlaitNode, PlaitOperation, PlaitToolbarComponent, SAVING, SCROLL_BAR_WIDTH, Transforms, Viewport, calculateBBox, calculateZoom, createG, createSVG, createText, distanceBetweenPointAndPoint, distanceBetweenPointAndSegment, getViewBox, getViewportClientBox, hotkeys, idCreator, inverse, isNoSelectionElement, isNullOrUndefined, isSetViewportOperation, rotate, shouldClear, shouldMerge, shouldSave, toPoint, toRectangleClient, transformPoint, transformPoints, updateCursorStatus };
1634
+ export { BOARD_TO_ON_CHANGE, BaseCursorStatus, CLIP_BOARD_FORMAT_KEY, FLUSHING, HOST_TO_ROUGH_SVG, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_SAFARI, IS_TEXT_EDITABLE, MERGING, NS, PLAIT_BOARD_TO_COMPONENT, Path, PlaitBoardComponent, PlaitElementComponent, PlaitHistoryBoard, PlaitModule, PlaitNode, PlaitOperation, PlaitToolbarComponent, SAVING, SCROLL_BAR_WIDTH, Transforms, Viewport, calculateBBox, calculateZoom, createG, createSVG, createText, distanceBetweenPointAndPoint, distanceBetweenPointAndSegment, getViewBox, getViewportClientBox, hotkeys, idCreator, inverse, invert, isNoSelectionElement, isNullOrUndefined, isSetViewportOperation, rotate, shouldClear, shouldMerge, shouldSave, toPoint, toRectangleClient, transformMat3, transformPoint, transformPoints, updateCursorStatus };
1566
1635
  //# sourceMappingURL=plait-core.mjs.map