@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.
- package/board/board.component.d.ts +5 -0
- package/esm2020/board/board.component.mjs +48 -7
- package/esm2020/interfaces/cursor.mjs +2 -1
- package/esm2020/utils/board.mjs +1 -58
- package/esm2020/utils/index.mjs +6 -5
- package/esm2020/utils/matrix.mjs +84 -0
- package/fesm2015/plait-core.mjs +174 -105
- package/fesm2015/plait-core.mjs.map +1 -1
- package/fesm2020/plait-core.mjs +173 -104
- package/fesm2020/plait-core.mjs.map +1 -1
- package/interfaces/cursor.d.ts +2 -1
- package/package.json +1 -1
- package/utils/board.d.ts +0 -6
- package/utils/index.d.ts +5 -4
- package/utils/matrix.d.ts +12 -0
package/fesm2020/plait-core.mjs
CHANGED
|
@@ -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
|
/**
|
|
@@ -534,6 +535,32 @@ function withBoard(board) {
|
|
|
534
535
|
return board;
|
|
535
536
|
}
|
|
536
537
|
|
|
538
|
+
function transformPoints(board, points) {
|
|
539
|
+
const newPoints = points.map(point => {
|
|
540
|
+
return transformPoint(board, point);
|
|
541
|
+
});
|
|
542
|
+
return newPoints;
|
|
543
|
+
}
|
|
544
|
+
function transformPoint(board, point) {
|
|
545
|
+
const { width, height } = board.host.getBoundingClientRect();
|
|
546
|
+
const viewBox = board.host.viewBox.baseVal;
|
|
547
|
+
const x = (point[0] / width) * viewBox.width + viewBox.x;
|
|
548
|
+
const y = (point[1] / height) * viewBox.height + viewBox.y;
|
|
549
|
+
const newPoint = [x, y];
|
|
550
|
+
return newPoint;
|
|
551
|
+
}
|
|
552
|
+
function calculateZoom(zoom, minZoom = 0.2, maxZoom = 4) {
|
|
553
|
+
return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
|
|
554
|
+
}
|
|
555
|
+
function isNoSelectionElement(e) {
|
|
556
|
+
return e.target?.closest('.plait-board-attached');
|
|
557
|
+
}
|
|
558
|
+
const updateCursorStatus = (board, cursor) => {
|
|
559
|
+
if (cursor) {
|
|
560
|
+
board.cursor = cursor;
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
|
|
537
564
|
const NS = 'http://www.w3.org/2000/svg';
|
|
538
565
|
function toPoint(x, y, container) {
|
|
539
566
|
const rect = container.getBoundingClientRect();
|
|
@@ -580,6 +607,68 @@ function toRectangleClient(points) {
|
|
|
580
607
|
return rect;
|
|
581
608
|
}
|
|
582
609
|
|
|
610
|
+
/**
|
|
611
|
+
* Check whether to merge an operation into the previous operation.
|
|
612
|
+
*/
|
|
613
|
+
const shouldMerge = (op, prev) => {
|
|
614
|
+
if (op.type === 'set_viewport' && op.type === prev?.type) {
|
|
615
|
+
return true;
|
|
616
|
+
}
|
|
617
|
+
return false;
|
|
618
|
+
};
|
|
619
|
+
/**
|
|
620
|
+
* Check whether an operation needs to be saved to the history.
|
|
621
|
+
*/
|
|
622
|
+
const shouldSave = (op, prev) => {
|
|
623
|
+
if (op.type === 'set_selection' || op.type === 'set_viewport') {
|
|
624
|
+
return false;
|
|
625
|
+
}
|
|
626
|
+
return true;
|
|
627
|
+
};
|
|
628
|
+
/**
|
|
629
|
+
* Check whether an operation should clear the redos stack.
|
|
630
|
+
*/
|
|
631
|
+
const shouldClear = (op) => {
|
|
632
|
+
if (op.type === 'set_selection') {
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
return true;
|
|
636
|
+
};
|
|
637
|
+
const PlaitHistoryBoard = {
|
|
638
|
+
/**
|
|
639
|
+
* Get the saving flag's current value.
|
|
640
|
+
*/
|
|
641
|
+
isSaving(board) {
|
|
642
|
+
return SAVING.get(board);
|
|
643
|
+
},
|
|
644
|
+
/**
|
|
645
|
+
* Get the merge flag's current value.
|
|
646
|
+
*/
|
|
647
|
+
isMerging(board) {
|
|
648
|
+
return MERGING.get(board);
|
|
649
|
+
},
|
|
650
|
+
/**
|
|
651
|
+
* Apply a series of changes inside a synchronous `fn`, without merging any of
|
|
652
|
+
* the new operations into previous save point in the history.
|
|
653
|
+
*/
|
|
654
|
+
withoutMerging(board, fn) {
|
|
655
|
+
const prev = PlaitHistoryBoard.isMerging(board);
|
|
656
|
+
MERGING.set(board, false);
|
|
657
|
+
fn();
|
|
658
|
+
MERGING.set(board, prev);
|
|
659
|
+
},
|
|
660
|
+
/**
|
|
661
|
+
* Apply a series of changes inside a synchronous `fn`, without saving any of
|
|
662
|
+
* their operations into the history.
|
|
663
|
+
*/
|
|
664
|
+
withoutSaving(board, fn) {
|
|
665
|
+
const prev = PlaitHistoryBoard.isSaving(board);
|
|
666
|
+
SAVING.set(board, false);
|
|
667
|
+
fn();
|
|
668
|
+
SAVING.set(board, prev);
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
|
|
583
672
|
/**
|
|
584
673
|
* Hotkey mappings for each platform.
|
|
585
674
|
*/
|
|
@@ -728,32 +817,27 @@ function distanceBetweenPointAndPoint(x1, y1, x2, y2) {
|
|
|
728
817
|
return Math.hypot(dx, dy);
|
|
729
818
|
}
|
|
730
819
|
|
|
731
|
-
function
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
820
|
+
function invert(oldMatrix, newMatrix) {
|
|
821
|
+
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;
|
|
822
|
+
return p
|
|
823
|
+
? ((p = 1 / p),
|
|
824
|
+
(oldMatrix[0] = d * p),
|
|
825
|
+
(oldMatrix[1] = (-u * r + a * s) * p),
|
|
826
|
+
(oldMatrix[2] = (c * r - a * o) * p),
|
|
827
|
+
(oldMatrix[3] = h * p),
|
|
828
|
+
(oldMatrix[4] = (u * n - a * l) * p),
|
|
829
|
+
(oldMatrix[5] = (-c * n + a * i) * p),
|
|
830
|
+
(oldMatrix[6] = f * p),
|
|
831
|
+
(oldMatrix[7] = (-s * n + r * l) * p),
|
|
832
|
+
(oldMatrix[8] = (o * n - r * i) * p),
|
|
833
|
+
oldMatrix)
|
|
834
|
+
: null;
|
|
736
835
|
}
|
|
737
|
-
function
|
|
738
|
-
const
|
|
739
|
-
const
|
|
740
|
-
const
|
|
741
|
-
|
|
742
|
-
const newPoint = [x, y];
|
|
743
|
-
return newPoint;
|
|
744
|
-
}
|
|
745
|
-
function getViewBox(board) {
|
|
746
|
-
const viewportBox = getViewportClientBox(board);
|
|
747
|
-
const rootGroupBBox = calculateBBox(board);
|
|
748
|
-
const padding = [viewportBox.height / 2, viewportBox.width / 2];
|
|
749
|
-
const zoom = board.viewport.zoom;
|
|
750
|
-
const minX = rootGroupBBox.left - padding[1] / zoom;
|
|
751
|
-
const minY = rootGroupBBox.top - padding[0] / zoom;
|
|
752
|
-
const viewportWidth = (rootGroupBBox.right - rootGroupBBox.left) * zoom + 2 * padding[1];
|
|
753
|
-
const viewportHeight = (rootGroupBBox.bottom - rootGroupBBox.top) * zoom + 2 * padding[0];
|
|
754
|
-
const width = viewportWidth / zoom;
|
|
755
|
-
const height = viewportHeight / zoom;
|
|
756
|
-
return { minX, minY, width, height, viewportWidth, viewportHeight };
|
|
836
|
+
function transformMat3(e, t, n) {
|
|
837
|
+
const r = t[0];
|
|
838
|
+
const a = t[1];
|
|
839
|
+
const i = t[2];
|
|
840
|
+
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;
|
|
757
841
|
}
|
|
758
842
|
function getViewportClientBox(board) {
|
|
759
843
|
const hideScrollbar = board.options.hideScrollbar;
|
|
@@ -762,9 +846,13 @@ function getViewportClientBox(board) {
|
|
|
762
846
|
const containerRect = container?.getBoundingClientRect();
|
|
763
847
|
const width = containerRect.width - scrollBarWidth;
|
|
764
848
|
const height = containerRect.height - scrollBarWidth;
|
|
849
|
+
const x = containerRect.x || containerRect.left;
|
|
850
|
+
const y = containerRect.y || containerRect.top;
|
|
765
851
|
return {
|
|
766
852
|
width,
|
|
767
|
-
height
|
|
853
|
+
height,
|
|
854
|
+
x,
|
|
855
|
+
y
|
|
768
856
|
};
|
|
769
857
|
}
|
|
770
858
|
function calculateBBox(board) {
|
|
@@ -798,79 +886,19 @@ function calculateBBox(board) {
|
|
|
798
886
|
// 在新的缩放比容器宽高下的内容盒子位置
|
|
799
887
|
return box;
|
|
800
888
|
}
|
|
801
|
-
function
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
889
|
+
function getViewBox(board) {
|
|
890
|
+
const viewportBox = getViewportClientBox(board);
|
|
891
|
+
const rootGroupBBox = calculateBBox(board);
|
|
892
|
+
const padding = [viewportBox.height / 2, viewportBox.width / 2];
|
|
893
|
+
const zoom = board.viewport.zoom;
|
|
894
|
+
const minX = rootGroupBBox.left - padding[1] / zoom;
|
|
895
|
+
const minY = rootGroupBBox.top - padding[0] / zoom;
|
|
896
|
+
const viewportWidth = (rootGroupBBox.right - rootGroupBBox.left) * zoom + 2 * padding[1];
|
|
897
|
+
const viewportHeight = (rootGroupBBox.bottom - rootGroupBBox.top) * zoom + 2 * padding[0];
|
|
898
|
+
const width = viewportWidth / zoom;
|
|
899
|
+
const height = viewportHeight / zoom;
|
|
900
|
+
return { minX, minY, width, height, viewportWidth, viewportHeight };
|
|
806
901
|
}
|
|
807
|
-
const updateCursorStatus = (board, cursor) => {
|
|
808
|
-
if (cursor) {
|
|
809
|
-
board.cursor = cursor;
|
|
810
|
-
}
|
|
811
|
-
};
|
|
812
|
-
|
|
813
|
-
/**
|
|
814
|
-
* Check whether to merge an operation into the previous operation.
|
|
815
|
-
*/
|
|
816
|
-
const shouldMerge = (op, prev) => {
|
|
817
|
-
if (op.type === 'set_viewport' && op.type === prev?.type) {
|
|
818
|
-
return true;
|
|
819
|
-
}
|
|
820
|
-
return false;
|
|
821
|
-
};
|
|
822
|
-
/**
|
|
823
|
-
* Check whether an operation needs to be saved to the history.
|
|
824
|
-
*/
|
|
825
|
-
const shouldSave = (op, prev) => {
|
|
826
|
-
if (op.type === 'set_selection' || op.type === 'set_viewport') {
|
|
827
|
-
return false;
|
|
828
|
-
}
|
|
829
|
-
return true;
|
|
830
|
-
};
|
|
831
|
-
/**
|
|
832
|
-
* Check whether an operation should clear the redos stack.
|
|
833
|
-
*/
|
|
834
|
-
const shouldClear = (op) => {
|
|
835
|
-
if (op.type === 'set_selection') {
|
|
836
|
-
return false;
|
|
837
|
-
}
|
|
838
|
-
return true;
|
|
839
|
-
};
|
|
840
|
-
const PlaitHistoryBoard = {
|
|
841
|
-
/**
|
|
842
|
-
* Get the saving flag's current value.
|
|
843
|
-
*/
|
|
844
|
-
isSaving(board) {
|
|
845
|
-
return SAVING.get(board);
|
|
846
|
-
},
|
|
847
|
-
/**
|
|
848
|
-
* Get the merge flag's current value.
|
|
849
|
-
*/
|
|
850
|
-
isMerging(board) {
|
|
851
|
-
return MERGING.get(board);
|
|
852
|
-
},
|
|
853
|
-
/**
|
|
854
|
-
* Apply a series of changes inside a synchronous `fn`, without merging any of
|
|
855
|
-
* the new operations into previous save point in the history.
|
|
856
|
-
*/
|
|
857
|
-
withoutMerging(board, fn) {
|
|
858
|
-
const prev = PlaitHistoryBoard.isMerging(board);
|
|
859
|
-
MERGING.set(board, false);
|
|
860
|
-
fn();
|
|
861
|
-
MERGING.set(board, prev);
|
|
862
|
-
},
|
|
863
|
-
/**
|
|
864
|
-
* Apply a series of changes inside a synchronous `fn`, without saving any of
|
|
865
|
-
* their operations into the history.
|
|
866
|
-
*/
|
|
867
|
-
withoutSaving(board, fn) {
|
|
868
|
-
const prev = PlaitHistoryBoard.isSaving(board);
|
|
869
|
-
SAVING.set(board, false);
|
|
870
|
-
fn();
|
|
871
|
-
SAVING.set(board, prev);
|
|
872
|
-
}
|
|
873
|
-
};
|
|
874
902
|
|
|
875
903
|
function withHistory(board) {
|
|
876
904
|
const { apply, keydown } = board;
|
|
@@ -1190,6 +1218,8 @@ class PlaitBoardComponent {
|
|
|
1190
1218
|
this.destroy$ = new Subject();
|
|
1191
1219
|
this.autoFitPadding = 8;
|
|
1192
1220
|
this.isMoving = false;
|
|
1221
|
+
this.focusPoint = [];
|
|
1222
|
+
this.matrix = [];
|
|
1193
1223
|
this.plaitValue = [];
|
|
1194
1224
|
this.plaitPlugins = [];
|
|
1195
1225
|
this.plaitChange = new EventEmitter();
|
|
@@ -1236,10 +1266,18 @@ class PlaitBoardComponent {
|
|
|
1236
1266
|
if (this.board.operations.some(op => PlaitOperation.isSetViewportOperation(op))) {
|
|
1237
1267
|
this.updateViewport();
|
|
1238
1268
|
}
|
|
1269
|
+
if (this.board.operations.some(op => ['set_node', 'remove_node'].includes(op.type))) {
|
|
1270
|
+
this.calculateViewport();
|
|
1271
|
+
}
|
|
1239
1272
|
this.plaitChange.emit(changeEvent);
|
|
1240
1273
|
});
|
|
1241
1274
|
this.hasInitialized = true;
|
|
1242
1275
|
}
|
|
1276
|
+
setMatrix() {
|
|
1277
|
+
const viewBox = getViewBox(this.board);
|
|
1278
|
+
const zoom = this.board.viewport.zoom;
|
|
1279
|
+
this.matrix = [zoom, 0, 0, 0, zoom, 0, -this.scrollLeft - zoom * viewBox.minX, -this.scrollTop - zoom * viewBox.minY, 1];
|
|
1280
|
+
}
|
|
1243
1281
|
ngOnChanges(changes) {
|
|
1244
1282
|
if (this.hasInitialized) {
|
|
1245
1283
|
const valueChange = changes['plaitValue'];
|
|
@@ -1379,6 +1417,39 @@ class PlaitBoardComponent {
|
|
|
1379
1417
|
offsetYRatio: scrollTopRatio
|
|
1380
1418
|
});
|
|
1381
1419
|
}
|
|
1420
|
+
updateScroll() {
|
|
1421
|
+
const container = this.contentContainer.nativeElement;
|
|
1422
|
+
container.scrollTo({
|
|
1423
|
+
top: this.scrollTop,
|
|
1424
|
+
left: this.scrollLeft
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
calculateViewport() {
|
|
1428
|
+
const viewBox = getViewBox(this.board);
|
|
1429
|
+
const { minX, minY, viewportWidth } = viewBox;
|
|
1430
|
+
const viewportBox = getViewportClientBox(this.board);
|
|
1431
|
+
const nweHhBox = calculateBBox(this.board);
|
|
1432
|
+
let scrollLeft = this.scrollLeft;
|
|
1433
|
+
let scrollTop = this.scrollTop;
|
|
1434
|
+
const zoom = this.board.viewport.zoom;
|
|
1435
|
+
const matrix = this.matrix;
|
|
1436
|
+
const focusPoint = this.focusPoint;
|
|
1437
|
+
if (matrix) {
|
|
1438
|
+
const g = [focusPoint[0] - viewportBox.x, focusPoint[1] - viewportBox.y, 1];
|
|
1439
|
+
const b = invert([], matrix);
|
|
1440
|
+
const x = transformMat3([], [g[0], g[1], 1], b);
|
|
1441
|
+
const k = [zoom, 0, 0, 0, zoom, 0, -zoom * minX, -zoom * minY, 1];
|
|
1442
|
+
const c = transformMat3([], x, k);
|
|
1443
|
+
scrollLeft = c[0] - g[0];
|
|
1444
|
+
scrollTop = c[1] - g[1];
|
|
1445
|
+
}
|
|
1446
|
+
else {
|
|
1447
|
+
scrollLeft = (viewportWidth - viewportBox.width) / 2;
|
|
1448
|
+
scrollTop = viewportBox.height / 2 - nweHhBox.top;
|
|
1449
|
+
}
|
|
1450
|
+
this.setScroll(scrollLeft, scrollTop);
|
|
1451
|
+
this.updateViewport();
|
|
1452
|
+
}
|
|
1382
1453
|
viewportChange() {
|
|
1383
1454
|
const viewBox = getViewBox(this.board);
|
|
1384
1455
|
const offsetXRatio = this.board.viewport.offsetXRatio;
|
|
@@ -1394,15 +1465,13 @@ class PlaitBoardComponent {
|
|
|
1394
1465
|
if (width > 0 && height > 0) {
|
|
1395
1466
|
this.renderer2.setAttribute(this.host, 'viewBox', box.join());
|
|
1396
1467
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
top: this.scrollTop,
|
|
1400
|
-
left: this.scrollLeft
|
|
1401
|
-
});
|
|
1468
|
+
this.focusPoint = [viewportBox.x, viewportBox.y];
|
|
1469
|
+
this.setMatrix();
|
|
1402
1470
|
}
|
|
1403
1471
|
updateViewport() {
|
|
1404
1472
|
this.resizeViewport();
|
|
1405
1473
|
this.viewportChange();
|
|
1474
|
+
this.updateScroll();
|
|
1406
1475
|
}
|
|
1407
1476
|
// 拖拽模式
|
|
1408
1477
|
changeMoveMode(cursorStatus) {
|
|
@@ -1579,5 +1648,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
|
|
|
1579
1648
|
* Generated bundle index. Do not edit.
|
|
1580
1649
|
*/
|
|
1581
1650
|
|
|
1582
|
-
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 };
|
|
1651
|
+
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 };
|
|
1583
1652
|
//# sourceMappingURL=plait-core.mjs.map
|