@plait/common 0.60.0 → 0.62.0-next.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.
- package/constants/default.d.ts +1 -0
- package/core/element-flavour.d.ts +1 -1
- package/core/index.d.ts +4 -0
- package/core/render-component.d.ts +4 -0
- package/esm2022/constants/default.mjs +2 -1
- package/esm2022/core/element-flavour.mjs +1 -1
- package/esm2022/core/group.component.mjs +3 -3
- package/esm2022/core/index.mjs +5 -0
- package/esm2022/core/render-component.mjs +2 -0
- package/esm2022/generators/generator.mjs +1 -1
- package/esm2022/generators/index.mjs +2 -2
- package/esm2022/image/image-base.component.mjs +26 -0
- package/esm2022/image/image.generator.mjs +96 -0
- package/esm2022/image/index.mjs +4 -0
- package/esm2022/image/with-image.mjs +8 -0
- package/esm2022/plugins/index.mjs +1 -2
- package/esm2022/public-api.mjs +5 -4
- package/esm2022/text/index.mjs +5 -0
- package/esm2022/text/text-manage.mjs +138 -0
- package/esm2022/text/text-measure.mjs +61 -0
- package/esm2022/text/types.mjs +7 -0
- package/esm2022/text/with-text.mjs +8 -0
- package/esm2022/transforms/index.mjs +1 -2
- package/esm2022/utils/image.mjs +3 -3
- package/esm2022/utils/text.mjs +22 -20
- package/fesm2022/plait-common.mjs +337 -214
- package/fesm2022/plait-common.mjs.map +1 -1
- package/generators/index.d.ts +1 -1
- package/image/image-base.component.d.ts +17 -0
- package/{generators → image}/image.generator.d.ts +11 -10
- package/image/index.d.ts +3 -0
- package/image/with-image.d.ts +15 -0
- package/package.json +1 -3
- package/plugins/index.d.ts +0 -1
- package/public-api.d.ts +4 -3
- package/text/index.d.ts +4 -0
- package/text/text-manage.d.ts +41 -0
- package/text/text-measure.d.ts +8 -0
- package/text/types.d.ts +24 -0
- package/text/with-text.d.ts +25 -0
- package/transforms/index.d.ts +0 -1
- package/utils/image.d.ts +1 -5
- package/utils/text.d.ts +9 -6
- package/core/image-base.component.d.ts +0 -29
- package/esm2022/core/image-base.component.mjs +0 -95
- package/esm2022/generators/image.generator.mjs +0 -59
- package/esm2022/plugins/text-options.mjs +0 -2
- package/esm2022/transforms/text.mjs +0 -71
- package/plugins/text-options.d.ts +0 -5
- package/transforms/text.d.ts +0 -9
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { PlaitGroupElement, getSelectionAngle, getElementsInGroup, setAngleForG, RectangleClient, drawCircle, PlaitBoard, RESIZE_HANDLE_CLASS_NAME, createG, setStrokeLinecap, drawRectangle, SELECTION_RECTANGLE_CLASS_NAME,
|
|
1
|
+
import { PlaitGroupElement, getSelectionAngle, getElementsInGroup, setAngleForG, RectangleClient, drawCircle, PlaitBoard, RESIZE_HANDLE_CLASS_NAME, createG, setStrokeLinecap, drawRectangle, SELECTION_RECTANGLE_CLASS_NAME, ResizeCursorClass, RESIZE_CURSORS, setDragging, rotatePoints, isSelectionMoving, getSelectedElements, distanceBetweenPointAndPoint, Point, Direction, hotkeys, createDebugGenerator, createForeignObject, ACTIVE_STROKE_WIDTH, updateForeignObject, Transforms, getHighestSelectedElements, getRectangleByElements, MERGING, PlaitPointerType, isMainPointer, toViewBoxPoint, toHostPoint, preventTouchMove, PRESS_AND_MOVE_BUFFER, isDragging, throttleRAF, handleTouchTarget, getRectangleByGroup, ElementFlavour, isSelectedElementOrGroup, Selection, getHitElementsBySelection, createGroupRectangleG, getSelectedGroups, getHighestSelectedGroups, getSelectedIsolatedElements, idCreator, getSelectedIsolatedElementsCanAddToGroup, getGroupByElement, updateForeignObjectWidth, IS_TEXT_EDITABLE } from '@plait/core';
|
|
2
2
|
import { isKeyHotkey } from 'is-hotkey';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import * as i0 from '@angular/core';
|
|
6
|
-
import { Directive, Input } from '@angular/core';
|
|
3
|
+
import { Node, Operation, Transforms as Transforms$1, Range, Editor } from 'slate';
|
|
4
|
+
import { fromEvent, timer } from 'rxjs';
|
|
7
5
|
|
|
8
6
|
const BASE = 4;
|
|
9
7
|
const PRIMARY_COLOR = '#6698FF';
|
|
@@ -13,6 +11,7 @@ const DEFAULT_ROUTE_MARGIN = 30;
|
|
|
13
11
|
const TRANSPARENT = 'transparent';
|
|
14
12
|
const ROTATE_HANDLE_DISTANCE_TO_ELEMENT = 20;
|
|
15
13
|
const ROTATE_HANDLE_SIZE = 18;
|
|
14
|
+
const DEFAULT_FONT_FAMILY = 'PingFangSC-Regular, "PingFang SC"';
|
|
16
15
|
|
|
17
16
|
var MediaKeys;
|
|
18
17
|
(function (MediaKeys) {
|
|
@@ -183,62 +182,6 @@ class ActiveGenerator extends Generator {
|
|
|
183
182
|
}
|
|
184
183
|
}
|
|
185
184
|
|
|
186
|
-
class ImageGenerator extends Generator {
|
|
187
|
-
static { this.key = 'image-generator'; }
|
|
188
|
-
constructor(board, options) {
|
|
189
|
-
super(board, options);
|
|
190
|
-
this.board = board;
|
|
191
|
-
this.options = options;
|
|
192
|
-
}
|
|
193
|
-
canDraw(element, data) {
|
|
194
|
-
return !!this.options.getImageItem(element);
|
|
195
|
-
}
|
|
196
|
-
draw(element, viewContainerRef) {
|
|
197
|
-
const g = createG();
|
|
198
|
-
const foreignRectangle = this.options.getRectangle(element);
|
|
199
|
-
this.foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
|
|
200
|
-
g.append(this.foreignObject);
|
|
201
|
-
const componentType = this.board.getPluginOptions(WithCommonPluginKey)
|
|
202
|
-
.imageComponentType;
|
|
203
|
-
if (!componentType) {
|
|
204
|
-
throw new Error('Not implement ImageBaseComponent error.');
|
|
205
|
-
}
|
|
206
|
-
this.componentRef = viewContainerRef.createComponent(componentType);
|
|
207
|
-
this.componentRef.instance.board = this.board;
|
|
208
|
-
this.componentRef.instance.imageItem = this.options.getImageItem(element);
|
|
209
|
-
this.componentRef.instance.element = element;
|
|
210
|
-
this.componentRef.instance.getRectangle = () => {
|
|
211
|
-
return this.options.getRectangle(element);
|
|
212
|
-
};
|
|
213
|
-
this.componentRef.instance.cdr.markForCheck();
|
|
214
|
-
this.foreignObject.append(this.componentRef.instance.nativeElement);
|
|
215
|
-
return g;
|
|
216
|
-
}
|
|
217
|
-
updateImage(nodeG, previous, current) {
|
|
218
|
-
if (previous !== current && this.componentRef) {
|
|
219
|
-
this.componentRef.instance.imageItem = this.options.getImageItem(current);
|
|
220
|
-
this.componentRef.instance.element = current;
|
|
221
|
-
this.componentRef.instance.getRectangle = () => {
|
|
222
|
-
return this.options.getRectangle(current);
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
const currentForeignObject = this.options.getRectangle(current);
|
|
226
|
-
updateForeignObject(this.g, currentForeignObject.width, currentForeignObject.height, currentForeignObject.x, currentForeignObject.y);
|
|
227
|
-
if (currentForeignObject && current.angle) {
|
|
228
|
-
setAngleForG(this.g, RectangleClient.getCenterPoint(currentForeignObject), current.angle);
|
|
229
|
-
}
|
|
230
|
-
// solve image lose on move node
|
|
231
|
-
if (this.foreignObject.children.length === 0) {
|
|
232
|
-
this.foreignObject.append(this.componentRef.instance.nativeElement);
|
|
233
|
-
}
|
|
234
|
-
this.componentRef?.instance.cdr.markForCheck();
|
|
235
|
-
}
|
|
236
|
-
destroy() {
|
|
237
|
-
super.destroy();
|
|
238
|
-
this.componentRef?.destroy();
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
185
|
const getResizeHandleByIndex = (index) => {
|
|
243
186
|
return `${index}`;
|
|
244
187
|
};
|
|
@@ -749,7 +692,7 @@ const getFirstTextManage = (element) => {
|
|
|
749
692
|
};
|
|
750
693
|
const getTextEditorsByElement = (element) => {
|
|
751
694
|
return getTextManages(element).map(manage => {
|
|
752
|
-
return manage.
|
|
695
|
+
return manage.editor;
|
|
753
696
|
});
|
|
754
697
|
};
|
|
755
698
|
const getFirstTextEditor = (element) => {
|
|
@@ -770,20 +713,6 @@ const findFirstTextEditor = (board) => {
|
|
|
770
713
|
});
|
|
771
714
|
return firstEditor;
|
|
772
715
|
};
|
|
773
|
-
const getTextMarksByElement = (element) => {
|
|
774
|
-
const editors = getTextEditorsByElement(element);
|
|
775
|
-
const editor = editors[0];
|
|
776
|
-
if (!editor) {
|
|
777
|
-
return {};
|
|
778
|
-
}
|
|
779
|
-
if (editor.children.length === 0) {
|
|
780
|
-
const textManage = getTextManages(element)[0];
|
|
781
|
-
const currentMarks = PlaitMarkEditor.getMarksByElement(textManage.componentRef.instance.children[0]);
|
|
782
|
-
return currentMarks;
|
|
783
|
-
}
|
|
784
|
-
const currentMarks = PlaitMarkEditor.getMarks(editor);
|
|
785
|
-
return currentMarks;
|
|
786
|
-
};
|
|
787
716
|
const getElementsText = (elements) => {
|
|
788
717
|
return elements
|
|
789
718
|
.map(item => {
|
|
@@ -815,10 +744,10 @@ const getTextEditors = (board, elements) => {
|
|
|
815
744
|
});
|
|
816
745
|
const editingTextManage = textManages.find(textManage => textManage.isEditing);
|
|
817
746
|
if (editingTextManage) {
|
|
818
|
-
return [editingTextManage.
|
|
747
|
+
return [editingTextManage.editor];
|
|
819
748
|
}
|
|
820
749
|
return textManages.map(item => {
|
|
821
|
-
return item.
|
|
750
|
+
return item.editor;
|
|
822
751
|
});
|
|
823
752
|
}
|
|
824
753
|
return undefined;
|
|
@@ -831,10 +760,27 @@ const getEditingTextEditor = (board, elements) => {
|
|
|
831
760
|
});
|
|
832
761
|
const editingTextManage = textManages.find(textManage => textManage.isEditing);
|
|
833
762
|
if (editingTextManage) {
|
|
834
|
-
return editingTextManage.
|
|
763
|
+
return editingTextManage.editor;
|
|
835
764
|
}
|
|
836
765
|
return undefined;
|
|
837
766
|
};
|
|
767
|
+
const buildText = (text, align, properties) => {
|
|
768
|
+
properties = properties || {};
|
|
769
|
+
const plaitText = typeof text === 'string' ? { children: [{ text, ...properties }] } : text;
|
|
770
|
+
if (align) {
|
|
771
|
+
plaitText.align = align;
|
|
772
|
+
}
|
|
773
|
+
return plaitText;
|
|
774
|
+
};
|
|
775
|
+
const getLineHeightByFontSize = (fontSize) => {
|
|
776
|
+
if (fontSize === 14) {
|
|
777
|
+
return 20;
|
|
778
|
+
}
|
|
779
|
+
if (fontSize === 18) {
|
|
780
|
+
return 25;
|
|
781
|
+
}
|
|
782
|
+
return fontSize * 1.5;
|
|
783
|
+
};
|
|
838
784
|
const ELEMENT_TO_TEXT_MANAGES = new WeakMap();
|
|
839
785
|
|
|
840
786
|
const selectImage = (board, defaultImageWidth, handle, acceptImageTypes = ['png', 'jpeg', 'gif', 'bmp']) => {
|
|
@@ -855,7 +801,7 @@ const buildImage = async (board, imageFile, defaultImageWidth, handle) => {
|
|
|
855
801
|
});
|
|
856
802
|
let imageItem = null;
|
|
857
803
|
const url = URL.createObjectURL(imageFile);
|
|
858
|
-
const context = PlaitBoard.
|
|
804
|
+
const context = PlaitBoard.getBoardContext(board);
|
|
859
805
|
context.setUploadingFile({ url, file: imageFile });
|
|
860
806
|
imageItem = {
|
|
861
807
|
url,
|
|
@@ -1280,6 +1226,98 @@ const removeRotating = (board) => {
|
|
|
1280
1226
|
setDragging(board, false);
|
|
1281
1227
|
};
|
|
1282
1228
|
|
|
1229
|
+
class ImageGenerator extends Generator {
|
|
1230
|
+
static { this.key = 'image-generator'; }
|
|
1231
|
+
constructor(board, options) {
|
|
1232
|
+
super(board, options);
|
|
1233
|
+
this.board = board;
|
|
1234
|
+
this.options = options;
|
|
1235
|
+
this.isFocus = false;
|
|
1236
|
+
}
|
|
1237
|
+
canDraw(element) {
|
|
1238
|
+
return !!this.options.getImageItem(element);
|
|
1239
|
+
}
|
|
1240
|
+
draw(element) {
|
|
1241
|
+
this.element = element;
|
|
1242
|
+
const g = createG();
|
|
1243
|
+
const foreignRectangle = this.options.getRectangle(element);
|
|
1244
|
+
this.foreignObject = createForeignObject(foreignRectangle.x, foreignRectangle.y, foreignRectangle.width, foreignRectangle.height);
|
|
1245
|
+
g.append(this.foreignObject);
|
|
1246
|
+
const props = {
|
|
1247
|
+
board: this.board,
|
|
1248
|
+
imageItem: this.options.getImageItem(element),
|
|
1249
|
+
element,
|
|
1250
|
+
getRectangle: () => {
|
|
1251
|
+
return this.options.getRectangle(element);
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
this.imageComponentRef = this.board.renderImage(this.foreignObject, props);
|
|
1255
|
+
this.activeGenerator = new ActiveGenerator(this.board, {
|
|
1256
|
+
getStrokeWidth: () => {
|
|
1257
|
+
const selectedElements = getSelectedElements(this.board);
|
|
1258
|
+
if (!(selectedElements.length === 1 && !isSelectionMoving(this.board))) {
|
|
1259
|
+
return ACTIVE_STROKE_WIDTH;
|
|
1260
|
+
}
|
|
1261
|
+
else {
|
|
1262
|
+
return ACTIVE_STROKE_WIDTH;
|
|
1263
|
+
}
|
|
1264
|
+
},
|
|
1265
|
+
getStrokeOpacity: () => {
|
|
1266
|
+
const selectedElements = getSelectedElements(this.board);
|
|
1267
|
+
if ((selectedElements.length === 1 && !isSelectionMoving(this.board)) || !selectedElements.length) {
|
|
1268
|
+
return 1;
|
|
1269
|
+
}
|
|
1270
|
+
else {
|
|
1271
|
+
return 0.5;
|
|
1272
|
+
}
|
|
1273
|
+
},
|
|
1274
|
+
getRectangle: () => {
|
|
1275
|
+
return this.options.getRectangle(this.element);
|
|
1276
|
+
},
|
|
1277
|
+
hasResizeHandle: () => {
|
|
1278
|
+
const isSelectedImageElement = canResize(this.board, this.element);
|
|
1279
|
+
const isSelectedImage = !!getElementOfFocusedImage(this.board);
|
|
1280
|
+
return isSelectedImage || isSelectedImageElement;
|
|
1281
|
+
}
|
|
1282
|
+
});
|
|
1283
|
+
return g;
|
|
1284
|
+
}
|
|
1285
|
+
updateImage(nodeG, previous, current) {
|
|
1286
|
+
this.element = current;
|
|
1287
|
+
if (previous !== current && this.imageComponentRef) {
|
|
1288
|
+
const props = {
|
|
1289
|
+
imageItem: this.options.getImageItem(current),
|
|
1290
|
+
element: current,
|
|
1291
|
+
getRectangle: () => {
|
|
1292
|
+
return this.options.getRectangle(current);
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
this.imageComponentRef.update(props);
|
|
1296
|
+
}
|
|
1297
|
+
const currentForeignObject = this.options.getRectangle(current);
|
|
1298
|
+
updateForeignObject(this.g, currentForeignObject.width, currentForeignObject.height, currentForeignObject.x, currentForeignObject.y);
|
|
1299
|
+
if (currentForeignObject && current.angle) {
|
|
1300
|
+
setAngleForG(this.g, RectangleClient.getCenterPoint(currentForeignObject), current.angle);
|
|
1301
|
+
}
|
|
1302
|
+
const activeG = PlaitBoard.getElementActiveHost(this.board);
|
|
1303
|
+
this.activeGenerator.processDrawing(current, activeG, { selected: this.isFocus });
|
|
1304
|
+
}
|
|
1305
|
+
setFocus(element, isFocus) {
|
|
1306
|
+
this.isFocus = isFocus;
|
|
1307
|
+
const activeG = PlaitBoard.getElementActiveHost(this.board);
|
|
1308
|
+
this.activeGenerator.processDrawing(element, activeG, { selected: isFocus });
|
|
1309
|
+
const props = {
|
|
1310
|
+
isFocus
|
|
1311
|
+
};
|
|
1312
|
+
this.imageComponentRef.update(props);
|
|
1313
|
+
}
|
|
1314
|
+
destroy() {
|
|
1315
|
+
super.destroy();
|
|
1316
|
+
this.imageComponentRef?.destroy();
|
|
1317
|
+
this.activeGenerator?.destroy();
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1283
1321
|
const setProperty = (board, properties, options) => {
|
|
1284
1322
|
const selectedElements = getSelectedElements(board);
|
|
1285
1323
|
selectedElements.forEach(element => {
|
|
@@ -1433,73 +1471,6 @@ const AlignTransform = {
|
|
|
1433
1471
|
distributeVertical
|
|
1434
1472
|
};
|
|
1435
1473
|
|
|
1436
|
-
const setTextMarks = (board, mark) => {
|
|
1437
|
-
const selectedElements = getSelectedElements(board);
|
|
1438
|
-
if (selectedElements.length) {
|
|
1439
|
-
const firstEditor = findFirstTextEditor(board);
|
|
1440
|
-
if (!firstEditor) {
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1443
|
-
const activeMarks = PlaitMarkEditor.getMarks(firstEditor);
|
|
1444
|
-
const elements = selectedElements.filter(element => {
|
|
1445
|
-
const editors = getTextEditorsByElement(element);
|
|
1446
|
-
return editors.some(editor => {
|
|
1447
|
-
const elementMarks = PlaitMarkEditor.getMarks(editor);
|
|
1448
|
-
return elementMarks[mark] === activeMarks[mark];
|
|
1449
|
-
});
|
|
1450
|
-
});
|
|
1451
|
-
const editors = getTextEditors(board, elements);
|
|
1452
|
-
if (editors && editors.length) {
|
|
1453
|
-
editors.forEach(editor => {
|
|
1454
|
-
PlaitMarkEditor.toggleMark(editor, mark);
|
|
1455
|
-
});
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
};
|
|
1459
|
-
const setFontSize = (board, size, defaultFontSize) => {
|
|
1460
|
-
const editors = getTextEditors(board);
|
|
1461
|
-
if (editors && editors.length) {
|
|
1462
|
-
const selectedElements = getSelectedElements(board);
|
|
1463
|
-
editors.forEach(editor => {
|
|
1464
|
-
let finalDefaultFontSize;
|
|
1465
|
-
if (typeof defaultFontSize === 'function') {
|
|
1466
|
-
const element = selectedElements.find(element => {
|
|
1467
|
-
const textEditors = getTextEditorsByElement(element);
|
|
1468
|
-
return textEditors.includes(editor);
|
|
1469
|
-
});
|
|
1470
|
-
finalDefaultFontSize = defaultFontSize(element);
|
|
1471
|
-
}
|
|
1472
|
-
else {
|
|
1473
|
-
finalDefaultFontSize = defaultFontSize;
|
|
1474
|
-
}
|
|
1475
|
-
PlaitMarkEditor.setFontSizeMark(editor, size, finalDefaultFontSize);
|
|
1476
|
-
});
|
|
1477
|
-
}
|
|
1478
|
-
};
|
|
1479
|
-
const setTextColor = (board, color, textSelection) => {
|
|
1480
|
-
const editors = getTextEditors(board);
|
|
1481
|
-
if (editors && editors.length) {
|
|
1482
|
-
editors.forEach(editor => {
|
|
1483
|
-
if (textSelection) {
|
|
1484
|
-
Transforms$1.select(editor, textSelection);
|
|
1485
|
-
}
|
|
1486
|
-
if (color === 'transparent') {
|
|
1487
|
-
Editor.removeMark(editor, MarkTypes.color);
|
|
1488
|
-
}
|
|
1489
|
-
else {
|
|
1490
|
-
PlaitMarkEditor.setColorMark(editor, color);
|
|
1491
|
-
}
|
|
1492
|
-
});
|
|
1493
|
-
}
|
|
1494
|
-
};
|
|
1495
|
-
const setTextAlign = (board, align) => {
|
|
1496
|
-
const editors = getTextEditors(board);
|
|
1497
|
-
if (editors && editors.length) {
|
|
1498
|
-
editors.forEach(editor => AlignEditor.setAlign(editor, align));
|
|
1499
|
-
}
|
|
1500
|
-
};
|
|
1501
|
-
const TextTransforms = { setTextAlign, setTextColor, setFontSize, setTextMarks };
|
|
1502
|
-
|
|
1503
1474
|
const normalizeShapePoints = (points, shift = false) => {
|
|
1504
1475
|
let start = points[0];
|
|
1505
1476
|
let end = points[1];
|
|
@@ -1707,7 +1678,7 @@ class GroupComponent extends CommonElementFlavour {
|
|
|
1707
1678
|
initialize() {
|
|
1708
1679
|
super.initialize();
|
|
1709
1680
|
this.initializeGenerator();
|
|
1710
|
-
const contextService = PlaitBoard.
|
|
1681
|
+
const contextService = PlaitBoard.getBoardContext(this.board);
|
|
1711
1682
|
this.onStableSubscription = contextService.onStable().subscribe(() => {
|
|
1712
1683
|
const elementsInGroup = getElementsInGroup(this.board, this.element, false, true);
|
|
1713
1684
|
const isPartialSelectGroup = elementsInGroup.some(item => isSelectedElementOrGroup(this.board, item)) &&
|
|
@@ -1915,94 +1886,246 @@ const updateSiblingElementGroupId = (board, removeGroups) => {
|
|
|
1915
1886
|
};
|
|
1916
1887
|
|
|
1917
1888
|
class ImageBaseComponent {
|
|
1889
|
+
constructor() {
|
|
1890
|
+
this.initialized = false;
|
|
1891
|
+
}
|
|
1918
1892
|
set imageItem(value) {
|
|
1919
|
-
this.afterImageItemChange(this._imageItem, value);
|
|
1920
1893
|
this._imageItem = value;
|
|
1921
|
-
this.
|
|
1894
|
+
if (this.initialized) {
|
|
1895
|
+
this.afterImageItemChange(this._imageItem, value);
|
|
1896
|
+
}
|
|
1922
1897
|
}
|
|
1923
1898
|
get imageItem() {
|
|
1924
1899
|
return this._imageItem;
|
|
1925
1900
|
}
|
|
1926
1901
|
set isFocus(value) {
|
|
1927
1902
|
this._isFocus = value;
|
|
1928
|
-
this.drawFocus();
|
|
1929
1903
|
}
|
|
1930
1904
|
get isFocus() {
|
|
1931
1905
|
return this._isFocus;
|
|
1932
1906
|
}
|
|
1933
|
-
|
|
1934
|
-
|
|
1907
|
+
initialize() {
|
|
1908
|
+
this.initialized = true;
|
|
1935
1909
|
}
|
|
1936
|
-
|
|
1937
|
-
this.elementRef = elementRef;
|
|
1938
|
-
this.cdr = cdr;
|
|
1939
|
-
this.initialized = false;
|
|
1910
|
+
destroy() {
|
|
1940
1911
|
}
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
function measureElement(element, options, containerMaxWidth = 10000) {
|
|
1915
|
+
const canvas = document.createElement('canvas');
|
|
1916
|
+
const ctx = canvas.getContext('2d');
|
|
1917
|
+
const textEntries = Node.texts(element);
|
|
1918
|
+
const lines = [[]];
|
|
1919
|
+
for (const textEntry of textEntries) {
|
|
1920
|
+
const [text] = textEntry;
|
|
1921
|
+
const textString = Node.string(text);
|
|
1922
|
+
const textArray = textString.split('\n');
|
|
1923
|
+
textArray.forEach((segmentTextString, index) => {
|
|
1924
|
+
const segmentText = { ...text, text: segmentTextString };
|
|
1925
|
+
if (index === 0) {
|
|
1926
|
+
const currentLine = lines[lines.length - 1];
|
|
1927
|
+
currentLine.push(segmentText);
|
|
1928
|
+
}
|
|
1929
|
+
else {
|
|
1930
|
+
const newLine = [];
|
|
1931
|
+
newLine.push(segmentText);
|
|
1932
|
+
lines.push(newLine);
|
|
1933
|
+
}
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1936
|
+
let width = 0;
|
|
1937
|
+
let height = 0;
|
|
1938
|
+
lines.forEach((lineTexts, index) => {
|
|
1939
|
+
let lineWidth = 0;
|
|
1940
|
+
let maxLineHeight = getLineHeightByFontSize(options.fontSize);
|
|
1941
|
+
lineTexts.forEach((text, index) => {
|
|
1942
|
+
const font = getFont(text, { fontFamily: options.fontFamily, fontSize: options.fontSize });
|
|
1943
|
+
ctx.font = font;
|
|
1944
|
+
const textMetrics = ctx.measureText(text.text);
|
|
1945
|
+
lineWidth += textMetrics.width;
|
|
1946
|
+
const isLast = index === lineTexts.length - 1;
|
|
1947
|
+
// skip when text is empty and is not last text of line
|
|
1948
|
+
if (text['font-size'] && (isLast || text.text !== '')) {
|
|
1949
|
+
const lineHeight = getLineHeightByFontSize(parseFloat(text['font-size']));
|
|
1950
|
+
if (lineHeight > maxLineHeight) {
|
|
1951
|
+
maxLineHeight = lineHeight;
|
|
1956
1952
|
}
|
|
1957
|
-
|
|
1958
|
-
|
|
1953
|
+
}
|
|
1954
|
+
});
|
|
1955
|
+
if (lineWidth <= containerMaxWidth) {
|
|
1956
|
+
if (lineWidth > width) {
|
|
1957
|
+
width = lineWidth;
|
|
1958
|
+
}
|
|
1959
|
+
height += maxLineHeight;
|
|
1960
|
+
}
|
|
1961
|
+
else {
|
|
1962
|
+
width = containerMaxWidth;
|
|
1963
|
+
const lineWrapNumber = Math.ceil(lineWidth / containerMaxWidth);
|
|
1964
|
+
height += maxLineHeight * lineWrapNumber;
|
|
1965
|
+
}
|
|
1966
|
+
});
|
|
1967
|
+
return { width, height };
|
|
1968
|
+
}
|
|
1969
|
+
const getFont = (text, options) => {
|
|
1970
|
+
return `${text.italic ? 'italic ' : ''} ${text.bold ? 'bold ' : ''} ${text['font-size'] || options.fontSize}px ${options.fontFamily} `;
|
|
1971
|
+
};
|
|
1972
|
+
|
|
1973
|
+
class TextManage {
|
|
1974
|
+
constructor(board, options) {
|
|
1975
|
+
this.board = board;
|
|
1976
|
+
this.options = options;
|
|
1977
|
+
this.isEditing = false;
|
|
1978
|
+
this.getSize = (element) => {
|
|
1979
|
+
const computedStyle = window.getComputedStyle(this.foreignObject.children[0]);
|
|
1980
|
+
const fontFamily = computedStyle.fontFamily;
|
|
1981
|
+
const fontSize = parseFloat(computedStyle.fontSize);
|
|
1982
|
+
const target = element || this.editor.children[0];
|
|
1983
|
+
return measureElement(target, {
|
|
1984
|
+
fontSize: fontSize,
|
|
1985
|
+
fontFamily
|
|
1986
|
+
}, this.options.getMaxWidth());
|
|
1987
|
+
};
|
|
1988
|
+
this.getText = () => {
|
|
1989
|
+
return this.editor.children[0];
|
|
1990
|
+
};
|
|
1991
|
+
if (!this.options.getMaxWidth) {
|
|
1992
|
+
this.options.getMaxWidth = () => 999;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
draw(text) {
|
|
1996
|
+
const _rectangle = this.options.getRectangle();
|
|
1997
|
+
this.g = createG();
|
|
1998
|
+
this.foreignObject = createForeignObject(_rectangle.x, _rectangle.y, _rectangle.width, _rectangle.height);
|
|
1999
|
+
this.g.append(this.foreignObject);
|
|
2000
|
+
this.g.classList.add('text');
|
|
2001
|
+
const props = {
|
|
2002
|
+
board: this.board,
|
|
2003
|
+
text,
|
|
2004
|
+
textPlugins: this.options.textPlugins,
|
|
2005
|
+
onChange: (data) => {
|
|
2006
|
+
if (data.operations.some(op => !Operation.isSelectionOperation(op))) {
|
|
2007
|
+
const { width, height } = this.getSize();
|
|
2008
|
+
this.options.onChange && this.options.onChange({ ...data, width, height });
|
|
2009
|
+
MERGING.set(this.board, true);
|
|
1959
2010
|
}
|
|
1960
2011
|
},
|
|
1961
|
-
|
|
1962
|
-
|
|
2012
|
+
afterInit: (editor) => {
|
|
2013
|
+
this.editor = editor;
|
|
1963
2014
|
},
|
|
1964
|
-
|
|
1965
|
-
const
|
|
1966
|
-
|
|
1967
|
-
|
|
2015
|
+
onComposition: (event) => {
|
|
2016
|
+
const fakeRoot = buildCompositionData(this.editor, event.data);
|
|
2017
|
+
if (fakeRoot) {
|
|
2018
|
+
const sizeData = this.getSize(fakeRoot.children[0]);
|
|
2019
|
+
this.options.onChange && this.options.onChange(sizeData);
|
|
2020
|
+
MERGING.set(this.board, true);
|
|
2021
|
+
}
|
|
1968
2022
|
}
|
|
1969
|
-
}
|
|
1970
|
-
this.
|
|
2023
|
+
};
|
|
2024
|
+
this.textComponentRef = this.board.renderText(this.foreignObject, props);
|
|
1971
2025
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
const activeG = PlaitBoard.getElementActiveHost(this.board);
|
|
1975
|
-
this.activeGenerator.processDrawing(this.element, activeG, { selected: this._isFocus });
|
|
1976
|
-
}
|
|
2026
|
+
updateRectangleWidth(width) {
|
|
2027
|
+
updateForeignObjectWidth(this.g, width);
|
|
1977
2028
|
}
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2029
|
+
updateAngle(centerPoint, angle = 0) {
|
|
2030
|
+
setAngleForG(this.g, centerPoint, angle);
|
|
2031
|
+
}
|
|
2032
|
+
updateRectangle(rectangle) {
|
|
2033
|
+
const { x, y, width, height } = rectangle || this.options.getRectangle();
|
|
2034
|
+
updateForeignObject(this.g, width, height, x, y);
|
|
2035
|
+
}
|
|
2036
|
+
updateText(newText) {
|
|
2037
|
+
const props = {
|
|
2038
|
+
text: newText
|
|
2039
|
+
};
|
|
2040
|
+
this.textComponentRef.update(props);
|
|
2041
|
+
}
|
|
2042
|
+
edit(callback) {
|
|
2043
|
+
this.isEditing = true;
|
|
2044
|
+
IS_TEXT_EDITABLE.set(this.board, true);
|
|
2045
|
+
const props = {
|
|
2046
|
+
readonly: false
|
|
2047
|
+
};
|
|
2048
|
+
this.textComponentRef.update(props);
|
|
2049
|
+
Transforms$1.select(this.editor, [0]);
|
|
2050
|
+
const mousedown$ = fromEvent(document, 'mousedown').subscribe((event) => {
|
|
2051
|
+
const point = toViewBoxPoint(this.board, toHostPoint(this.board, event.x, event.y));
|
|
2052
|
+
const textRec = this.options.getRenderRectangle ? this.options.getRenderRectangle() : this.options.getRectangle();
|
|
2053
|
+
const clickInText = RectangleClient.isHit(RectangleClient.getRectangleByPoints([point, point]), textRec);
|
|
2054
|
+
const isAttached = event.target.closest('.plait-board-attached');
|
|
2055
|
+
if (!clickInText && !isAttached) {
|
|
2056
|
+
// handle composition input state, like: Chinese IME Composition Input
|
|
2057
|
+
timer(0).subscribe(() => {
|
|
2058
|
+
exitCallback();
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
2061
|
+
});
|
|
2062
|
+
const keydown$ = fromEvent(document, 'keydown').subscribe((event) => {
|
|
2063
|
+
if (event.isComposing) {
|
|
2064
|
+
return;
|
|
2065
|
+
}
|
|
2066
|
+
if (event.key === 'Escape' || (event.key === 'Enter' && !event.shiftKey) || event.key === 'Tab') {
|
|
2067
|
+
event.preventDefault();
|
|
2068
|
+
event.stopPropagation();
|
|
2069
|
+
exitCallback();
|
|
2070
|
+
return;
|
|
2071
|
+
}
|
|
2072
|
+
});
|
|
2073
|
+
const exitCallback = () => {
|
|
2074
|
+
this.updateRectangle();
|
|
2075
|
+
mousedown$.unsubscribe();
|
|
2076
|
+
keydown$.unsubscribe();
|
|
2077
|
+
IS_TEXT_EDITABLE.set(this.board, false);
|
|
2078
|
+
MERGING.set(this.board, false);
|
|
2079
|
+
callback && callback();
|
|
2080
|
+
const props = {
|
|
2081
|
+
readonly: true
|
|
2082
|
+
};
|
|
2083
|
+
this.textComponentRef.update(props);
|
|
2084
|
+
this.isEditing = false;
|
|
2085
|
+
};
|
|
2086
|
+
return exitCallback;
|
|
2087
|
+
}
|
|
2088
|
+
destroy() {
|
|
2089
|
+
this.g?.remove();
|
|
2090
|
+
this.textComponentRef?.destroy();
|
|
1982
2091
|
}
|
|
1983
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: ImageBaseComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1984
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.4", type: ImageBaseComponent, inputs: { element: "element", imageItem: "imageItem", board: "board", isFocus: "isFocus", getRectangle: "getRectangle", hasResizeHandle: "hasResizeHandle" }, host: { classAttribute: "plait-image-container" }, ngImport: i0 }); }
|
|
1985
2092
|
}
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2093
|
+
const buildCompositionData = (editor, data) => {
|
|
2094
|
+
if (editor.selection && Range.isCollapsed(editor.selection)) {
|
|
2095
|
+
const [textNode, textPath] = Editor.node(editor, editor.selection);
|
|
2096
|
+
const offset = editor.selection.anchor.offset;
|
|
2097
|
+
const clonedElement = JSON.parse(JSON.stringify(editor.children[0]));
|
|
2098
|
+
const root = { children: [clonedElement] };
|
|
2099
|
+
const newTextString = textNode.text.slice(0, offset + 1) + data + textNode.text.slice(offset + 1);
|
|
2100
|
+
const clonedTextNode = Node.get(root, textPath);
|
|
2101
|
+
clonedTextNode.text = newTextString;
|
|
2102
|
+
return root;
|
|
2103
|
+
}
|
|
2104
|
+
return null;
|
|
2105
|
+
};
|
|
2106
|
+
|
|
2107
|
+
const withText = (board) => {
|
|
2108
|
+
const newBoard = board;
|
|
2109
|
+
newBoard.renderText = (container, props) => {
|
|
2110
|
+
throw new Error('No implementation for renderText method.');
|
|
2111
|
+
};
|
|
2112
|
+
return newBoard;
|
|
2113
|
+
};
|
|
2114
|
+
|
|
2115
|
+
var Alignment;
|
|
2116
|
+
(function (Alignment) {
|
|
2117
|
+
Alignment["left"] = "left";
|
|
2118
|
+
Alignment["center"] = "center";
|
|
2119
|
+
Alignment["right"] = "right";
|
|
2120
|
+
})(Alignment || (Alignment = {}));
|
|
2121
|
+
|
|
2122
|
+
const withImage = (board) => {
|
|
2123
|
+
const newBoard = board;
|
|
2124
|
+
newBoard.renderImage = (container, props) => {
|
|
2125
|
+
throw new Error('No implementation for renderImage method.');
|
|
2126
|
+
};
|
|
2127
|
+
return newBoard;
|
|
2128
|
+
};
|
|
2006
2129
|
|
|
2007
2130
|
/*
|
|
2008
2131
|
* Public API Surface of utils
|
|
@@ -2012,5 +2135,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImpor
|
|
|
2012
2135
|
* Generated bundle index. Do not edit.
|
|
2013
2136
|
*/
|
|
2014
2137
|
|
|
2015
|
-
export { AStar, ActiveGenerator, AlignTransform, BASE, BoardCreationMode, CommonElementFlavour, DEFAULT_ROUTE_MARGIN, ELEMENT_TO_TEXT_MANAGES, Generator, IS_RESIZING, IS_ROTATING, ImageBaseComponent, ImageGenerator, MediaKeys, PICTURE_ACCEPTED_UPLOAD_SIZE, PRIMARY_COLOR, PlaitCommonElementRef, PointGraph, PointNode, PriorityQueue, PropertyTransforms, RESIZE_HANDLE_DIAMETER, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, ResizeHandle, TRANSPARENT,
|
|
2138
|
+
export { AStar, ActiveGenerator, AlignTransform, Alignment, BASE, BoardCreationMode, CommonElementFlavour, DEFAULT_FONT_FAMILY, DEFAULT_ROUTE_MARGIN, ELEMENT_TO_TEXT_MANAGES, Generator, GroupComponent, IS_RESIZING, IS_ROTATING, ImageBaseComponent, ImageGenerator, MediaKeys, PICTURE_ACCEPTED_UPLOAD_SIZE, PRIMARY_COLOR, PlaitCommonElementRef, PointGraph, PointNode, PriorityQueue, PropertyTransforms, RESIZE_HANDLE_DIAMETER, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, ResizeHandle, TRANSPARENT, TextManage, WithCommonPluginKey, WithTextPluginKey, acceptImageTypes, addElementOfFocusedImage, addResizing, addRotating, alignBottom, alignHorizontalCenter, alignLeft, alignRight, alignTop, alignVerticalCenter, buildCompositionData, buildImage, buildText, calculatePolylineLength, canResize, createGraph, distributeHorizontal, distributeVertical, drawFillPrimaryHandle, drawHandle, drawPrimaryHandle, drawRotateHandle, findFirstTextEditor, generateElbowLineRoute, getCreationMode, getCrossingPointsBetweenPointAndSegment, getDirectionBetweenPointAndPoint, getDirectionByPointOfRectangle, getDirectionByVector, getDirectionFactor, getDirectionFactorByDirectionComponent, getEditingTextEditor, getElementOfFocusedImage, getElementsText, getExtendPoint, getFirstTextEditor, getFirstTextManage, getGraphPoints, getIndexByResizeHandle, getLineHeightByFontSize, getMemorizedLatest, getNextPoint, getOppositeDirection, getPointByVectorComponent, getPointByVectorDirectionComponent, getPointOnPolyline, getPoints, getRatioByPoint, getRectangleResizeHandleRefs, getResizeHandleByIndex, getResizeHandlePointByIndex, getRotatedResizeCursorClassByAngle, getSourceAndTargetOuterRectangle, getSymmetricHandleIndex, getTextEditors, getTextEditorsByElement, getTextManages, getUnitVectorByPointAndPoint, hasAfterDraw, isCornerHandle, isDelete, isDndMode, isDrawingMode, isEdgeHandle, isEnterHotkey, isExpandHotkey, isPointOnSegment, isResizing, isResizingByCondition, isRotating, isSourceAndTargetIntersect, isSpaceHotkey, isTabHotkey, isVirtualKey, measureElement, memorizeLatest, normalizeShapePoints, reduceRouteMargin, removeDuplicatePoints, removeElementOfFocusedImage, removeResizing, removeRotating, resetPointsAfterResize, rotateVector, rotateVectorAnti90, routeAdjust, selectImage, setCreationMode, setProperty, simplifyOrthogonalPoints, withGroup, withImage, withResize, withText };
|
|
2016
2139
|
//# sourceMappingURL=plait-common.mjs.map
|