@plait/core 0.0.42 → 0.0.43
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 +14 -8
- package/constants/index.d.ts +1 -0
- package/core/element/element.component.d.ts +1 -2
- package/core/toolbar/toolbar.component.d.ts +3 -1
- package/esm2020/board/board.component.mjs +141 -97
- package/esm2020/constants/index.mjs +2 -1
- package/esm2020/core/element/element.component.mjs +1 -12
- package/esm2020/core/toolbar/toolbar.component.mjs +8 -1
- package/esm2020/interfaces/viewport.mjs +3 -3
- package/esm2020/plugins/create-board.mjs +5 -5
- package/esm2020/plugins/with-move.mjs +2 -9
- package/esm2020/utils/board.mjs +60 -13
- package/esm2020/utils/dom.mjs +1 -1
- package/fesm2015/plait-core.mjs +274 -181
- package/fesm2015/plait-core.mjs.map +1 -1
- package/fesm2020/plait-core.mjs +272 -191
- package/fesm2020/plait-core.mjs.map +1 -1
- package/interfaces/viewport.d.ts +2 -2
- package/package.json +1 -1
- package/plugins/create-board.d.ts +1 -1
- package/styles/styles.scss +6 -0
- package/utils/board.d.ts +8 -0
package/fesm2020/plait-core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { Component, ChangeDetectionStrategy, Input, EventEmitter, HostBinding, Output, ElementRef, ViewChild, ContentChild, NgModule } from '@angular/core';
|
|
3
3
|
import rough from 'roughjs/bin/rough';
|
|
4
4
|
import { Subject, fromEvent } from 'rxjs';
|
|
5
5
|
import { takeUntil, filter } from 'rxjs/operators';
|
|
@@ -8,6 +8,9 @@ import { isKeyHotkey, isHotkey } from 'is-hotkey';
|
|
|
8
8
|
import * as i1 from '@angular/common';
|
|
9
9
|
import { BrowserModule } from '@angular/platform-browser';
|
|
10
10
|
|
|
11
|
+
const CLIP_BOARD_FORMAT_KEY = 'x-plait-fragment';
|
|
12
|
+
const SCROLL_BAR_WIDTH = 20;
|
|
13
|
+
|
|
11
14
|
var BaseCursorStatus;
|
|
12
15
|
(function (BaseCursorStatus) {
|
|
13
16
|
BaseCursorStatus["move"] = "move";
|
|
@@ -255,8 +258,8 @@ function isNullOrUndefined(value) {
|
|
|
255
258
|
|
|
256
259
|
const Viewport = {
|
|
257
260
|
isViewport: (value) => {
|
|
258
|
-
return (!isNullOrUndefined(value.
|
|
259
|
-
!isNullOrUndefined(value.
|
|
261
|
+
return (!isNullOrUndefined(value.offsetXRatio) &&
|
|
262
|
+
!isNullOrUndefined(value.offsetYRatio) &&
|
|
260
263
|
!isNullOrUndefined(value.zoom) &&
|
|
261
264
|
!isNullOrUndefined(value.viewBackgroundColor));
|
|
262
265
|
}
|
|
@@ -265,13 +268,6 @@ const Viewport = {
|
|
|
265
268
|
const SAVING = new WeakMap();
|
|
266
269
|
const MERGING = new WeakMap();
|
|
267
270
|
|
|
268
|
-
// record richtext type status
|
|
269
|
-
const FLUSHING = new WeakMap();
|
|
270
|
-
const IS_TEXT_EDITABLE = new WeakMap();
|
|
271
|
-
const BOARD_TO_ON_CHANGE = new WeakMap();
|
|
272
|
-
const HOST_TO_ROUGH_SVG = new WeakMap();
|
|
273
|
-
const PLAIT_BOARD_TO_COMPONENT = new WeakMap();
|
|
274
|
-
|
|
275
271
|
const applyToDraft = (board, selection, viewport, op) => {
|
|
276
272
|
switch (op.type) {
|
|
277
273
|
case 'insert_node': {
|
|
@@ -466,12 +462,19 @@ const Transforms = {
|
|
|
466
462
|
...NodeTransforms
|
|
467
463
|
};
|
|
468
464
|
|
|
465
|
+
// record richtext type status
|
|
466
|
+
const FLUSHING = new WeakMap();
|
|
467
|
+
const IS_TEXT_EDITABLE = new WeakMap();
|
|
468
|
+
const BOARD_TO_ON_CHANGE = new WeakMap();
|
|
469
|
+
const HOST_TO_ROUGH_SVG = new WeakMap();
|
|
470
|
+
const PLAIT_BOARD_TO_COMPONENT = new WeakMap();
|
|
471
|
+
|
|
469
472
|
function createBoard(host, children, options) {
|
|
470
473
|
const board = {
|
|
471
474
|
host,
|
|
472
475
|
viewport: {
|
|
473
|
-
|
|
474
|
-
|
|
476
|
+
offsetXRatio: 0.5,
|
|
477
|
+
offsetYRatio: 0.5,
|
|
475
478
|
zoom: 1,
|
|
476
479
|
viewBackgroundColor: '#000'
|
|
477
480
|
},
|
|
@@ -729,22 +732,68 @@ function transformPoints(board, points) {
|
|
|
729
732
|
return newPoints;
|
|
730
733
|
}
|
|
731
734
|
function transformPoint(board, point) {
|
|
732
|
-
const { width, height } = board.host.getBoundingClientRect();
|
|
733
735
|
const viewBox = getViewBox(board);
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
const newPoint = [x
|
|
736
|
+
const x = (point[0] / viewBox.viewportWidth) * viewBox.width + viewBox.minX;
|
|
737
|
+
const y = (point[1] / viewBox.viewportHeight) * viewBox.height + viewBox.minY;
|
|
738
|
+
const newPoint = [x, y];
|
|
737
739
|
return newPoint;
|
|
738
740
|
}
|
|
739
741
|
function getViewBox(board) {
|
|
740
|
-
const
|
|
741
|
-
const
|
|
742
|
-
const
|
|
743
|
-
const
|
|
744
|
-
const
|
|
745
|
-
const
|
|
746
|
-
const
|
|
747
|
-
|
|
742
|
+
const viewportBox = getViewportClientBox(board);
|
|
743
|
+
const rootGroupBBox = calculateBBox(board);
|
|
744
|
+
const padding = [viewportBox.height / 2, viewportBox.width / 2];
|
|
745
|
+
const zoom = board.viewport.zoom;
|
|
746
|
+
const minX = rootGroupBBox.left - padding[1] / zoom;
|
|
747
|
+
const minY = rootGroupBBox.top - padding[0] / zoom;
|
|
748
|
+
const viewportWidth = (rootGroupBBox.right - rootGroupBBox.left) * zoom + 2 * padding[1];
|
|
749
|
+
const viewportHeight = (rootGroupBBox.bottom - rootGroupBBox.top) * zoom + 2 * padding[0];
|
|
750
|
+
const width = viewportWidth / zoom;
|
|
751
|
+
const height = viewportHeight / zoom;
|
|
752
|
+
return { minX, minY, width, height, viewportWidth, viewportHeight };
|
|
753
|
+
}
|
|
754
|
+
function getViewportClientBox(board) {
|
|
755
|
+
const container = board.host?.parentElement;
|
|
756
|
+
const containerRect = container?.getBoundingClientRect();
|
|
757
|
+
const width = containerRect.width - SCROLL_BAR_WIDTH;
|
|
758
|
+
const height = containerRect.height - SCROLL_BAR_WIDTH;
|
|
759
|
+
return {
|
|
760
|
+
width,
|
|
761
|
+
height
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
function calculateBBox(board) {
|
|
765
|
+
const viewportBox = getViewportClientBox(board);
|
|
766
|
+
const rootGroup = board.host.firstChild;
|
|
767
|
+
const zoom = board.viewport.zoom;
|
|
768
|
+
const rootGroupBox = rootGroup.getBBox();
|
|
769
|
+
let box = {};
|
|
770
|
+
const containerWidth = viewportBox.width / zoom;
|
|
771
|
+
const containerHeight = viewportBox.height / zoom;
|
|
772
|
+
if (rootGroupBox.width < containerWidth) {
|
|
773
|
+
const offsetX = rootGroupBox.x + rootGroupBox.width / 2;
|
|
774
|
+
const containerX = containerWidth / 2;
|
|
775
|
+
box.left = offsetX - containerX;
|
|
776
|
+
box.right = offsetX + containerX;
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
box.left = rootGroupBox.x;
|
|
780
|
+
box.right = rootGroupBox.x + rootGroupBox.width;
|
|
781
|
+
}
|
|
782
|
+
if (rootGroupBox.height < containerHeight) {
|
|
783
|
+
const offsetY = rootGroupBox.y + rootGroupBox.height / 2;
|
|
784
|
+
const containerY = containerHeight / 2;
|
|
785
|
+
box.top = offsetY - containerY;
|
|
786
|
+
box.bottom = offsetY + containerY;
|
|
787
|
+
}
|
|
788
|
+
else {
|
|
789
|
+
box.top = rootGroupBox.y;
|
|
790
|
+
box.bottom = rootGroupBox.y + rootGroupBox.height;
|
|
791
|
+
}
|
|
792
|
+
// 在新的缩放比容器宽高下的内容盒子位置
|
|
793
|
+
return box;
|
|
794
|
+
}
|
|
795
|
+
function calculateZoom(zoom, minZoom = 0.2, maxZoom = 4) {
|
|
796
|
+
return zoom < minZoom ? minZoom : zoom > maxZoom ? maxZoom : zoom;
|
|
748
797
|
}
|
|
749
798
|
function isNoSelectionElement(e) {
|
|
750
799
|
return e.target?.closest('.plait-board-attached');
|
|
@@ -938,12 +987,6 @@ function withMove(board) {
|
|
|
938
987
|
board.mousemove = (event) => {
|
|
939
988
|
const boardComponent = PLAIT_BOARD_TO_COMPONENT.get(board);
|
|
940
989
|
if (board.cursor === BaseCursorStatus.move && board.selection && boardComponent.isMoving) {
|
|
941
|
-
const viewport = board?.viewport;
|
|
942
|
-
Transforms.setViewport(board, {
|
|
943
|
-
...viewport,
|
|
944
|
-
offsetX: viewport.offsetX + ((event.x - plaitBoardMove.x) * 100) / transformZoom(board.viewport.zoom),
|
|
945
|
-
offsetY: viewport.offsetY + ((event.y - plaitBoardMove.y) * 100) / transformZoom(board.viewport.zoom)
|
|
946
|
-
});
|
|
947
990
|
plaitBoardMove.x = event.x;
|
|
948
991
|
plaitBoardMove.y = event.y;
|
|
949
992
|
}
|
|
@@ -1021,8 +1064,65 @@ function withSelection(board) {
|
|
|
1021
1064
|
return board;
|
|
1022
1065
|
}
|
|
1023
1066
|
|
|
1067
|
+
class PlaitElementComponent {
|
|
1068
|
+
constructor(renderer2, viewContainerRef) {
|
|
1069
|
+
this.renderer2 = renderer2;
|
|
1070
|
+
this.viewContainerRef = viewContainerRef;
|
|
1071
|
+
this.initialized = false;
|
|
1072
|
+
this.selection = null;
|
|
1073
|
+
}
|
|
1074
|
+
ngOnInit() {
|
|
1075
|
+
this.initialize();
|
|
1076
|
+
this.drawElement();
|
|
1077
|
+
}
|
|
1078
|
+
initialize() {
|
|
1079
|
+
this.initialized = true;
|
|
1080
|
+
this.groupG = createG();
|
|
1081
|
+
this.renderer2.setAttribute(this.groupG, 'plait-element-group', this.index.toString());
|
|
1082
|
+
this.host.append(this.groupG);
|
|
1083
|
+
}
|
|
1084
|
+
drawElement() {
|
|
1085
|
+
const gArray = this.board.drawElement({ elementInstance: this });
|
|
1086
|
+
gArray.forEach(g => {
|
|
1087
|
+
this.groupG.appendChild(g);
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
ngOnChanges(changes) {
|
|
1091
|
+
if (this.initialized) {
|
|
1092
|
+
this.board.redrawElement({ elementInstance: this }, changes);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
ngOnDestroy() {
|
|
1096
|
+
this.board.destroyElement();
|
|
1097
|
+
this.groupG.remove();
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
PlaitElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitElementComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1101
|
+
PlaitElementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: PlaitElementComponent, selector: "plait-element", inputs: { index: "index", element: "element", board: "board", viewport: "viewport", selection: "selection", host: "host" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1102
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitElementComponent, decorators: [{
|
|
1103
|
+
type: Component,
|
|
1104
|
+
args: [{
|
|
1105
|
+
selector: 'plait-element',
|
|
1106
|
+
template: '',
|
|
1107
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
1108
|
+
}]
|
|
1109
|
+
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ViewContainerRef }]; }, propDecorators: { index: [{
|
|
1110
|
+
type: Input
|
|
1111
|
+
}], element: [{
|
|
1112
|
+
type: Input
|
|
1113
|
+
}], board: [{
|
|
1114
|
+
type: Input
|
|
1115
|
+
}], viewport: [{
|
|
1116
|
+
type: Input
|
|
1117
|
+
}], selection: [{
|
|
1118
|
+
type: Input
|
|
1119
|
+
}], host: [{
|
|
1120
|
+
type: Input
|
|
1121
|
+
}] } });
|
|
1122
|
+
|
|
1024
1123
|
class PlaitToolbarComponent {
|
|
1025
1124
|
constructor() {
|
|
1125
|
+
this._viewZoom = 100;
|
|
1026
1126
|
this.hostClass = `plait-board-toolbar`;
|
|
1027
1127
|
this.moveHandle = new EventEmitter();
|
|
1028
1128
|
this.adaptHandle = new EventEmitter();
|
|
@@ -1030,6 +1130,12 @@ class PlaitToolbarComponent {
|
|
|
1030
1130
|
this.zoomOutHandle = new EventEmitter();
|
|
1031
1131
|
this.resetZoomHandel = new EventEmitter();
|
|
1032
1132
|
}
|
|
1133
|
+
set viewZoom(zoom) {
|
|
1134
|
+
this._viewZoom = Math.floor(zoom * 100);
|
|
1135
|
+
}
|
|
1136
|
+
get viewZoom() {
|
|
1137
|
+
return this._viewZoom;
|
|
1138
|
+
}
|
|
1033
1139
|
dragMove() {
|
|
1034
1140
|
if (this.cursorStatus !== BaseCursorStatus.move) {
|
|
1035
1141
|
this.moveHandle.emit(BaseCursorStatus.move);
|
|
@@ -1078,81 +1184,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
|
|
|
1078
1184
|
type: Output
|
|
1079
1185
|
}] } });
|
|
1080
1186
|
|
|
1081
|
-
class PlaitElementComponent {
|
|
1082
|
-
constructor(renderer2, viewContainerRef) {
|
|
1083
|
-
this.renderer2 = renderer2;
|
|
1084
|
-
this.viewContainerRef = viewContainerRef;
|
|
1085
|
-
this.initialized = false;
|
|
1086
|
-
this.selection = null;
|
|
1087
|
-
}
|
|
1088
|
-
ngOnInit() {
|
|
1089
|
-
this.initialize();
|
|
1090
|
-
this.transform(true);
|
|
1091
|
-
this.drawElement();
|
|
1092
|
-
}
|
|
1093
|
-
initialize() {
|
|
1094
|
-
this.initialized = true;
|
|
1095
|
-
this.groupG = createG();
|
|
1096
|
-
this.renderer2.setAttribute(this.groupG, 'plait-element-group', this.index.toString());
|
|
1097
|
-
this.host.append(this.groupG);
|
|
1098
|
-
}
|
|
1099
|
-
transform(first = false) {
|
|
1100
|
-
if (first && this.viewport.offsetX === 0 && this.viewport.offsetY === 0) {
|
|
1101
|
-
return;
|
|
1102
|
-
}
|
|
1103
|
-
this.renderer2.setAttribute(this.groupG, 'transform', `translate(${this.viewport.offsetX} ${this.viewport.offsetY})`);
|
|
1104
|
-
}
|
|
1105
|
-
drawElement() {
|
|
1106
|
-
const gArray = this.board.drawElement({ elementInstance: this });
|
|
1107
|
-
gArray.forEach(g => {
|
|
1108
|
-
this.groupG.appendChild(g);
|
|
1109
|
-
});
|
|
1110
|
-
}
|
|
1111
|
-
ngOnChanges(changes) {
|
|
1112
|
-
const viewport = changes['viewport'];
|
|
1113
|
-
if (this.initialized && viewport) {
|
|
1114
|
-
this.transform();
|
|
1115
|
-
}
|
|
1116
|
-
if (this.initialized) {
|
|
1117
|
-
this.board.redrawElement({ elementInstance: this }, changes);
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
ngOnDestroy() {
|
|
1121
|
-
this.board.destroyElement();
|
|
1122
|
-
this.groupG.remove();
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
PlaitElementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitElementComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1126
|
-
PlaitElementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: PlaitElementComponent, selector: "plait-element", inputs: { index: "index", element: "element", board: "board", viewport: "viewport", selection: "selection", host: "host" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1127
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitElementComponent, decorators: [{
|
|
1128
|
-
type: Component,
|
|
1129
|
-
args: [{
|
|
1130
|
-
selector: 'plait-element',
|
|
1131
|
-
template: '',
|
|
1132
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
1133
|
-
}]
|
|
1134
|
-
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ViewContainerRef }]; }, propDecorators: { index: [{
|
|
1135
|
-
type: Input
|
|
1136
|
-
}], element: [{
|
|
1137
|
-
type: Input
|
|
1138
|
-
}], board: [{
|
|
1139
|
-
type: Input
|
|
1140
|
-
}], viewport: [{
|
|
1141
|
-
type: Input
|
|
1142
|
-
}], selection: [{
|
|
1143
|
-
type: Input
|
|
1144
|
-
}], host: [{
|
|
1145
|
-
type: Input
|
|
1146
|
-
}] } });
|
|
1147
|
-
|
|
1148
1187
|
class PlaitBoardComponent {
|
|
1149
|
-
constructor(cdr, renderer2) {
|
|
1188
|
+
constructor(cdr, renderer2, elementRef) {
|
|
1150
1189
|
this.cdr = cdr;
|
|
1151
1190
|
this.renderer2 = renderer2;
|
|
1191
|
+
this.elementRef = elementRef;
|
|
1152
1192
|
this.hasInitialized = false;
|
|
1153
1193
|
this.destroy$ = new Subject();
|
|
1154
|
-
this._viewZoom = 100;
|
|
1155
1194
|
this.isMoving = false;
|
|
1195
|
+
this.autoFitPadding = 8;
|
|
1156
1196
|
this.plaitValue = [];
|
|
1157
1197
|
this.plaitPlugins = [];
|
|
1158
1198
|
this.plaitReadonly = false;
|
|
@@ -1163,16 +1203,6 @@ class PlaitBoardComponent {
|
|
|
1163
1203
|
return index;
|
|
1164
1204
|
};
|
|
1165
1205
|
}
|
|
1166
|
-
get hostClass() {
|
|
1167
|
-
return `plait-board-container ${this.board.cursor}`;
|
|
1168
|
-
}
|
|
1169
|
-
get viewZoom() {
|
|
1170
|
-
const vZoom = transformZoom(this.board.viewport.zoom);
|
|
1171
|
-
if (this._viewZoom !== vZoom) {
|
|
1172
|
-
this._viewZoom = vZoom;
|
|
1173
|
-
}
|
|
1174
|
-
return vZoom;
|
|
1175
|
-
}
|
|
1176
1206
|
get isMoveMode() {
|
|
1177
1207
|
return this.board.cursor === BaseCursorStatus.move;
|
|
1178
1208
|
}
|
|
@@ -1182,6 +1212,9 @@ class PlaitBoardComponent {
|
|
|
1182
1212
|
get isFocused() {
|
|
1183
1213
|
return this.board?.selection;
|
|
1184
1214
|
}
|
|
1215
|
+
get hostClass() {
|
|
1216
|
+
return `plait-board-container ${this.board.cursor}`;
|
|
1217
|
+
}
|
|
1185
1218
|
get readonly() {
|
|
1186
1219
|
return this.plaitReadonly;
|
|
1187
1220
|
}
|
|
@@ -1196,7 +1229,6 @@ class PlaitBoardComponent {
|
|
|
1196
1229
|
HOST_TO_ROUGH_SVG.set(this.host, roughSVG);
|
|
1197
1230
|
this.initializePlugins();
|
|
1198
1231
|
this.initializeEvents();
|
|
1199
|
-
this.updateViewport();
|
|
1200
1232
|
PLAIT_BOARD_TO_COMPONENT.set(this.board, this);
|
|
1201
1233
|
BOARD_TO_ON_CHANGE.set(this.board, () => {
|
|
1202
1234
|
this.cdr.detectChanges();
|
|
@@ -1206,10 +1238,7 @@ class PlaitBoardComponent {
|
|
|
1206
1238
|
viewport: this.board.viewport,
|
|
1207
1239
|
selection: this.board.selection
|
|
1208
1240
|
};
|
|
1209
|
-
|
|
1210
|
-
if (this.board.operations.some(op => PlaitOperation.isSetViewportOperation(op))) {
|
|
1211
|
-
this.updateViewport();
|
|
1212
|
-
}
|
|
1241
|
+
this.updateViewport();
|
|
1213
1242
|
this.plaitChange.emit(changeEvent);
|
|
1214
1243
|
});
|
|
1215
1244
|
this.hasInitialized = true;
|
|
@@ -1223,6 +1252,8 @@ class PlaitBoardComponent {
|
|
|
1223
1252
|
}
|
|
1224
1253
|
ngAfterViewInit() {
|
|
1225
1254
|
this.plaitBoardInitialized.emit(this.board);
|
|
1255
|
+
this.initContainerSize();
|
|
1256
|
+
this.updateViewport();
|
|
1226
1257
|
}
|
|
1227
1258
|
initializePlugins() {
|
|
1228
1259
|
const options = { readonly: this.plaitReadonly, allowClearBoard: this.plaitAllowClearBoard };
|
|
@@ -1256,19 +1287,6 @@ class PlaitBoardComponent {
|
|
|
1256
1287
|
.subscribe((event) => {
|
|
1257
1288
|
this.board.dblclick(event);
|
|
1258
1289
|
});
|
|
1259
|
-
fromEvent(this.host, 'wheel')
|
|
1260
|
-
.pipe(takeUntil(this.destroy$))
|
|
1261
|
-
.subscribe((event) => {
|
|
1262
|
-
if (this.isFocused) {
|
|
1263
|
-
event.preventDefault();
|
|
1264
|
-
const viewport = this.board.viewport;
|
|
1265
|
-
Transforms.setViewport(this.board, {
|
|
1266
|
-
...viewport,
|
|
1267
|
-
offsetX: viewport?.offsetX - event.deltaX,
|
|
1268
|
-
offsetY: viewport?.offsetY - event.deltaY
|
|
1269
|
-
});
|
|
1270
|
-
}
|
|
1271
|
-
});
|
|
1272
1290
|
fromEvent(document, 'keydown')
|
|
1273
1291
|
.pipe(takeUntil(this.destroy$), filter(() => {
|
|
1274
1292
|
return !IS_TEXT_EDITABLE.get(this.board) && !!this.board.selection;
|
|
@@ -1307,18 +1325,70 @@ class PlaitBoardComponent {
|
|
|
1307
1325
|
this.board?.setFragment(event.clipboardData);
|
|
1308
1326
|
this.board?.deleteFragment(event.clipboardData);
|
|
1309
1327
|
});
|
|
1328
|
+
fromEvent(this.contentContainer.nativeElement, 'scroll')
|
|
1329
|
+
.pipe(takeUntil(this.destroy$), filter(() => {
|
|
1330
|
+
return !!this.isFocused;
|
|
1331
|
+
}))
|
|
1332
|
+
.subscribe((event) => {
|
|
1333
|
+
const scrollLeft = event.target.scrollLeft;
|
|
1334
|
+
const scrollTop = event.target.scrollTop;
|
|
1335
|
+
this.getScrollOffset(scrollLeft, scrollTop);
|
|
1336
|
+
this.setScroll(scrollLeft, scrollTop);
|
|
1337
|
+
});
|
|
1310
1338
|
window.onresize = () => {
|
|
1311
|
-
this.
|
|
1339
|
+
this.updateViewport();
|
|
1312
1340
|
};
|
|
1313
1341
|
}
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1342
|
+
initContainerSize() {
|
|
1343
|
+
this.renderer2.setStyle(this.contentContainer.nativeElement, 'overflow', 'auto');
|
|
1344
|
+
this.resizeViewport();
|
|
1345
|
+
}
|
|
1346
|
+
resizeViewport() {
|
|
1347
|
+
const container = this.elementRef.nativeElement?.parentElement;
|
|
1348
|
+
const containerRect = container?.getBoundingClientRect();
|
|
1349
|
+
const width = `${containerRect.width + SCROLL_BAR_WIDTH}px`;
|
|
1350
|
+
const height = `${containerRect.height + SCROLL_BAR_WIDTH}px`;
|
|
1351
|
+
this.renderer2.setStyle(this.contentContainer.nativeElement, 'width', width);
|
|
1352
|
+
this.renderer2.setStyle(this.contentContainer.nativeElement, 'height', height);
|
|
1353
|
+
this.renderer2.setStyle(this.contentContainer.nativeElement, 'maxWidth', width);
|
|
1354
|
+
this.renderer2.setStyle(this.contentContainer.nativeElement, 'maxHeight', height);
|
|
1355
|
+
}
|
|
1356
|
+
setScroll(left, top) {
|
|
1357
|
+
const container = this.contentContainer.nativeElement;
|
|
1358
|
+
container.scrollTo({
|
|
1359
|
+
top,
|
|
1360
|
+
left
|
|
1361
|
+
});
|
|
1362
|
+
}
|
|
1363
|
+
getScrollOffset(left, top) {
|
|
1364
|
+
const viewportBox = getViewportClientBox(this.board);
|
|
1365
|
+
const viewBox = getViewBox(this.board);
|
|
1366
|
+
const scrollLeftRatio = left / (viewBox.viewportWidth - viewportBox.width);
|
|
1367
|
+
const scrollTopRatio = top / (viewBox.viewportHeight - viewportBox.height);
|
|
1368
|
+
this.setViewport({
|
|
1369
|
+
offsetXRatio: scrollLeftRatio,
|
|
1370
|
+
offsetYRatio: scrollTopRatio
|
|
1371
|
+
});
|
|
1372
|
+
}
|
|
1373
|
+
viewportChange(viewBox) {
|
|
1374
|
+
const offsetXRatio = this.board.viewport.offsetXRatio;
|
|
1375
|
+
const offsetYRatio = this.board.viewport.offsetYRatio;
|
|
1376
|
+
const viewportBox = getViewportClientBox(this.board);
|
|
1377
|
+
const { minX, minY, width, height, viewportWidth, viewportHeight } = viewBox;
|
|
1378
|
+
const box = [minX, minY, width, height];
|
|
1379
|
+
const scrollLeft = (viewportWidth - viewportBox.width) * offsetXRatio;
|
|
1380
|
+
const scrollTop = (viewportHeight - viewportBox.height) * offsetYRatio;
|
|
1381
|
+
this.resizeViewport();
|
|
1382
|
+
this.renderer2.setStyle(this.host, 'display', 'block');
|
|
1383
|
+
this.renderer2.setStyle(this.host, 'width', `${viewportWidth}px`);
|
|
1384
|
+
this.renderer2.setStyle(this.host, 'height', `${viewportHeight}px`);
|
|
1385
|
+
this.renderer2.setStyle(this.host, 'cursor', this.plaitReadonly ? 'grab' : 'default');
|
|
1386
|
+
this.renderer2.setAttribute(this.host, 'viewBox', box.join());
|
|
1387
|
+
this.setScroll(scrollLeft, scrollTop);
|
|
1318
1388
|
}
|
|
1319
1389
|
updateViewport() {
|
|
1320
1390
|
const viewBox = getViewBox(this.board);
|
|
1321
|
-
this.
|
|
1391
|
+
this.viewportChange(viewBox);
|
|
1322
1392
|
}
|
|
1323
1393
|
// 拖拽模式
|
|
1324
1394
|
changeMoveMode(cursorStatus) {
|
|
@@ -1327,39 +1397,45 @@ class PlaitBoardComponent {
|
|
|
1327
1397
|
}
|
|
1328
1398
|
// 适应画布
|
|
1329
1399
|
adaptHandle() {
|
|
1330
|
-
const
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1400
|
+
const viewportBox = getViewportClientBox(this.board);
|
|
1401
|
+
const rootGroup = this.host.firstChild;
|
|
1402
|
+
const rootGroupBox = rootGroup.getBBox();
|
|
1403
|
+
const viewportWidth = viewportBox.width - 2 * this.autoFitPadding;
|
|
1404
|
+
const viewportHeight = viewportBox.height - 2 * this.autoFitPadding;
|
|
1405
|
+
let zoom = this.board.viewport.zoom;
|
|
1406
|
+
if (viewportWidth < rootGroupBox.width || viewportHeight < rootGroupBox.height) {
|
|
1407
|
+
zoom = Math.min(viewportWidth / rootGroupBox.width, viewportHeight / rootGroupBox.height);
|
|
1408
|
+
}
|
|
1409
|
+
this.setViewport({
|
|
1410
|
+
zoom: calculateZoom(zoom),
|
|
1411
|
+
offsetXRatio: 0.5,
|
|
1412
|
+
offsetYRatio: 0.5
|
|
1335
1413
|
});
|
|
1336
|
-
this.resetZoomHandel();
|
|
1337
1414
|
}
|
|
1338
1415
|
// 放大
|
|
1339
1416
|
zoomInHandle() {
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
this.zoomChange();
|
|
1417
|
+
const zoom = this.board.viewport.zoom;
|
|
1418
|
+
this.setViewport({
|
|
1419
|
+
zoom: calculateZoom(zoom + 0.1)
|
|
1420
|
+
});
|
|
1345
1421
|
}
|
|
1346
1422
|
// 缩小
|
|
1347
1423
|
zoomOutHandle() {
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
this.zoomChange();
|
|
1424
|
+
const zoom = this.board.viewport.zoom;
|
|
1425
|
+
this.setViewport({
|
|
1426
|
+
zoom: calculateZoom(zoom - 0.1)
|
|
1427
|
+
});
|
|
1353
1428
|
}
|
|
1354
1429
|
resetZoomHandel() {
|
|
1355
|
-
this.
|
|
1356
|
-
|
|
1430
|
+
this.setViewport({
|
|
1431
|
+
zoom: 1
|
|
1432
|
+
});
|
|
1357
1433
|
}
|
|
1358
|
-
|
|
1434
|
+
setViewport(options) {
|
|
1359
1435
|
const viewport = this.board?.viewport;
|
|
1360
1436
|
Transforms.setViewport(this.board, {
|
|
1361
1437
|
...viewport,
|
|
1362
|
-
|
|
1438
|
+
...options
|
|
1363
1439
|
});
|
|
1364
1440
|
}
|
|
1365
1441
|
ngOnDestroy() {
|
|
@@ -1371,69 +1447,64 @@ class PlaitBoardComponent {
|
|
|
1371
1447
|
this.isMoving = isMoving;
|
|
1372
1448
|
}
|
|
1373
1449
|
}
|
|
1374
|
-
PlaitBoardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitBoardComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
1375
|
-
PlaitBoardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: PlaitBoardComponent, selector: "plait-board", inputs: { plaitValue: "plaitValue", plaitViewport: "plaitViewport", plaitPlugins: "plaitPlugins", plaitReadonly: "plaitReadonly", plaitAllowClearBoard: "plaitAllowClearBoard" }, outputs: { plaitChange: "plaitChange", plaitBoardInitialized: "plaitBoardInitialized" }, host: { properties: { "class": "this.hostClass", "class.readonly": "this.readonly", "class.moving": "this.moving", "class.focused": "this.focused" } }, queries: [{ propertyName: "toolbarTemplateRef", first: true, predicate: ["plaitToolbar"], descendants: true }], viewQueries: [{ propertyName: "svg", first: true, predicate: ["svg"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
1376
|
-
<
|
|
1450
|
+
PlaitBoardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitBoardComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1451
|
+
PlaitBoardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: PlaitBoardComponent, selector: "plait-board", inputs: { plaitValue: "plaitValue", plaitViewport: "plaitViewport", plaitPlugins: "plaitPlugins", plaitReadonly: "plaitReadonly", plaitAllowClearBoard: "plaitAllowClearBoard" }, outputs: { plaitChange: "plaitChange", plaitBoardInitialized: "plaitBoardInitialized" }, host: { properties: { "class": "this.hostClass", "class.readonly": "this.readonly", "class.moving": "this.moving", "class.focused": "this.focused" } }, queries: [{ propertyName: "toolbarTemplateRef", first: true, predicate: ["plaitToolbar"], descendants: true }], viewQueries: [{ propertyName: "svg", first: true, predicate: ["svg"], descendants: true, static: true }, { propertyName: "contentContainer", first: true, predicate: ["container"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
1452
|
+
<div class="container" #container>
|
|
1453
|
+
<svg #svg width="100%" height="100%" style="position: relative"></svg>
|
|
1454
|
+
<plait-element
|
|
1455
|
+
*ngFor="let item of board.children; let index = index; trackBy: trackBy"
|
|
1456
|
+
[index]="index"
|
|
1457
|
+
[element]="item"
|
|
1458
|
+
[board]="board"
|
|
1459
|
+
[viewport]="board.viewport"
|
|
1460
|
+
[selection]="board.selection"
|
|
1461
|
+
[host]="host"
|
|
1462
|
+
></plait-element>
|
|
1463
|
+
</div>
|
|
1377
1464
|
<plait-toolbar
|
|
1378
1465
|
*ngIf="isFocused && !toolbarTemplateRef"
|
|
1379
1466
|
[cursorStatus]="board.cursor"
|
|
1380
|
-
[viewZoom]="
|
|
1467
|
+
[viewZoom]="board.viewport!.zoom"
|
|
1381
1468
|
(moveHandle)="changeMoveMode($event)"
|
|
1382
1469
|
(adaptHandle)="adaptHandle()"
|
|
1383
1470
|
(zoomInHandle)="zoomInHandle()"
|
|
1384
1471
|
(zoomOutHandle)="zoomOutHandle()"
|
|
1385
1472
|
(resetZoomHandel)="resetZoomHandel()"
|
|
1386
1473
|
></plait-toolbar>
|
|
1387
|
-
<plait-element
|
|
1388
|
-
*ngFor="let item of board.children; let index = index; trackBy: trackBy"
|
|
1389
|
-
[index]="index"
|
|
1390
|
-
[element]="item"
|
|
1391
|
-
[board]="board"
|
|
1392
|
-
[viewport]="board.viewport"
|
|
1393
|
-
[selection]="board.selection"
|
|
1394
|
-
[host]="host"
|
|
1395
|
-
></plait-element>
|
|
1396
1474
|
<ng-content></ng-content>
|
|
1397
|
-
`, isInline: true, components: [{ type:
|
|
1475
|
+
`, isInline: true, components: [{ type: PlaitElementComponent, selector: "plait-element", inputs: ["index", "element", "board", "viewport", "selection", "host"] }, { type: PlaitToolbarComponent, selector: "plait-toolbar", inputs: ["cursorStatus", "viewZoom"], outputs: ["moveHandle", "adaptHandle", "zoomInHandle", "zoomOutHandle", "resetZoomHandel"] }], directives: [{ type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1398
1476
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaitBoardComponent, decorators: [{
|
|
1399
1477
|
type: Component,
|
|
1400
1478
|
args: [{
|
|
1401
1479
|
selector: 'plait-board',
|
|
1402
1480
|
template: `
|
|
1403
|
-
<
|
|
1481
|
+
<div class="container" #container>
|
|
1482
|
+
<svg #svg width="100%" height="100%" style="position: relative"></svg>
|
|
1483
|
+
<plait-element
|
|
1484
|
+
*ngFor="let item of board.children; let index = index; trackBy: trackBy"
|
|
1485
|
+
[index]="index"
|
|
1486
|
+
[element]="item"
|
|
1487
|
+
[board]="board"
|
|
1488
|
+
[viewport]="board.viewport"
|
|
1489
|
+
[selection]="board.selection"
|
|
1490
|
+
[host]="host"
|
|
1491
|
+
></plait-element>
|
|
1492
|
+
</div>
|
|
1404
1493
|
<plait-toolbar
|
|
1405
1494
|
*ngIf="isFocused && !toolbarTemplateRef"
|
|
1406
1495
|
[cursorStatus]="board.cursor"
|
|
1407
|
-
[viewZoom]="
|
|
1496
|
+
[viewZoom]="board.viewport!.zoom"
|
|
1408
1497
|
(moveHandle)="changeMoveMode($event)"
|
|
1409
1498
|
(adaptHandle)="adaptHandle()"
|
|
1410
1499
|
(zoomInHandle)="zoomInHandle()"
|
|
1411
1500
|
(zoomOutHandle)="zoomOutHandle()"
|
|
1412
1501
|
(resetZoomHandel)="resetZoomHandel()"
|
|
1413
1502
|
></plait-toolbar>
|
|
1414
|
-
<plait-element
|
|
1415
|
-
*ngFor="let item of board.children; let index = index; trackBy: trackBy"
|
|
1416
|
-
[index]="index"
|
|
1417
|
-
[element]="item"
|
|
1418
|
-
[board]="board"
|
|
1419
|
-
[viewport]="board.viewport"
|
|
1420
|
-
[selection]="board.selection"
|
|
1421
|
-
[host]="host"
|
|
1422
|
-
></plait-element>
|
|
1423
1503
|
<ng-content></ng-content>
|
|
1424
1504
|
`,
|
|
1425
1505
|
changeDetection: ChangeDetectionStrategy.OnPush
|
|
1426
1506
|
}]
|
|
1427
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }]; }, propDecorators: {
|
|
1428
|
-
type: HostBinding,
|
|
1429
|
-
args: ['class']
|
|
1430
|
-
}], svg: [{
|
|
1431
|
-
type: ViewChild,
|
|
1432
|
-
args: ['svg', { static: true }]
|
|
1433
|
-
}], toolbarTemplateRef: [{
|
|
1434
|
-
type: ContentChild,
|
|
1435
|
-
args: ['plaitToolbar']
|
|
1436
|
-
}], plaitValue: [{
|
|
1507
|
+
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i0.ElementRef }]; }, propDecorators: { plaitValue: [{
|
|
1437
1508
|
type: Input
|
|
1438
1509
|
}], plaitViewport: [{
|
|
1439
1510
|
type: Input
|
|
@@ -1447,6 +1518,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
|
|
|
1447
1518
|
type: Output
|
|
1448
1519
|
}], plaitBoardInitialized: [{
|
|
1449
1520
|
type: Output
|
|
1521
|
+
}], hostClass: [{
|
|
1522
|
+
type: HostBinding,
|
|
1523
|
+
args: ['class']
|
|
1450
1524
|
}], readonly: [{
|
|
1451
1525
|
type: HostBinding,
|
|
1452
1526
|
args: ['class.readonly']
|
|
@@ -1456,6 +1530,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
|
|
|
1456
1530
|
}], focused: [{
|
|
1457
1531
|
type: HostBinding,
|
|
1458
1532
|
args: ['class.focused']
|
|
1533
|
+
}], svg: [{
|
|
1534
|
+
type: ViewChild,
|
|
1535
|
+
args: ['svg', { static: true }]
|
|
1536
|
+
}], toolbarTemplateRef: [{
|
|
1537
|
+
type: ContentChild,
|
|
1538
|
+
args: ['plaitToolbar']
|
|
1539
|
+
}], contentContainer: [{
|
|
1540
|
+
type: ViewChild,
|
|
1541
|
+
args: ['container', { read: ElementRef, static: true }]
|
|
1459
1542
|
}] } });
|
|
1460
1543
|
|
|
1461
1544
|
const COMPONENTS = [PlaitBoardComponent, PlaitElementComponent, PlaitToolbarComponent];
|
|
@@ -1473,8 +1556,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
|
|
|
1473
1556
|
}]
|
|
1474
1557
|
}] });
|
|
1475
1558
|
|
|
1476
|
-
const CLIP_BOARD_FORMAT_KEY = 'x-plait-fragment';
|
|
1477
|
-
|
|
1478
1559
|
/*
|
|
1479
1560
|
* Public API Surface of plait
|
|
1480
1561
|
*/
|
|
@@ -1483,5 +1564,5 @@ const CLIP_BOARD_FORMAT_KEY = 'x-plait-fragment';
|
|
|
1483
1564
|
* Generated bundle index. Do not edit.
|
|
1484
1565
|
*/
|
|
1485
1566
|
|
|
1486
|
-
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, Transforms, Viewport, createG, createSVG, createText, distanceBetweenPointAndPoint, distanceBetweenPointAndSegment, getViewBox, hotkeys, idCreator, inverse, isNoSelectionElement, isNullOrUndefined, isSetViewportOperation, rotate, shouldClear, shouldMerge, shouldSave, toPoint, toRectangleClient, transformPoint, transformPoints, transformViewZoom, transformZoom, updateCursorStatus };
|
|
1567
|
+
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, transformViewZoom, transformZoom, updateCursorStatus };
|
|
1487
1568
|
//# sourceMappingURL=plait-core.mjs.map
|