@plait/draw 0.75.0 → 0.77.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 +4 -0
- package/constants/index.d.ts +1 -0
- package/esm2022/arrow-line.component.mjs +14 -7
- package/esm2022/constants/default.mjs +6 -1
- package/esm2022/constants/index.mjs +2 -1
- package/esm2022/generators/arrow-line-auto-complete.generator.mjs +3 -3
- package/esm2022/generators/line-active.generator.mjs +14 -10
- package/esm2022/geometry.component.mjs +20 -11
- package/esm2022/image.component.mjs +12 -8
- package/esm2022/plugins/with-arrow-line-auto-complete-reaction.mjs +9 -7
- package/esm2022/plugins/with-arrow-line-auto-complete.mjs +9 -8
- package/esm2022/plugins/with-arrow-line-bound-reaction.mjs +4 -4
- package/esm2022/plugins/with-arrow-line-text.mjs +20 -8
- package/esm2022/plugins/with-draw-resize.mjs +28 -21
- package/esm2022/plugins/with-draw-rotate.mjs +23 -18
- package/esm2022/plugins/with-geometry-create.mjs +10 -10
- package/esm2022/plugins/with-swimlane-create.mjs +4 -4
- package/esm2022/plugins/with-table-resize.mjs +15 -11
- package/esm2022/plugins/with-table.mjs +8 -5
- package/esm2022/table.component.mjs +19 -12
- package/esm2022/utils/arrow-line/arrow-line-basic.mjs +3 -3
- package/esm2022/utils/common.mjs +14 -11
- package/esm2022/utils/geometry.mjs +12 -74
- package/esm2022/utils/hit.mjs +3 -3
- package/esm2022/utils/table-selected.mjs +1 -5
- package/esm2022/utils/table.mjs +3 -3
- package/esm2022/utils/uml.mjs +7 -5
- package/esm2022/utils/vector-line.mjs +2 -2
- package/esm2022/vector-line.component.mjs +12 -5
- package/fesm2022/plait-draw.mjs +1516 -1502
- package/fesm2022/plait-draw.mjs.map +1 -1
- package/generators/line-active.generator.d.ts +5 -1
- package/package.json +1 -1
- package/plugins/with-arrow-line-text.d.ts +1 -0
- package/plugins/with-draw-resize.d.ts +1 -0
- package/utils/common.d.ts +1 -0
- package/utils/geometry.d.ts +19 -21
- package/utils/table-selected.d.ts +0 -1
package/fesm2022/plait-draw.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ACTIVE_STROKE_WIDTH, DEFAULT_COLOR, ThemeColorMode, PlaitElement, RectangleClient, getSelectedElements, idCreator,
|
|
2
|
-
import { DEFAULT_FILL, Alignment,
|
|
3
|
-
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
1
|
+
import { ACTIVE_STROKE_WIDTH, DEFAULT_COLOR, ThemeColorMode, PlaitElement, RectangleClient, getSelectedElements, idCreator, createDebugGenerator, Point, createG, arrowPoints, createPath, distanceBetweenPointAndPoint, drawLinearPath, rotate, catmullRomFitting, PlaitBoard, setStrokeLinecap, findElements, createMask, createRect, setPathStrokeLinecap, getNearestPointBetweenPointAndArc, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, isPointInPolygon, isLineHitRectangle, rotatePointsByAngle, rotateAntiPointsByElement, getEllipseArcCenter, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, depthFirstRecursion, getIsRecursionFunc, SNAPPING_STROKE_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, getI18nValue, toActiveRectangleFromViewBoxRectangle, getElementById, rotatePointsByElement, PlaitNode, hasValidAngle, toViewBoxPoint, toHostPoint, Direction, rotatePoints, getRectangleByElements, getSelectionAngle, rotatedDataPoints, isAxisChangedByAngle, isSelectionMoving, drawRectangle, getRectangleByAngle, getSnapRectangles, getTripleAxis, getMinPointDelta, SNAP_TOLERANCE, drawPointSnapLines, drawSolidLines, getNearestPointBetweenPointAndSegments, isPointInEllipse, getNearestPointBetweenPointAndEllipse, getEllipseTangentSlope, getVectorFromPointAndSlope, drawRoundRectangle, isPointInRoundRectangle, getCrossingPointsBetweenEllipseAndSegment, drawLine, getNearestPointBetweenPointAndDiscreteSegments, getNearestPointBetweenPointAndSegment, Path, RgbaToHEX, SELECTION_RECTANGLE_CLASS_NAME, toActivePointFromViewBoxPoint, getHitElementByPoint, WritableClipboardOperationType, WritableClipboardType, addOrCreateClipboardContext, setAngleForG, CursorClass, toActivePoint, temporaryDisableSelection, toScreenPointFromActivePoint, PRESS_AND_MOVE_BUFFER, isMainPointer, throttleRAF, getAngleBetweenPoints, normalizeAngle, degreesToRadians, rotateElements, MERGING, ROTATE_HANDLE_CLASS_NAME, isSelectedElement, isDragging } from '@plait/core';
|
|
2
|
+
import { DEFAULT_FILL, Alignment, getMemorizedLatest, memorizeLatest, WithTextPluginKey, TextManage, StrokeStyle, removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, getExtendPoint, getUnitVectorByPointAndPoint, Generator, getPointByVectorComponent, getStrokeLineDash, getPointOnPolyline, buildText, getCrossingPointsBetweenPointAndSegment, isPointOnSegment, getFirstTextEditor, sortElementsByArea, isFilled, getTextEditorsByElement, RESIZE_HANDLE_DIAMETER, measureElement, DEFAULT_FONT_FAMILY, getFirstTextManage, isSourceAndTargetIntersect, getPoints, DEFAULT_ROUTE_MARGIN, normalizeShapePoints, resetPointsAfterResize, getDirectionByVector, getRectangleResizeHandleRefs, getRotatedResizeCursorClassByAngle, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, isCornerHandle, getIndexByResizeHandle, withResize, getSymmetricHandleIndex, getResizeHandlePointByIndex, drawHandle, getDirectionFactorByDirectionComponent, buildClipboardData as buildClipboardData$1, insertClipboardData as insertClipboardData$1, getDirectionByPointOfRectangle, getDirectionFactor, rotateVector, getOppositeDirection, rotateVectorAnti90, getSourceAndTargetOuterRectangle, getNextPoint, PRIMARY_COLOR, CommonElementFlavour, createActiveGenerator, hasResizeHandle, ActiveGenerator, drawPrimaryHandle, drawFillPrimaryHandle, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, getElementsText, acceptImageTypes, getElementOfFocusedImage, buildImage, isResizingByCondition, getRatioByPoint, getTextManages, ImageGenerator, ResizeHandle, addRotating, removeRotating, drawRotateHandle } from '@plait/common';
|
|
4
3
|
import { TEXT_DEFAULT_HEIGHT, DEFAULT_FONT_SIZE, AlignEditor } from '@plait/text-plugins';
|
|
4
|
+
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
5
5
|
import { Editor, Node } from 'slate';
|
|
6
6
|
import { isKeyHotkey } from 'is-hotkey';
|
|
7
7
|
|
|
@@ -114,6 +114,11 @@ const PlaitTableElement = {
|
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
const WithDrawPluginKey = 'plait-draw-plugin-key';
|
|
117
|
+
var DrawI18nKey;
|
|
118
|
+
(function (DrawI18nKey) {
|
|
119
|
+
DrawI18nKey["lineText"] = "line-text";
|
|
120
|
+
DrawI18nKey["geometryText"] = "geometry-text";
|
|
121
|
+
})(DrawI18nKey || (DrawI18nKey = {}));
|
|
117
122
|
|
|
118
123
|
const ShapeDefaultSpace = {
|
|
119
124
|
rectangleAndText: 4
|
|
@@ -461,6 +466,18 @@ const DefaultSwimlanePropertyMap = {
|
|
|
461
466
|
|
|
462
467
|
const MIN_TEXT_WIDTH = 5;
|
|
463
468
|
|
|
469
|
+
const DefaultLineStyle = {
|
|
470
|
+
strokeWidth: 2,
|
|
471
|
+
strokeColor: '#000'
|
|
472
|
+
};
|
|
473
|
+
const LINE_TEXT_SPACE = 4;
|
|
474
|
+
const LINE_AUTO_COMPLETE_DIAMETER = 6;
|
|
475
|
+
const LINE_AUTO_COMPLETE_OPACITY = 0.6;
|
|
476
|
+
const LINE_AUTO_COMPLETE_HOVERED_OPACITY = 0.8;
|
|
477
|
+
const LINE_AUTO_COMPLETE_HOVERED_DIAMETER = 10;
|
|
478
|
+
const LINE_ALIGN_TOLERANCE = 3;
|
|
479
|
+
const LINE_TEXT = '文本';
|
|
480
|
+
|
|
464
481
|
const getElementShape = (value) => {
|
|
465
482
|
if (PlaitDrawElement.isImage(value)) {
|
|
466
483
|
return BasicShapes.rectangle;
|
|
@@ -471,6 +488,97 @@ const getElementShape = (value) => {
|
|
|
471
488
|
return value.shape;
|
|
472
489
|
};
|
|
473
490
|
|
|
491
|
+
const SHAPE_MAX_LENGTH = 6;
|
|
492
|
+
const memorizedShape = new WeakMap();
|
|
493
|
+
const getMemorizeKey = (element) => {
|
|
494
|
+
let key = '';
|
|
495
|
+
switch (true) {
|
|
496
|
+
case PlaitDrawElement.isText(element): {
|
|
497
|
+
key = MemorizeKey.text;
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
case PlaitDrawElement.isBasicShape(element): {
|
|
501
|
+
key = MemorizeKey.basicShape;
|
|
502
|
+
break;
|
|
503
|
+
}
|
|
504
|
+
case PlaitDrawElement.isFlowchart(element): {
|
|
505
|
+
key = MemorizeKey.flowchart;
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
case PlaitDrawElement.isArrowLine(element): {
|
|
509
|
+
key = MemorizeKey.arrowLine;
|
|
510
|
+
break;
|
|
511
|
+
}
|
|
512
|
+
case PlaitDrawElement.isUML(element): {
|
|
513
|
+
key = MemorizeKey.UML;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return key;
|
|
517
|
+
};
|
|
518
|
+
const getLineMemorizedLatest = () => {
|
|
519
|
+
const properties = getMemorizedLatest(MemorizeKey.arrowLine);
|
|
520
|
+
return { ...properties } || {};
|
|
521
|
+
};
|
|
522
|
+
const getMemorizedLatestByPointer = (pointer) => {
|
|
523
|
+
let memorizeKey = '';
|
|
524
|
+
if (PlaitDrawElement.isBasicShape({ shape: pointer })) {
|
|
525
|
+
memorizeKey = pointer === BasicShapes.text ? MemorizeKey.text : MemorizeKey.basicShape;
|
|
526
|
+
}
|
|
527
|
+
else if (PlaitDrawElement.isUML({ shape: pointer })) {
|
|
528
|
+
memorizeKey = MemorizeKey.UML;
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
memorizeKey = MemorizeKey.flowchart;
|
|
532
|
+
}
|
|
533
|
+
const properties = { ...getMemorizedLatest(memorizeKey) } || {};
|
|
534
|
+
const textProperties = { ...properties.text } || {};
|
|
535
|
+
delete properties.text;
|
|
536
|
+
return { textProperties, geometryProperties: properties };
|
|
537
|
+
};
|
|
538
|
+
const memorizeLatestText = (element, operations) => {
|
|
539
|
+
const memorizeKey = getMemorizeKey(element);
|
|
540
|
+
let textMemory = getMemorizedLatest(memorizeKey)?.text || {};
|
|
541
|
+
const setNodeOperation = operations.find(operation => operation.type === 'set_node');
|
|
542
|
+
if (setNodeOperation) {
|
|
543
|
+
const { properties, newProperties } = setNodeOperation;
|
|
544
|
+
for (const key in newProperties) {
|
|
545
|
+
const value = newProperties[key];
|
|
546
|
+
if (value == null) {
|
|
547
|
+
delete textMemory[key];
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
textMemory[key] = value;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
for (const key in properties) {
|
|
554
|
+
if (!newProperties.hasOwnProperty(key)) {
|
|
555
|
+
delete textMemory[key];
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
memorizeLatest(memorizeKey, 'text', textMemory);
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
const memorizeLatestShape = (board, shape) => {
|
|
562
|
+
const shapes = memorizedShape.has(board) ? memorizedShape.get(board) : [];
|
|
563
|
+
const shapeIndex = shapes.indexOf(shape);
|
|
564
|
+
if (shape === BasicShapes.text || shapeIndex === 0) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (shapeIndex !== -1) {
|
|
568
|
+
shapes.splice(shapeIndex, 1);
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
if (shapes.length === SHAPE_MAX_LENGTH) {
|
|
572
|
+
shapes.pop();
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
shapes.unshift(shape);
|
|
576
|
+
memorizedShape.set(board, shapes);
|
|
577
|
+
};
|
|
578
|
+
const getMemorizedLatestShape = (board) => {
|
|
579
|
+
return memorizedShape.get(board);
|
|
580
|
+
};
|
|
581
|
+
|
|
474
582
|
// TODO: 是否可以完全基于位置定位 TextManager,实现 line 和 多文本 geometry 统一
|
|
475
583
|
// 一个元素有多个文本时,单纯通过位置无法获取 TextManage,因此这里单独通过 Map 保存关键字 key 和 TextManage 的对应关系
|
|
476
584
|
// 1. 单文本元素 key 就是元素的 id
|
|
@@ -602,10 +710,6 @@ const isSingleSelectTable = (board) => {
|
|
|
602
710
|
const selectedElements = getSelectedElements(board);
|
|
603
711
|
return selectedElements && selectedElements.length === 1 && PlaitDrawElement.isElementByTable(selectedElements[0]);
|
|
604
712
|
};
|
|
605
|
-
const isSingleSelectElementByTable = (board) => {
|
|
606
|
-
const selectedElements = getSelectedElements(board);
|
|
607
|
-
return selectedElements && selectedElements.length === 1 && PlaitDrawElement.isElementByTable(selectedElements[0]);
|
|
608
|
-
};
|
|
609
713
|
const getSelectedTableElements = (board, elements) => {
|
|
610
714
|
const selectedElements = elements?.length ? elements : getSelectedElements(board);
|
|
611
715
|
return selectedElements.filter(value => PlaitDrawElement.isElementByTable(value));
|
|
@@ -774,7 +878,7 @@ const createCell = (rowId, columnId, text = null) => {
|
|
|
774
878
|
return cell;
|
|
775
879
|
};
|
|
776
880
|
const getSelectedTableCellsEditor = (board) => {
|
|
777
|
-
if (
|
|
881
|
+
if (isSingleSelectTable(board)) {
|
|
778
882
|
const elements = getSelectedTableElements(board);
|
|
779
883
|
const selectedCells = getSelectedCells(elements[0]);
|
|
780
884
|
const selectedCellsEditor = selectedCells?.map(cell => {
|
|
@@ -788,1458 +892,1358 @@ const getSelectedTableCellsEditor = (board) => {
|
|
|
788
892
|
return undefined;
|
|
789
893
|
};
|
|
790
894
|
|
|
791
|
-
const
|
|
792
|
-
const
|
|
793
|
-
const
|
|
794
|
-
|
|
795
|
-
switch (true) {
|
|
796
|
-
case PlaitDrawElement.isText(element): {
|
|
797
|
-
key = MemorizeKey.text;
|
|
798
|
-
break;
|
|
799
|
-
}
|
|
800
|
-
case PlaitDrawElement.isBasicShape(element): {
|
|
801
|
-
key = MemorizeKey.basicShape;
|
|
802
|
-
break;
|
|
803
|
-
}
|
|
804
|
-
case PlaitDrawElement.isFlowchart(element): {
|
|
805
|
-
key = MemorizeKey.flowchart;
|
|
806
|
-
break;
|
|
807
|
-
}
|
|
808
|
-
case PlaitDrawElement.isArrowLine(element): {
|
|
809
|
-
key = MemorizeKey.arrowLine;
|
|
810
|
-
break;
|
|
811
|
-
}
|
|
812
|
-
case PlaitDrawElement.isUML(element): {
|
|
813
|
-
key = MemorizeKey.UML;
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
return key;
|
|
895
|
+
const getStrokeColorByElement = (board, element) => {
|
|
896
|
+
const defaultColor = getDrawDefaultStrokeColor(board.theme.themeColorMode);
|
|
897
|
+
const strokeColor = element.strokeColor || defaultColor;
|
|
898
|
+
return strokeColor;
|
|
817
899
|
};
|
|
818
|
-
const
|
|
819
|
-
const
|
|
820
|
-
|
|
900
|
+
const getFillByElement = (board, element) => {
|
|
901
|
+
const defaultFill = PlaitDrawElement.isFlowchart(element) && isClosedDrawElement(element)
|
|
902
|
+
? getFlowchartDefaultFill(board.theme.themeColorMode)
|
|
903
|
+
: DefaultDrawStyle.fill;
|
|
904
|
+
const fill = element.fill || defaultFill;
|
|
905
|
+
return fill;
|
|
821
906
|
};
|
|
822
|
-
const
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
907
|
+
const getStrokeStyleByElement = (board, element) => {
|
|
908
|
+
return element.strokeStyle || StrokeStyle.solid;
|
|
909
|
+
};
|
|
910
|
+
|
|
911
|
+
const debugKey$4 = 'debug:plait:line-mirror';
|
|
912
|
+
const debugGenerator$4 = createDebugGenerator(debugKey$4);
|
|
913
|
+
const alignPoints = (basePoint, movingPoint) => {
|
|
914
|
+
const newPoint = [...movingPoint];
|
|
915
|
+
if (Point.isVertical(newPoint, basePoint, LINE_ALIGN_TOLERANCE)) {
|
|
916
|
+
newPoint[0] = basePoint[0];
|
|
829
917
|
}
|
|
830
|
-
|
|
831
|
-
|
|
918
|
+
if (Point.isHorizontal(newPoint, basePoint, LINE_ALIGN_TOLERANCE)) {
|
|
919
|
+
newPoint[1] = basePoint[1];
|
|
832
920
|
}
|
|
833
|
-
|
|
834
|
-
const textProperties = { ...properties.text } || {};
|
|
835
|
-
delete properties.text;
|
|
836
|
-
return { textProperties, geometryProperties: properties };
|
|
921
|
+
return newPoint;
|
|
837
922
|
};
|
|
838
|
-
|
|
839
|
-
const
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
}
|
|
853
|
-
for (const key in properties) {
|
|
854
|
-
if (!newProperties.hasOwnProperty(key)) {
|
|
855
|
-
delete textMemory[key];
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
memorizeLatest(memorizeKey, 'text', textMemory);
|
|
923
|
+
function getResizedPreviousAndNextPoint(nextRenderPoints, sourcePoint, targetPoint, handleIndex) {
|
|
924
|
+
const referencePoint = {
|
|
925
|
+
previous: null,
|
|
926
|
+
next: null
|
|
927
|
+
};
|
|
928
|
+
const startPoint = nextRenderPoints[handleIndex];
|
|
929
|
+
const endPoint = nextRenderPoints[handleIndex + 1];
|
|
930
|
+
const isHorizontal = Point.isHorizontal(startPoint, endPoint);
|
|
931
|
+
const isVertical = Point.isVertical(startPoint, endPoint);
|
|
932
|
+
const previousPoint = nextRenderPoints[handleIndex - 1] ?? nextRenderPoints[0];
|
|
933
|
+
const beforePreviousPoint = nextRenderPoints[handleIndex - 2] ?? sourcePoint;
|
|
934
|
+
if ((isHorizontal && Point.isHorizontal(beforePreviousPoint, previousPoint)) ||
|
|
935
|
+
(isVertical && Point.isVertical(beforePreviousPoint, previousPoint))) {
|
|
936
|
+
referencePoint.previous = previousPoint;
|
|
859
937
|
}
|
|
860
|
-
|
|
861
|
-
const
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
if (shape === BasicShapes.text || shapeIndex === 0) {
|
|
865
|
-
return;
|
|
938
|
+
const nextPoint = nextRenderPoints[handleIndex + 2] ?? nextRenderPoints[nextRenderPoints.length - 1];
|
|
939
|
+
const afterNextPoint = nextRenderPoints[handleIndex + 3] ?? targetPoint;
|
|
940
|
+
if ((isHorizontal && Point.isHorizontal(nextPoint, afterNextPoint)) || (isVertical && Point.isVertical(nextPoint, afterNextPoint))) {
|
|
941
|
+
referencePoint.next = nextPoint;
|
|
866
942
|
}
|
|
867
|
-
|
|
868
|
-
|
|
943
|
+
return referencePoint;
|
|
944
|
+
}
|
|
945
|
+
function alignElbowSegment(startKeyPoint, endKeyPoint, resizeState, resizedPreviousAndNextPoint) {
|
|
946
|
+
let newStartPoint = startKeyPoint;
|
|
947
|
+
let newEndPoint = endKeyPoint;
|
|
948
|
+
if (Point.isHorizontal(startKeyPoint, endKeyPoint)) {
|
|
949
|
+
const offsetY = Point.getOffsetY(resizeState.startPoint, resizeState.endPoint);
|
|
950
|
+
let pointY = startKeyPoint[1] + offsetY;
|
|
951
|
+
if (resizedPreviousAndNextPoint.previous && Math.abs(resizedPreviousAndNextPoint.previous[1] - pointY) < LINE_ALIGN_TOLERANCE) {
|
|
952
|
+
pointY = resizedPreviousAndNextPoint.previous[1];
|
|
953
|
+
}
|
|
954
|
+
else if (resizedPreviousAndNextPoint.next && Math.abs(resizedPreviousAndNextPoint.next[1] - pointY) < LINE_ALIGN_TOLERANCE) {
|
|
955
|
+
pointY = resizedPreviousAndNextPoint.next[1];
|
|
956
|
+
}
|
|
957
|
+
newStartPoint = [startKeyPoint[0], pointY];
|
|
958
|
+
newEndPoint = [endKeyPoint[0], pointY];
|
|
869
959
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
960
|
+
if (Point.isVertical(startKeyPoint, endKeyPoint)) {
|
|
961
|
+
const offsetX = Point.getOffsetX(resizeState.startPoint, resizeState.endPoint);
|
|
962
|
+
let pointX = startKeyPoint[0] + offsetX;
|
|
963
|
+
if (resizedPreviousAndNextPoint.previous && Math.abs(resizedPreviousAndNextPoint.previous[0] - pointX) < LINE_ALIGN_TOLERANCE) {
|
|
964
|
+
pointX = resizedPreviousAndNextPoint.previous[0];
|
|
965
|
+
}
|
|
966
|
+
else if (resizedPreviousAndNextPoint.next && Math.abs(resizedPreviousAndNextPoint.next[0] - pointX) < LINE_ALIGN_TOLERANCE) {
|
|
967
|
+
pointX = resizedPreviousAndNextPoint.next[0];
|
|
873
968
|
}
|
|
969
|
+
newStartPoint = [pointX, startKeyPoint[1]];
|
|
970
|
+
newEndPoint = [pointX, endKeyPoint[1]];
|
|
874
971
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
const texts = element.texts;
|
|
884
|
-
if (!texts.length)
|
|
885
|
-
return -1;
|
|
886
|
-
const points = getArrowLinePoints(board, element);
|
|
887
|
-
return texts.findIndex(text => {
|
|
888
|
-
const center = getPointOnPolyline(points, text.position);
|
|
889
|
-
const rectangle = {
|
|
890
|
-
x: center[0] - text.width / 2,
|
|
891
|
-
y: center[1] - text.height / 2,
|
|
892
|
-
width: text.width,
|
|
893
|
-
height: text.height
|
|
894
|
-
};
|
|
895
|
-
return RectangleClient.isHit(rectangle, RectangleClient.getRectangleByPoints([point, point]));
|
|
896
|
-
});
|
|
897
|
-
};
|
|
898
|
-
|
|
899
|
-
const isMultipleTextShape = (shape) => {
|
|
900
|
-
return GEOMETRY_WITH_MULTIPLE_TEXT.includes(shape);
|
|
901
|
-
};
|
|
902
|
-
const isMultipleTextGeometry = (geometry) => {
|
|
903
|
-
return PlaitDrawElement.isGeometry(geometry) && isMultipleTextShape(geometry.shape);
|
|
904
|
-
};
|
|
905
|
-
const getMultipleTextGeometryTextKeys = (shape) => {
|
|
906
|
-
return MultipleTextGeometryTextKeys[shape];
|
|
907
|
-
};
|
|
908
|
-
const createMultipleTextGeometryElement = (shape, points, options = {}) => {
|
|
909
|
-
const id = idCreator();
|
|
910
|
-
const drawShapeTexts = buildDefaultTextsByShape(shape);
|
|
911
|
-
return {
|
|
912
|
-
id,
|
|
913
|
-
type: 'geometry',
|
|
914
|
-
shape,
|
|
915
|
-
angle: 0,
|
|
916
|
-
opacity: 1,
|
|
917
|
-
texts: drawShapeTexts,
|
|
918
|
-
points,
|
|
919
|
-
...options
|
|
920
|
-
};
|
|
921
|
-
};
|
|
922
|
-
const buildDefaultTextsByShape = (shape) => {
|
|
923
|
-
const memorizedLatest = getMemorizedLatestByPointer(shape);
|
|
924
|
-
const textProperties = { ...memorizedLatest.textProperties };
|
|
925
|
-
const alignment = textProperties?.align;
|
|
926
|
-
const textHeight = textProperties?.textHeight || DefaultTextProperty.height;
|
|
927
|
-
delete textProperties?.align;
|
|
928
|
-
delete textProperties?.textHeight;
|
|
929
|
-
const defaultTexts = getDefaultGeometryProperty(shape)?.texts || [];
|
|
930
|
-
const textKeys = getMultipleTextGeometryTextKeys(shape);
|
|
931
|
-
return (textKeys || []).map((textKey) => {
|
|
932
|
-
const text = defaultTexts?.find((item) => item?.key === textKey);
|
|
972
|
+
return [newStartPoint, newEndPoint];
|
|
973
|
+
}
|
|
974
|
+
function getIndexAndDeleteCountByKeyPoint(board, element, dataPoints, nextRenderPoints, handleIndex) {
|
|
975
|
+
let index = null;
|
|
976
|
+
let deleteCount = null;
|
|
977
|
+
const startKeyPoint = nextRenderPoints[handleIndex];
|
|
978
|
+
const endKeyPoint = nextRenderPoints[handleIndex + 1];
|
|
979
|
+
if (!startKeyPoint || !endKeyPoint) {
|
|
933
980
|
return {
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
textHeight: textHeight
|
|
981
|
+
index,
|
|
982
|
+
deleteCount
|
|
937
983
|
};
|
|
938
|
-
});
|
|
939
|
-
};
|
|
940
|
-
const getHitMultipleGeometryText = (element, point) => {
|
|
941
|
-
const engine = getEngine(element.shape);
|
|
942
|
-
const rectangle = RectangleClient.getRectangleByPoints([point, point]);
|
|
943
|
-
let hitText;
|
|
944
|
-
if (engine.getTextRectangle) {
|
|
945
|
-
hitText = element.texts.find(text => {
|
|
946
|
-
const textRectangle = engine.getTextRectangle(element, { id: text.id });
|
|
947
|
-
return RectangleClient.isHit(rectangle, textRectangle);
|
|
948
|
-
});
|
|
949
|
-
}
|
|
950
|
-
return hitText;
|
|
951
|
-
};
|
|
952
|
-
|
|
953
|
-
const DefaultLineStyle = {
|
|
954
|
-
strokeWidth: 2,
|
|
955
|
-
strokeColor: '#000'
|
|
956
|
-
};
|
|
957
|
-
const LINE_TEXT_SPACE = 4;
|
|
958
|
-
const LINE_AUTO_COMPLETE_DIAMETER = 6;
|
|
959
|
-
const LINE_AUTO_COMPLETE_OPACITY = 0.6;
|
|
960
|
-
const LINE_AUTO_COMPLETE_HOVERED_OPACITY = 0.8;
|
|
961
|
-
const LINE_AUTO_COMPLETE_HOVERED_DIAMETER = 10;
|
|
962
|
-
const LINE_ALIGN_TOLERANCE = 3;
|
|
963
|
-
const LINE_TEXT = '文本';
|
|
964
|
-
|
|
965
|
-
class VectorLineShapeGenerator extends Generator {
|
|
966
|
-
canDraw(element) {
|
|
967
|
-
return true;
|
|
968
984
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
985
|
+
const midDataPoints = dataPoints.slice(1, -1);
|
|
986
|
+
const startIndex = midDataPoints.findIndex(item => Point.isEquals(item, startKeyPoint));
|
|
987
|
+
const endIndex = midDataPoints.findIndex(item => Point.isEquals(item, endKeyPoint));
|
|
988
|
+
if (Math.max(startIndex, endIndex) > -1) {
|
|
989
|
+
if (startIndex > -1 && endIndex > -1) {
|
|
990
|
+
return {
|
|
991
|
+
index: startIndex,
|
|
992
|
+
deleteCount: 2
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
if (startIndex > -1 && endIndex === -1) {
|
|
996
|
+
const isReplace = startIndex < midDataPoints.length - 1 &&
|
|
997
|
+
Point.isAlign([midDataPoints[startIndex], midDataPoints[startIndex + 1], startKeyPoint, endKeyPoint]);
|
|
998
|
+
if (isReplace) {
|
|
999
|
+
return {
|
|
1000
|
+
index: startIndex,
|
|
1001
|
+
deleteCount: 2
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
return {
|
|
1005
|
+
index: startIndex,
|
|
1006
|
+
deleteCount: 1
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
if (startIndex === -1 && endIndex > -1) {
|
|
1010
|
+
const isReplace = endIndex > 0 && Point.isAlign([midDataPoints[endIndex], midDataPoints[endIndex - 1], startKeyPoint, endKeyPoint]);
|
|
1011
|
+
if (isReplace) {
|
|
1012
|
+
return {
|
|
1013
|
+
index: endIndex - 1,
|
|
1014
|
+
deleteCount: 2
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
return {
|
|
1018
|
+
index: endIndex,
|
|
1019
|
+
deleteCount: 1
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
973
1022
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
const
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1023
|
+
else {
|
|
1024
|
+
for (let i = 0; i < midDataPoints.length - 1; i++) {
|
|
1025
|
+
const currentPoint = midDataPoints[i];
|
|
1026
|
+
const nextPoint = midDataPoints[i + 1];
|
|
1027
|
+
if (Point.isAlign([currentPoint, nextPoint, startKeyPoint, endKeyPoint])) {
|
|
1028
|
+
index = i;
|
|
1029
|
+
deleteCount = 2;
|
|
1030
|
+
break;
|
|
1031
|
+
}
|
|
1032
|
+
if (Point.isAlign([currentPoint, nextPoint, startKeyPoint])) {
|
|
1033
|
+
index = Math.min(i + 1, midDataPoints.length - 1);
|
|
1034
|
+
deleteCount = 1;
|
|
1035
|
+
break;
|
|
1036
|
+
}
|
|
1037
|
+
if (Point.isAlign([currentPoint, nextPoint, endKeyPoint])) {
|
|
1038
|
+
index = Math.max(i - 1, 0);
|
|
1039
|
+
deleteCount = 1;
|
|
1040
|
+
break;
|
|
1041
|
+
}
|
|
980
1042
|
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1043
|
+
}
|
|
1044
|
+
if (index === null) {
|
|
1045
|
+
deleteCount = 0;
|
|
1046
|
+
if (midDataPoints.length > 0) {
|
|
1047
|
+
const handleRefPair = getArrowLineHandleRefPair(board, element);
|
|
1048
|
+
const params = getElbowLineRouteOptions(board, element, handleRefPair);
|
|
1049
|
+
const keyPoints = removeDuplicatePoints(generateElbowLineRoute(params, board));
|
|
1050
|
+
const nextKeyPoints = simplifyOrthogonalPoints(keyPoints.slice(1, keyPoints.length - 1));
|
|
1051
|
+
const nextDataPoints = [nextRenderPoints[0], ...midDataPoints, nextRenderPoints[nextRenderPoints.length - 1]];
|
|
1052
|
+
const mirrorDataPoints = getMirrorDataPoints(board, nextDataPoints, nextKeyPoints, params);
|
|
1053
|
+
for (let i = handleIndex - 1; i >= 0; i--) {
|
|
1054
|
+
const previousIndex = mirrorDataPoints.slice(1, -1).findIndex(item => Point.isEquals(item, nextRenderPoints[i]));
|
|
1055
|
+
if (previousIndex > -1) {
|
|
1056
|
+
index = previousIndex + 1;
|
|
1057
|
+
break;
|
|
1058
|
+
}
|
|
984
1059
|
}
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1060
|
+
if (index === null) {
|
|
1061
|
+
index = 0;
|
|
1062
|
+
// When renderPoints is a straight line and dataPoints are not on the line,
|
|
1063
|
+
// the default 'deleteCount' is set to midDataPoints.length.
|
|
1064
|
+
if (Point.isAlign(nextRenderPoints)) {
|
|
1065
|
+
deleteCount = midDataPoints.length;
|
|
1066
|
+
}
|
|
989
1067
|
}
|
|
990
1068
|
}
|
|
991
|
-
|
|
992
|
-
|
|
1069
|
+
else {
|
|
1070
|
+
index = 0;
|
|
1071
|
+
}
|
|
993
1072
|
}
|
|
994
|
-
};
|
|
995
|
-
const createVectorLineElement = (shape, points, options) => {
|
|
996
1073
|
return {
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
shape,
|
|
1000
|
-
opacity: 1,
|
|
1001
|
-
points,
|
|
1002
|
-
...options
|
|
1074
|
+
index,
|
|
1075
|
+
deleteCount
|
|
1003
1076
|
};
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
const temporaryLineElement = createVectorLineElement(lineShape, [...points, movingPoint], {
|
|
1009
|
-
strokeWidth: DefaultLineStyle.strokeWidth,
|
|
1010
|
-
...memorizedLatest
|
|
1011
|
-
});
|
|
1012
|
-
const otherPoint = points[points.length - 1];
|
|
1013
|
-
temporaryLineElement.points[temporaryLineElement.points.length - 1] = alignPoints(otherPoint, movingPoint);
|
|
1014
|
-
lineGenerator.processDrawing(temporaryLineElement, lineShapeG);
|
|
1015
|
-
PlaitBoard.getElementActiveHost(board).append(lineShapeG);
|
|
1016
|
-
return temporaryLineElement;
|
|
1017
|
-
};
|
|
1018
|
-
const drawVectorLine = (board, element) => {
|
|
1019
|
-
const strokeWidth = getStrokeWidthByElement(element);
|
|
1020
|
-
const strokeColor = getStrokeColorByElement(board, element);
|
|
1021
|
-
const strokeStyle = getStrokeStyleByElement(board, element);
|
|
1022
|
-
const strokeLineDash = getStrokeLineDash(strokeStyle, strokeWidth);
|
|
1023
|
-
const fill = getFillByElement(board, element);
|
|
1024
|
-
const options = { stroke: strokeColor, strokeWidth, strokeLineDash, fill };
|
|
1025
|
-
const lineG = createG();
|
|
1026
|
-
let points = getVectorLinePoints(board, element);
|
|
1027
|
-
const line = drawLinearPath(points, options);
|
|
1028
|
-
const id = idCreator();
|
|
1029
|
-
line.setAttribute('mask', `url(#${id})`);
|
|
1030
|
-
if (element.strokeStyle === StrokeStyle.dotted) {
|
|
1031
|
-
setStrokeLinecap(line, 'round');
|
|
1032
|
-
}
|
|
1033
|
-
lineG.appendChild(line);
|
|
1034
|
-
return lineG;
|
|
1035
|
-
};
|
|
1036
|
-
|
|
1037
|
-
const getCenterPointsOnPolygon$1 = (points) => {
|
|
1038
|
-
const centerPoints = [];
|
|
1039
|
-
for (let i = 0; i < points.length; i++) {
|
|
1040
|
-
let j = i == points.length - 1 ? 0 : i + 1;
|
|
1041
|
-
centerPoints.push([(points[i][0] + points[j][0]) / 2, (points[i][1] + points[j][1]) / 2]);
|
|
1042
|
-
}
|
|
1043
|
-
return centerPoints;
|
|
1044
|
-
};
|
|
1045
|
-
const getCrossingPointBetweenPointAndPolygon = (corners, point) => {
|
|
1046
|
-
const result = [];
|
|
1047
|
-
for (let index = 1; index <= corners.length; index++) {
|
|
1048
|
-
let start = corners[index - 1];
|
|
1049
|
-
let end = index === corners.length ? corners[0] : corners[index];
|
|
1050
|
-
const crossingPoint = getCrossingPointsBetweenPointAndSegment(point, start, end);
|
|
1051
|
-
result.push(...crossingPoint);
|
|
1077
|
+
}
|
|
1078
|
+
function getMirrorDataPoints(board, nextDataPoints, nextKeyPoints, params) {
|
|
1079
|
+
for (let index = 1; index < nextDataPoints.length - 2; index++) {
|
|
1080
|
+
adjustByCustomPointStartIndex(board, index, nextDataPoints, nextKeyPoints, params);
|
|
1052
1081
|
}
|
|
1053
|
-
return
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1082
|
+
return nextDataPoints;
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* adjust based parallel segment
|
|
1086
|
+
*/
|
|
1087
|
+
const adjustByCustomPointStartIndex = (board, customPointStartIndex, nextDataPoints, nextKeyPoints, params) => {
|
|
1088
|
+
const beforePoint = nextDataPoints[customPointStartIndex - 1];
|
|
1089
|
+
const startPoint = nextDataPoints[customPointStartIndex];
|
|
1090
|
+
const endPoint = nextDataPoints[customPointStartIndex + 1];
|
|
1091
|
+
const afterPoint = nextDataPoints[customPointStartIndex + 2];
|
|
1092
|
+
const beforeSegment = [beforePoint, startPoint];
|
|
1093
|
+
const afterSegment = [endPoint, afterPoint];
|
|
1094
|
+
const isStraightWithBefore = Point.isAlign(beforeSegment);
|
|
1095
|
+
const isStraightWithAfter = Point.isAlign(afterSegment);
|
|
1096
|
+
let isAdjustStart = false;
|
|
1097
|
+
let isAdjustEnd = false;
|
|
1098
|
+
if (!isStraightWithBefore || !isStraightWithAfter) {
|
|
1099
|
+
const midKeyPointsWithBefore = getMidKeyPoints(nextKeyPoints, beforeSegment[0], beforeSegment[1]);
|
|
1100
|
+
const midKeyPointsWithAfter = getMidKeyPoints(nextKeyPoints, afterSegment[0], afterSegment[1]);
|
|
1101
|
+
const hasMidKeyPoints = midKeyPointsWithBefore.length > 0 && midKeyPointsWithAfter.length > 0;
|
|
1102
|
+
isAdjustStart = !isStraightWithBefore && !hasMidKeyPoints;
|
|
1103
|
+
isAdjustEnd = !isStraightWithAfter && !hasMidKeyPoints;
|
|
1062
1104
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
ry: yRadius * 1.2,
|
|
1076
|
-
xAxisRotation: 0,
|
|
1077
|
-
largeArcFlag: 1,
|
|
1078
|
-
sweepFlag: 1,
|
|
1079
|
-
endX: rectangle.x + divisionWidth * 2,
|
|
1080
|
-
endY: rectangle.y + divisionHeight / 2
|
|
1081
|
-
},
|
|
1082
|
-
{
|
|
1083
|
-
rx: xRadius,
|
|
1084
|
-
ry: yRadius,
|
|
1085
|
-
xAxisRotation: 0,
|
|
1086
|
-
largeArcFlag: 1,
|
|
1087
|
-
sweepFlag: 1,
|
|
1088
|
-
endX: rectangle.x + divisionWidth * 4.2,
|
|
1089
|
-
endY: rectangle.y + divisionHeight / 2.2
|
|
1090
|
-
},
|
|
1091
|
-
{
|
|
1092
|
-
rx: xRadius,
|
|
1093
|
-
ry: yRadius,
|
|
1094
|
-
xAxisRotation: 0,
|
|
1095
|
-
largeArcFlag: 1,
|
|
1096
|
-
sweepFlag: 1,
|
|
1097
|
-
endX: rectangle.x + divisionWidth * 5.8,
|
|
1098
|
-
endY: rectangle.y + divisionHeight
|
|
1099
|
-
},
|
|
1100
|
-
{
|
|
1101
|
-
rx: xRadius,
|
|
1102
|
-
ry: yRadius * 1.3,
|
|
1103
|
-
xAxisRotation: 0,
|
|
1104
|
-
largeArcFlag: 1,
|
|
1105
|
-
sweepFlag: 1,
|
|
1106
|
-
endX: rectangle.x + divisionWidth * 6,
|
|
1107
|
-
endY: rectangle.y + divisionHeight * 2.2
|
|
1108
|
-
},
|
|
1109
|
-
{
|
|
1110
|
-
rx: xRadius,
|
|
1111
|
-
ry: yRadius * 1.2,
|
|
1112
|
-
xAxisRotation: 0,
|
|
1113
|
-
largeArcFlag: 1,
|
|
1114
|
-
sweepFlag: 1,
|
|
1115
|
-
endX: rectangle.x + divisionWidth * 5,
|
|
1116
|
-
endY: rectangle.y + divisionHeight * 2.8
|
|
1117
|
-
},
|
|
1118
|
-
{
|
|
1119
|
-
rx: xRadius,
|
|
1120
|
-
ry: yRadius / 1.2,
|
|
1121
|
-
xAxisRotation: 0,
|
|
1122
|
-
largeArcFlag: 1,
|
|
1123
|
-
sweepFlag: 1,
|
|
1124
|
-
endX: rectangle.x + divisionWidth * 2.8,
|
|
1125
|
-
endY: rectangle.y + divisionHeight * 2.8
|
|
1126
|
-
},
|
|
1127
|
-
{
|
|
1128
|
-
rx: xRadius,
|
|
1129
|
-
ry: yRadius,
|
|
1130
|
-
xAxisRotation: 0,
|
|
1131
|
-
largeArcFlag: 1,
|
|
1132
|
-
sweepFlag: 1,
|
|
1133
|
-
endX: rectangle.x + divisionWidth,
|
|
1134
|
-
endY: rectangle.y + divisionHeight * 2.2
|
|
1135
|
-
},
|
|
1136
|
-
{
|
|
1137
|
-
rx: xRadius,
|
|
1138
|
-
ry: yRadius * 1.42,
|
|
1139
|
-
xAxisRotation: 0,
|
|
1140
|
-
largeArcFlag: 1,
|
|
1141
|
-
sweepFlag: 1,
|
|
1142
|
-
endX: rectangle.x + divisionWidth,
|
|
1143
|
-
endY: rectangle.y + divisionHeight
|
|
1105
|
+
if (isAdjustStart || isAdjustEnd) {
|
|
1106
|
+
const parallelSegment = [startPoint, endPoint];
|
|
1107
|
+
const parallelSegments = findOrthogonalParallelSegments(parallelSegment, nextKeyPoints);
|
|
1108
|
+
const mirrorSegments = findMirrorSegments(board, parallelSegment, parallelSegments, params.sourceRectangle, params.targetRectangle);
|
|
1109
|
+
if (mirrorSegments.length === 1) {
|
|
1110
|
+
const mirrorSegment = mirrorSegments[0];
|
|
1111
|
+
if (isAdjustStart) {
|
|
1112
|
+
nextDataPoints.splice(customPointStartIndex, 1, mirrorSegment[0]);
|
|
1113
|
+
}
|
|
1114
|
+
if (isAdjustEnd) {
|
|
1115
|
+
nextDataPoints.splice(customPointStartIndex + 1, 1, mirrorSegment[1]);
|
|
1116
|
+
}
|
|
1144
1117
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
const svgElement = rs.path(pathData, { ...options, fillStyle: 'solid' });
|
|
1158
|
-
setPathStrokeLinecap(svgElement, 'round');
|
|
1159
|
-
return svgElement;
|
|
1160
|
-
},
|
|
1161
|
-
isInsidePoint(rectangle, point) {
|
|
1162
|
-
const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
|
|
1163
|
-
return RectangleClient.isHit(rectangle, rangeRectangle);
|
|
1164
|
-
},
|
|
1165
|
-
getCornerPoints(rectangle) {
|
|
1166
|
-
return RectangleClient.getCornerPoints(rectangle);
|
|
1167
|
-
},
|
|
1168
|
-
getNearestPoint(rectangle, point) {
|
|
1169
|
-
const { startPoint, arcCommands } = generateCloudPath(rectangle);
|
|
1170
|
-
let minDistance = Infinity;
|
|
1171
|
-
let nearestPoint = point;
|
|
1172
|
-
let currentStart = startPoint;
|
|
1173
|
-
for (const arcCommand of arcCommands) {
|
|
1174
|
-
const arcNearestPoint = getNearestPointBetweenPointAndArc(point, currentStart, arcCommand);
|
|
1175
|
-
const distance = distanceBetweenPointAndPoint(point[0], point[1], arcNearestPoint[0], arcNearestPoint[1]);
|
|
1176
|
-
if (distance < minDistance) {
|
|
1177
|
-
minDistance = distance;
|
|
1178
|
-
nearestPoint = arcNearestPoint;
|
|
1118
|
+
else {
|
|
1119
|
+
const isHorizontal = Point.isHorizontal(startPoint, endPoint);
|
|
1120
|
+
const adjustIndex = isHorizontal ? 0 : 1;
|
|
1121
|
+
if (isAdjustStart) {
|
|
1122
|
+
const newStartPoint = [startPoint[0], startPoint[1]];
|
|
1123
|
+
newStartPoint[adjustIndex] = beforePoint[adjustIndex];
|
|
1124
|
+
nextDataPoints.splice(customPointStartIndex, 1, newStartPoint);
|
|
1125
|
+
}
|
|
1126
|
+
if (isAdjustEnd) {
|
|
1127
|
+
const newEndPoint = [endPoint[0], endPoint[1]];
|
|
1128
|
+
newEndPoint[adjustIndex] = afterPoint[adjustIndex];
|
|
1129
|
+
nextDataPoints.splice(customPointStartIndex + 1, 1, newEndPoint);
|
|
1179
1130
|
}
|
|
1180
|
-
currentStart = [arcCommand.endX, arcCommand.endY];
|
|
1181
1131
|
}
|
|
1182
|
-
return nearestPoint;
|
|
1183
|
-
},
|
|
1184
|
-
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
1185
|
-
const corners = CloudEngine.getCornerPoints(rectangle);
|
|
1186
|
-
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
1187
|
-
return getPolygonEdgeByConnectionPoint(corners, point);
|
|
1188
|
-
},
|
|
1189
|
-
getConnectorPoints(rectangle) {
|
|
1190
|
-
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
1191
|
-
},
|
|
1192
|
-
getTextRectangle(element) {
|
|
1193
|
-
const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
|
|
1194
|
-
const strokeWidth = getStrokeWidthByElement(element);
|
|
1195
|
-
const height = element.textHeight;
|
|
1196
|
-
const originWidth = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
|
|
1197
|
-
const width = originWidth / 1.5;
|
|
1198
|
-
return {
|
|
1199
|
-
height,
|
|
1200
|
-
width: width > 0 ? width : 0,
|
|
1201
|
-
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth + originWidth / 6,
|
|
1202
|
-
y: elementRectangle.y + elementRectangle.height / 6 + ((elementRectangle.height * 4) / 6 - height) / 2
|
|
1203
|
-
};
|
|
1204
1132
|
}
|
|
1205
1133
|
};
|
|
1206
|
-
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
if (geometry.textHeight && geometry.textHeight > client.height) {
|
|
1134
|
+
function isUpdatedHandleIndex(board, element, dataPoints, nextRenderPoints, handleIndex) {
|
|
1135
|
+
const { deleteCount } = getIndexAndDeleteCountByKeyPoint(board, element, dataPoints, nextRenderPoints, handleIndex);
|
|
1136
|
+
if (deleteCount !== null && deleteCount > 1) {
|
|
1210
1137
|
return true;
|
|
1211
1138
|
}
|
|
1212
1139
|
return false;
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
}
|
|
1226
|
-
const isHitVectorLine = (board, element, point) => {
|
|
1227
|
-
const points = getVectorLinePoints(board, element);
|
|
1228
|
-
if (isClosedPoints(element.points)) {
|
|
1229
|
-
return isPointInPolygon(point, points) || isHitPolyLine(points, point);
|
|
1230
|
-
}
|
|
1231
|
-
else {
|
|
1232
|
-
return isHitPolyLine(points, point);
|
|
1233
|
-
}
|
|
1234
|
-
};
|
|
1235
|
-
const isRectangleHitElementText = (element, rectangle) => {
|
|
1236
|
-
const engine = getEngine(element.shape);
|
|
1237
|
-
if (isMultipleTextGeometry(element)) {
|
|
1238
|
-
const texts = element.texts;
|
|
1239
|
-
return texts.some((item) => {
|
|
1240
|
-
const textClient = engine.getTextRectangle(element, { id: item.id });
|
|
1241
|
-
return isRectangleHitRotatedPoints(rectangle, RectangleClient.getCornerPoints(textClient), element.angle);
|
|
1242
|
-
});
|
|
1140
|
+
}
|
|
1141
|
+
function getMidKeyPoints(simplifiedNextKeyPoints, startPoint, endPoint) {
|
|
1142
|
+
let midElbowPoints = [];
|
|
1143
|
+
let startPointIndex = -1;
|
|
1144
|
+
let endPointIndex = -1;
|
|
1145
|
+
for (let i = 0; i < simplifiedNextKeyPoints.length; i++) {
|
|
1146
|
+
if (Point.isAlign([simplifiedNextKeyPoints[i], startPoint])) {
|
|
1147
|
+
startPointIndex = i;
|
|
1148
|
+
}
|
|
1149
|
+
if (startPointIndex > -1 && Point.isAlign([simplifiedNextKeyPoints[i], endPoint])) {
|
|
1150
|
+
endPointIndex = i;
|
|
1151
|
+
break;
|
|
1152
|
+
}
|
|
1243
1153
|
}
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
return isRectangleHitRotatedPoints(rectangle, RectangleClient.getCornerPoints(textClient), element.angle);
|
|
1154
|
+
if (startPointIndex > -1 && endPointIndex > -1) {
|
|
1155
|
+
midElbowPoints = simplifiedNextKeyPoints.slice(startPointIndex, endPointIndex + 1);
|
|
1247
1156
|
}
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1157
|
+
return midElbowPoints;
|
|
1158
|
+
}
|
|
1159
|
+
function findOrthogonalParallelSegments(segment, keyPoints) {
|
|
1160
|
+
const isHorizontalSegment = Point.isHorizontal(segment[0], segment[1]);
|
|
1161
|
+
const parallelSegments = [];
|
|
1162
|
+
for (let i = 0; i < keyPoints.length - 1; i++) {
|
|
1163
|
+
const current = keyPoints[i];
|
|
1164
|
+
const next = keyPoints[i + 1];
|
|
1165
|
+
const isHorizontal = Point.isHorizontal(current, next, 0.1);
|
|
1166
|
+
if (isHorizontalSegment && isHorizontal) {
|
|
1167
|
+
parallelSegments.push([current, next]);
|
|
1168
|
+
}
|
|
1169
|
+
if (!isHorizontalSegment && !isHorizontal) {
|
|
1170
|
+
parallelSegments.push([current, next]);
|
|
1171
|
+
}
|
|
1257
1172
|
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1173
|
+
return parallelSegments;
|
|
1174
|
+
}
|
|
1175
|
+
function findMirrorSegments(board, segment, parallelSegments, sourceRectangle, targetRectangle) {
|
|
1176
|
+
debugGenerator$4.isDebug() && debugGenerator$4.clear();
|
|
1177
|
+
const mirrorSegments = [];
|
|
1178
|
+
for (let index = 0; index < parallelSegments.length; index++) {
|
|
1179
|
+
const parallelPath = parallelSegments[index];
|
|
1180
|
+
const startPoint = [segment[0][0], segment[0][1]];
|
|
1181
|
+
const endPoint = [segment[1][0], segment[1][1]];
|
|
1182
|
+
const isHorizontal = Point.isHorizontal(startPoint, endPoint);
|
|
1183
|
+
const adjustDataIndex = isHorizontal ? 0 : 1;
|
|
1184
|
+
startPoint[adjustDataIndex] = parallelPath[0][adjustDataIndex];
|
|
1185
|
+
endPoint[adjustDataIndex] = parallelPath[1][adjustDataIndex];
|
|
1186
|
+
const fakeRectangle = RectangleClient.getRectangleByPoints([startPoint, endPoint, ...parallelPath]);
|
|
1187
|
+
const isValid = !RectangleClient.isHit(fakeRectangle, sourceRectangle) && !RectangleClient.isHit(fakeRectangle, targetRectangle);
|
|
1188
|
+
if (isValid) {
|
|
1189
|
+
mirrorSegments.push([startPoint, endPoint]);
|
|
1190
|
+
debugGenerator$4.isDebug() && debugGenerator$4.drawPolygon(board, RectangleClient.getCornerPoints(fakeRectangle));
|
|
1191
|
+
}
|
|
1261
1192
|
}
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1193
|
+
return mirrorSegments;
|
|
1194
|
+
}
|
|
1195
|
+
const hasIllegalElbowPoint = (midDataPoints) => {
|
|
1196
|
+
if (midDataPoints.length === 1) {
|
|
1265
1197
|
return true;
|
|
1266
1198
|
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
const
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
const
|
|
1274
|
-
if (
|
|
1275
|
-
return
|
|
1199
|
+
return midDataPoints.some((item, index) => {
|
|
1200
|
+
const beforePoint = midDataPoints[index - 1];
|
|
1201
|
+
const afterPoint = midDataPoints[index + 1];
|
|
1202
|
+
const beforeSegment = beforePoint && [beforePoint, item];
|
|
1203
|
+
const afterSegment = afterPoint && [item, afterPoint];
|
|
1204
|
+
const isStraightWithBefore = beforeSegment && Point.isAlign(beforeSegment);
|
|
1205
|
+
const isStraightWithAfter = afterSegment && Point.isAlign(afterSegment);
|
|
1206
|
+
if (index === 0) {
|
|
1207
|
+
return !isStraightWithAfter;
|
|
1276
1208
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
return
|
|
1281
|
-
}
|
|
1282
|
-
if (PlaitDrawElement.isArrowLine(element)) {
|
|
1283
|
-
const points = getArrowLinePoints(board, element);
|
|
1284
|
-
return isLineHitRectangle(points, rangeRectangle);
|
|
1285
|
-
}
|
|
1286
|
-
if (PlaitDrawElement.isVectorLine(element)) {
|
|
1287
|
-
const points = getVectorLinePoints(board, element);
|
|
1288
|
-
return isLineHitRectangle(points, rangeRectangle);
|
|
1289
|
-
}
|
|
1290
|
-
return null;
|
|
1291
|
-
};
|
|
1292
|
-
const isRectangleHitRotatedElement = (board, rectangle, element) => {
|
|
1293
|
-
const client = RectangleClient.getRectangleByPoints(element.points);
|
|
1294
|
-
return isRectangleHitRotatedPoints(rectangle, RectangleClient.getCornerPoints(client), element.angle);
|
|
1295
|
-
};
|
|
1296
|
-
const isRectangleHitRotatedPoints = (rectangle, points, angle) => {
|
|
1297
|
-
let rotatedPoints = rotatePointsByAngle(points, angle) || points;
|
|
1298
|
-
return isLineHitRectangle(rotatedPoints, rectangle);
|
|
1209
|
+
if (index === midDataPoints.length - 1) {
|
|
1210
|
+
return !isStraightWithBefore;
|
|
1211
|
+
}
|
|
1212
|
+
return !isStraightWithBefore && !isStraightWithAfter;
|
|
1213
|
+
});
|
|
1299
1214
|
};
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
const newElements = elements.slice(0, endIndex);
|
|
1307
|
-
const element = getFirstTextOrLineElement(newElements);
|
|
1308
|
-
if (element) {
|
|
1309
|
-
return element;
|
|
1215
|
+
|
|
1216
|
+
const ARROW_LENGTH = 20;
|
|
1217
|
+
const drawArrowLineArrow = (element, points, options) => {
|
|
1218
|
+
const arrowG = createG();
|
|
1219
|
+
if (PlaitArrowLine.isSourceMark(element, ArrowLineMarkerType.none) && PlaitArrowLine.isTargetMark(element, ArrowLineMarkerType.none)) {
|
|
1220
|
+
return null;
|
|
1310
1221
|
}
|
|
1311
|
-
const
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
let filledElement = null;
|
|
1316
|
-
for (let i = 0; i < elements.length; i++) {
|
|
1317
|
-
const element = elements[i];
|
|
1318
|
-
if (isClosedCustomGeometry(board, element) || isClosedDrawElement(element)) {
|
|
1319
|
-
const fill = getFillByElement(board, element);
|
|
1320
|
-
if (isFilled(fill)) {
|
|
1321
|
-
filledElement = element;
|
|
1322
|
-
break;
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1222
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1223
|
+
const offset = (strokeWidth * strokeWidth) / 3;
|
|
1224
|
+
if (points.length === 1) {
|
|
1225
|
+
points = [points[0], [points[0][0] + 0.1, points[0][1]]];
|
|
1325
1226
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
const
|
|
1329
|
-
|
|
1330
|
-
};
|
|
1331
|
-
const getFirstTextOrLineElement = (elements) => {
|
|
1332
|
-
const texts = elements.filter((item) => PlaitDrawElement.isText(item));
|
|
1333
|
-
if (texts.length) {
|
|
1334
|
-
return texts[0];
|
|
1227
|
+
if (!PlaitArrowLine.isSourceMark(element, ArrowLineMarkerType.none)) {
|
|
1228
|
+
const source = getExtendPoint(points[0], points[1], ARROW_LENGTH + offset);
|
|
1229
|
+
const sourceArrow = getArrow(element, { marker: element.source.marker, source, target: points[0], isSource: true }, options);
|
|
1230
|
+
sourceArrow && arrowG.appendChild(sourceArrow);
|
|
1335
1231
|
}
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1232
|
+
if (!PlaitArrowLine.isTargetMark(element, ArrowLineMarkerType.none)) {
|
|
1233
|
+
const source = getExtendPoint(points[points.length - 1], points[points.length - 2], ARROW_LENGTH + offset);
|
|
1234
|
+
const arrow = getArrow(element, { marker: element.target.marker, source, target: points[points.length - 1], isSource: false }, options);
|
|
1235
|
+
arrow && arrowG.appendChild(arrow);
|
|
1339
1236
|
}
|
|
1340
|
-
return
|
|
1237
|
+
return arrowG;
|
|
1341
1238
|
};
|
|
1342
|
-
const
|
|
1343
|
-
const
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
if (debugGenerator$4.isDebug() && shapes.includes(element.shape)) {
|
|
1350
|
-
debugGenerator$4.clear();
|
|
1351
|
-
const { startPoint, arcCommands } = generateCloudPath(rectangle);
|
|
1352
|
-
const points = [startPoint, ...arcCommands.map((arc) => [arc.endX, arc.endY])];
|
|
1353
|
-
debugGenerator$4.drawCircles(board, points, 5, false);
|
|
1354
|
-
let minDistance = Infinity;
|
|
1355
|
-
let nearestPoint = point;
|
|
1356
|
-
let currentStart = startPoint;
|
|
1357
|
-
for (const arc of arcCommands) {
|
|
1358
|
-
const arcNearestPoint = getNearestPointBetweenPointAndArc(point, currentStart, arc);
|
|
1359
|
-
const distance = distanceBetweenPointAndPoint(point[0], point[1], arcNearestPoint[0], arcNearestPoint[1]);
|
|
1360
|
-
const { center } = getEllipseArcCenter(currentStart, arc);
|
|
1361
|
-
debugGenerator$4.drawCircles(board, [center], 8, false, { fill: 'yellow' });
|
|
1362
|
-
if (distance < minDistance) {
|
|
1363
|
-
minDistance = distance;
|
|
1364
|
-
nearestPoint = arcNearestPoint;
|
|
1365
|
-
}
|
|
1366
|
-
currentStart = [arc.endX, arc.endY];
|
|
1367
|
-
}
|
|
1368
|
-
debugGenerator$4.drawCircles(board, [point], 12, false, { fill: 'black', stroke: 'black' });
|
|
1369
|
-
debugGenerator$4.drawCircles(board, [nearestPoint], 12, false, { fill: 'green', stroke: 'green' });
|
|
1239
|
+
const getArrow = (element, arrowOptions, options) => {
|
|
1240
|
+
const { marker, target, source, isSource } = arrowOptions;
|
|
1241
|
+
let targetArrow;
|
|
1242
|
+
switch (marker) {
|
|
1243
|
+
case ArrowLineMarkerType.openTriangle: {
|
|
1244
|
+
targetArrow = drawOpenTriangle(element, source, target, options);
|
|
1245
|
+
break;
|
|
1370
1246
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1247
|
+
case ArrowLineMarkerType.solidTriangle: {
|
|
1248
|
+
targetArrow = drawSolidTriangle(source, target, options);
|
|
1249
|
+
break;
|
|
1373
1250
|
}
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
return RectangleClient.isPointInRectangle(textClient, point);
|
|
1251
|
+
case ArrowLineMarkerType.arrow: {
|
|
1252
|
+
targetArrow = drawArrow(element, source, target, options);
|
|
1253
|
+
break;
|
|
1378
1254
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1255
|
+
case ArrowLineMarkerType.sharpArrow: {
|
|
1256
|
+
targetArrow = drawSharpArrow(source, target, options);
|
|
1257
|
+
break;
|
|
1381
1258
|
}
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
if (PlaitDrawElement.isImage(element)) {
|
|
1386
|
-
const client = RectangleClient.getRectangleByPoints(element.points);
|
|
1387
|
-
return RectangleClient.isPointInRectangle(client, point);
|
|
1388
|
-
}
|
|
1389
|
-
if (PlaitDrawElement.isArrowLine(element)) {
|
|
1390
|
-
return isHitArrowLine(board, element, point);
|
|
1391
|
-
}
|
|
1392
|
-
if (PlaitDrawElement.isVectorLine(element)) {
|
|
1393
|
-
return isHitVectorLine(board, element, point);
|
|
1394
|
-
}
|
|
1395
|
-
return null;
|
|
1396
|
-
};
|
|
1397
|
-
const isHitEdgeOfShape = (board, element, point, hitDistanceBuffer) => {
|
|
1398
|
-
const nearestPoint = getNearestPoint(element, point);
|
|
1399
|
-
const distance = distanceBetweenPointAndPoint(nearestPoint[0], nearestPoint[1], point[0], point[1]);
|
|
1400
|
-
return distance <= hitDistanceBuffer;
|
|
1401
|
-
};
|
|
1402
|
-
const isInsideOfShape = (board, element, point, hitDistanceBuffer) => {
|
|
1403
|
-
const client = RectangleClient.inflate(RectangleClient.getRectangleByPoints(element.points), hitDistanceBuffer);
|
|
1404
|
-
return getEngine(getElementShape(element)).isInsidePoint(client, point);
|
|
1405
|
-
};
|
|
1406
|
-
const isHitElementInside = (board, element, point) => {
|
|
1407
|
-
const rectangle = board.getRectangle(element);
|
|
1408
|
-
point = rotateAntiPointsByElement(point, element) || point;
|
|
1409
|
-
if (PlaitDrawElement.isGeometry(element) && !PlaitDrawElement.isGeometryByTable(element)) {
|
|
1410
|
-
const engine = getEngine(getElementShape(element));
|
|
1411
|
-
const isHitInside = engine.isInsidePoint(rectangle, point);
|
|
1412
|
-
if (isHitInside) {
|
|
1413
|
-
return isHitInside;
|
|
1259
|
+
case ArrowLineMarkerType.oneSideUp: {
|
|
1260
|
+
targetArrow = drawOneSideArrow(source, target, isSource ? 'down' : 'up', options);
|
|
1261
|
+
break;
|
|
1414
1262
|
}
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1263
|
+
case ArrowLineMarkerType.oneSideDown: {
|
|
1264
|
+
targetArrow = drawOneSideArrow(source, target, isSource ? 'up' : 'down', options);
|
|
1265
|
+
break;
|
|
1266
|
+
}
|
|
1267
|
+
case ArrowLineMarkerType.hollowTriangle: {
|
|
1268
|
+
targetArrow = drawHollowTriangleArrow(source, target, options);
|
|
1269
|
+
break;
|
|
1270
|
+
}
|
|
1271
|
+
case ArrowLineMarkerType.singleSlash: {
|
|
1272
|
+
targetArrow = drawSingleSlash(source, target, isSource, options);
|
|
1273
|
+
break;
|
|
1420
1274
|
}
|
|
1421
1275
|
}
|
|
1422
|
-
|
|
1423
|
-
const client = RectangleClient.getRectangleByPoints(element.points);
|
|
1424
|
-
return RectangleClient.isPointInRectangle(client, point);
|
|
1425
|
-
}
|
|
1426
|
-
if (PlaitDrawElement.isArrowLine(element)) {
|
|
1427
|
-
return isHitArrowLine(board, element, point);
|
|
1428
|
-
}
|
|
1429
|
-
if (PlaitDrawElement.isVectorLine(element)) {
|
|
1430
|
-
return isHitVectorLine(board, element, point);
|
|
1431
|
-
}
|
|
1432
|
-
return null;
|
|
1276
|
+
return targetArrow;
|
|
1433
1277
|
};
|
|
1434
|
-
|
|
1435
|
-
const
|
|
1436
|
-
const
|
|
1437
|
-
const
|
|
1438
|
-
const
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1278
|
+
const drawSharpArrow = (source, target, options) => {
|
|
1279
|
+
const startPoint = target;
|
|
1280
|
+
const { pointLeft, pointRight } = arrowPoints(source, target, 20);
|
|
1281
|
+
const g = createG();
|
|
1282
|
+
const path = createPath();
|
|
1283
|
+
let polylinePath = `M${pointRight[0]},${pointRight[1]}A25,25,20,0,1,${pointLeft[0]},${pointLeft[1]}L${startPoint[0]},${startPoint[1]}Z`;
|
|
1284
|
+
path.setAttribute('d', polylinePath);
|
|
1285
|
+
path.setAttribute('stroke', `${options?.stroke}`);
|
|
1286
|
+
path.setAttribute('stroke-width', `${options?.strokeWidth}`);
|
|
1287
|
+
path.setAttribute('fill', `${options?.stroke}`);
|
|
1288
|
+
g.appendChild(path);
|
|
1289
|
+
return g;
|
|
1446
1290
|
};
|
|
1447
|
-
const
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
const
|
|
1452
|
-
|
|
1291
|
+
const drawArrow = (element, source, target, options) => {
|
|
1292
|
+
const unitVector = getUnitVectorByPointAndPoint(source, target);
|
|
1293
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1294
|
+
const endPoint = [target[0] + (strokeWidth * unitVector[0]) / 2, target[1] + (strokeWidth * unitVector[1]) / 2];
|
|
1295
|
+
const distance = distanceBetweenPointAndPoint(...source, ...endPoint);
|
|
1296
|
+
const middlePoint = [
|
|
1297
|
+
endPoint[0] - (((distance * 3) / 5 + strokeWidth) / 2) * unitVector[0],
|
|
1298
|
+
endPoint[1] - (((distance * 3) / 5 + strokeWidth) / 2) * unitVector[1]
|
|
1299
|
+
];
|
|
1300
|
+
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 30);
|
|
1301
|
+
const arrowG = drawLinearPath([pointLeft, endPoint, pointRight, middlePoint], { ...options, fill: options.stroke }, true);
|
|
1302
|
+
const path = arrowG.querySelector('path');
|
|
1303
|
+
path.setAttribute('stroke-linejoin', 'round');
|
|
1304
|
+
return arrowG;
|
|
1453
1305
|
};
|
|
1454
|
-
const
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
addSelectedElement(board, element);
|
|
1459
|
-
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
1306
|
+
const drawSolidTriangle = (source, target, options) => {
|
|
1307
|
+
const endPoint = target;
|
|
1308
|
+
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 30);
|
|
1309
|
+
return drawLinearPath([pointLeft, endPoint, pointRight], { ...options, fill: options.stroke }, true);
|
|
1460
1310
|
};
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1311
|
+
const drawOpenTriangle = (element, source, target, options) => {
|
|
1312
|
+
const unitVector = getUnitVectorByPointAndPoint(source, target);
|
|
1313
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1314
|
+
const endPoint = [target[0] + (strokeWidth * unitVector[0]) / 2, target[1] + (strokeWidth * unitVector[1]) / 2];
|
|
1315
|
+
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 40);
|
|
1316
|
+
return drawLinearPath([pointLeft, endPoint, pointRight], options);
|
|
1317
|
+
};
|
|
1318
|
+
const drawOneSideArrow = (source, target, side, options) => {
|
|
1319
|
+
const { pointLeft, pointRight } = arrowPoints(source, target, 40);
|
|
1320
|
+
return drawLinearPath([side === 'up' ? pointRight : pointLeft, target], options);
|
|
1321
|
+
};
|
|
1322
|
+
const drawSingleSlash = (source, target, isSource, options) => {
|
|
1323
|
+
const length = distanceBetweenPointAndPoint(...source, ...target);
|
|
1324
|
+
const middlePoint = getExtendPoint(target, source, length / 2);
|
|
1325
|
+
const angle = isSource ? 120 : 60;
|
|
1326
|
+
const start = rotate(...source, ...middlePoint, (angle * Math.PI) / 180);
|
|
1327
|
+
const end = rotate(...target, ...middlePoint, (angle * Math.PI) / 180);
|
|
1328
|
+
return drawLinearPath([start, end], options);
|
|
1329
|
+
};
|
|
1330
|
+
const drawHollowTriangleArrow = (source, target, options) => {
|
|
1331
|
+
const { pointLeft, pointRight } = arrowPoints(source, target, 30);
|
|
1332
|
+
return drawLinearPath([pointLeft, pointRight, target], { ...options, fill: 'white' }, true);
|
|
1333
|
+
};
|
|
1334
|
+
|
|
1335
|
+
class ArrowLineShapeGenerator extends Generator {
|
|
1336
|
+
canDraw(element) {
|
|
1463
1337
|
return true;
|
|
1464
1338
|
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
return isGeometryIncludeText(element);
|
|
1470
|
-
}
|
|
1471
|
-
if (PlaitDrawElement.isArrowLine(element)) {
|
|
1472
|
-
const editors = getTextEditorsByElement(element);
|
|
1473
|
-
return editors.length > 0;
|
|
1474
|
-
}
|
|
1475
|
-
if (PlaitDrawElement.isElementByTable(element)) {
|
|
1476
|
-
return element.cells.some(cell => isCellIncludeText(cell));
|
|
1339
|
+
draw(element) {
|
|
1340
|
+
let lineG;
|
|
1341
|
+
lineG = drawArrowLine(this.board, element);
|
|
1342
|
+
return lineG;
|
|
1477
1343
|
}
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
const
|
|
1481
|
-
return
|
|
1482
|
-
|
|
1483
|
-
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
const createArrowLineElement = (shape, points, source, target, texts, options) => {
|
|
1347
|
+
return {
|
|
1348
|
+
id: idCreator(),
|
|
1349
|
+
type: 'arrow-line',
|
|
1350
|
+
shape,
|
|
1351
|
+
source,
|
|
1352
|
+
texts: texts ? texts : [],
|
|
1353
|
+
target,
|
|
1354
|
+
opacity: 1,
|
|
1355
|
+
points,
|
|
1356
|
+
...options
|
|
1357
|
+
};
|
|
1484
1358
|
};
|
|
1485
|
-
const
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
return
|
|
1359
|
+
const getArrowLinePoints = (board, element) => {
|
|
1360
|
+
switch (element.shape) {
|
|
1361
|
+
case ArrowLineShape.elbow: {
|
|
1362
|
+
return getElbowPoints(board, element);
|
|
1489
1363
|
}
|
|
1490
|
-
|
|
1491
|
-
return
|
|
1364
|
+
case ArrowLineShape.curve: {
|
|
1365
|
+
return getCurvePoints(board, element);
|
|
1492
1366
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1367
|
+
default: {
|
|
1368
|
+
const points = PlaitArrowLine.getPoints(board, element);
|
|
1369
|
+
const handleRefPair = getArrowLineHandleRefPair(board, element);
|
|
1370
|
+
points[0] = handleRefPair.source.point;
|
|
1371
|
+
points[points.length - 1] = handleRefPair.target.point;
|
|
1372
|
+
return points;
|
|
1495
1373
|
}
|
|
1496
|
-
return true;
|
|
1497
1374
|
}
|
|
1498
|
-
return false;
|
|
1499
|
-
};
|
|
1500
|
-
const isClosedCustomGeometry = (board, value) => {
|
|
1501
|
-
return PlaitDrawElement.isCustomGeometryElement(board, value) && isClosedPoints(value.points);
|
|
1502
1375
|
};
|
|
1503
|
-
const
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
const
|
|
1507
|
-
|
|
1508
|
-
|
|
1376
|
+
const getCurvePoints = (board, element) => {
|
|
1377
|
+
if (element.points.length === 2) {
|
|
1378
|
+
const handleRefPair = getArrowLineHandleRefPair(board, element);
|
|
1379
|
+
const { source, target } = handleRefPair;
|
|
1380
|
+
const sourceBoundElement = handleRefPair.source.boundElement;
|
|
1381
|
+
const targetBoundElement = handleRefPair.target.boundElement;
|
|
1382
|
+
let curvePoints = [source.point];
|
|
1383
|
+
const sumDistance = distanceBetweenPointAndPoint(...source.point, ...target.point);
|
|
1384
|
+
const offset = 12 + sumDistance / 3;
|
|
1385
|
+
if (sourceBoundElement) {
|
|
1386
|
+
curvePoints.push(getPointByVectorComponent(source.point, source.vector, offset));
|
|
1509
1387
|
}
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
};
|
|
1513
|
-
const getSnappingRef = (board, hitElement, point) => {
|
|
1514
|
-
const rotatedPoint = rotateAntiPointsByElement(point, hitElement) || point;
|
|
1515
|
-
const connectorPoint = getHitConnectorPoint(rotatedPoint, hitElement);
|
|
1516
|
-
const edgePoint = getNearestPoint(hitElement, rotatedPoint);
|
|
1517
|
-
const isHitEdge = isHitEdgeOfShape(board, hitElement, rotatedPoint, LINE_SNAPPING_BUFFER);
|
|
1518
|
-
return { isHitEdge, isHitConnector: !!connectorPoint, connectorPoint, edgePoint };
|
|
1519
|
-
};
|
|
1520
|
-
const getHitShape = (board, point, offset = LINE_HIT_GEOMETRY_BUFFER) => {
|
|
1521
|
-
let hitShape = null;
|
|
1522
|
-
traverseDrawShapes(board, (element) => {
|
|
1523
|
-
if (hitShape === null && isInsideOfShape(board, element, rotateAntiPointsByElement(point, element) || point, offset * 2)) {
|
|
1524
|
-
hitShape = element;
|
|
1388
|
+
if (targetBoundElement) {
|
|
1389
|
+
curvePoints.push(getPointByVectorComponent(target.point, target.vector, offset));
|
|
1525
1390
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
const
|
|
1530
|
-
|
|
1531
|
-
if (!PlaitBoard.isBoard(node) && PlaitDrawElement.isShapeElement(node)) {
|
|
1532
|
-
callback(node);
|
|
1391
|
+
const isSingleBound = (sourceBoundElement && !targetBoundElement) || (!sourceBoundElement && targetBoundElement);
|
|
1392
|
+
if (isSingleBound) {
|
|
1393
|
+
curvePoints.push(target.point);
|
|
1394
|
+
const points = Q2C(curvePoints);
|
|
1395
|
+
return pointsOnBezierCurves(points);
|
|
1533
1396
|
}
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
const g = createG();
|
|
1541
|
-
const rectangle = RectangleClient.getRectangleByPoints(element.points);
|
|
1542
|
-
const activeRectangle = RectangleClient.inflate(rectangle, SNAPPING_STROKE_WIDTH);
|
|
1543
|
-
const shape = getElementShape(element);
|
|
1544
|
-
let drawOptions;
|
|
1545
|
-
if (PlaitDrawElement.isElementByTable(element)) {
|
|
1546
|
-
drawOptions = { element };
|
|
1547
|
-
}
|
|
1548
|
-
const strokeG = drawShape(board, activeRectangle, shape, {
|
|
1549
|
-
stroke: SELECTION_BORDER_COLOR,
|
|
1550
|
-
strokeWidth: SNAPPING_STROKE_WIDTH
|
|
1551
|
-
}, drawOptions);
|
|
1552
|
-
g.appendChild(strokeG);
|
|
1553
|
-
if (roughOptions.hasMask) {
|
|
1554
|
-
const maskG = drawShape(board, activeRectangle, shape, {
|
|
1555
|
-
stroke: SELECTION_BORDER_COLOR,
|
|
1556
|
-
strokeWidth: 0,
|
|
1557
|
-
fill: isClosedDrawElement(element) ? SELECTION_FILL_COLOR : DefaultDrawStyle.fill,
|
|
1558
|
-
fillStyle: 'solid'
|
|
1559
|
-
}, drawOptions);
|
|
1560
|
-
g.appendChild(maskG);
|
|
1561
|
-
}
|
|
1562
|
-
if (roughOptions.hasConnector) {
|
|
1563
|
-
const connectorPoints = getEngine(shape).getConnectorPoints(rectangle);
|
|
1564
|
-
connectorPoints.forEach(point => {
|
|
1565
|
-
const circleG = drawCircle(PlaitBoard.getRoughSVG(board), point, 8, {
|
|
1566
|
-
stroke: SELECTION_BORDER_COLOR,
|
|
1567
|
-
strokeWidth: ACTIVE_STROKE_WIDTH,
|
|
1568
|
-
fill: '#FFF',
|
|
1569
|
-
fillStyle: 'solid'
|
|
1570
|
-
});
|
|
1571
|
-
g.appendChild(circleG);
|
|
1572
|
-
});
|
|
1573
|
-
}
|
|
1574
|
-
return g;
|
|
1575
|
-
};
|
|
1576
|
-
const getTextKey = (element, text) => {
|
|
1577
|
-
if (element && isMultipleTextGeometry(element)) {
|
|
1578
|
-
return `${element.id}-${text.id}`;
|
|
1397
|
+
if (!sourceBoundElement && !targetBoundElement) {
|
|
1398
|
+
curvePoints.push(getPointByVectorComponent(source.point, source.vector, offset));
|
|
1399
|
+
curvePoints.push(getPointByVectorComponent(target.point, target.vector, offset));
|
|
1400
|
+
}
|
|
1401
|
+
curvePoints.push(target.point);
|
|
1402
|
+
return pointsOnBezierCurves(curvePoints);
|
|
1579
1403
|
}
|
|
1580
1404
|
else {
|
|
1581
|
-
|
|
1405
|
+
let dataPoints = PlaitArrowLine.getPoints(board, element);
|
|
1406
|
+
dataPoints = removeDuplicatePoints(dataPoints);
|
|
1407
|
+
const points = catmullRomFitting(dataPoints);
|
|
1408
|
+
return pointsOnBezierCurves(points);
|
|
1582
1409
|
}
|
|
1583
1410
|
};
|
|
1584
|
-
const
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1411
|
+
const drawArrowLine = (board, element) => {
|
|
1412
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1413
|
+
const strokeColor = getStrokeColorByElement(board, element);
|
|
1414
|
+
const strokeStyle = getStrokeStyleByElement(board, element);
|
|
1415
|
+
const strokeLineDash = getStrokeLineDash(strokeStyle, strokeWidth);
|
|
1416
|
+
const options = { stroke: strokeColor, strokeWidth, strokeLineDash };
|
|
1417
|
+
const lineG = createG();
|
|
1418
|
+
let points = getArrowLinePoints(board, element);
|
|
1419
|
+
let line;
|
|
1420
|
+
if (element.shape === ArrowLineShape.curve) {
|
|
1421
|
+
line = PlaitBoard.getRoughSVG(board).curve(points, options);
|
|
1588
1422
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1423
|
+
else {
|
|
1424
|
+
line = drawLinearPath(points, options);
|
|
1591
1425
|
}
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1426
|
+
const id = idCreator();
|
|
1427
|
+
line.setAttribute('mask', `url(#${id})`);
|
|
1428
|
+
if (element.strokeStyle === StrokeStyle.dotted) {
|
|
1429
|
+
setStrokeLinecap(line, 'round');
|
|
1595
1430
|
}
|
|
1596
|
-
|
|
1431
|
+
lineG.appendChild(line);
|
|
1432
|
+
const { mask, maskTargetFillRect } = drawArrowLineMask(board, element, id);
|
|
1433
|
+
lineG.appendChild(mask);
|
|
1434
|
+
line.appendChild(maskTargetFillRect);
|
|
1435
|
+
const arrow = drawArrowLineArrow(element, points, { stroke: strokeColor, strokeWidth });
|
|
1436
|
+
arrow && lineG.appendChild(arrow);
|
|
1437
|
+
return lineG;
|
|
1597
1438
|
};
|
|
1598
|
-
const
|
|
1599
|
-
|
|
1600
|
-
const
|
|
1601
|
-
|
|
1439
|
+
const getHitConnection = (board, point, hitElement) => {
|
|
1440
|
+
let rectangle = RectangleClient.getRectangleByPoints(hitElement.points);
|
|
1441
|
+
const ref = getSnappingRef(board, hitElement, point);
|
|
1442
|
+
const connectionPoint = ref.connectorPoint || ref.edgePoint;
|
|
1443
|
+
return [(connectionPoint[0] - rectangle.x) / rectangle.width, (connectionPoint[1] - rectangle.y) / rectangle.height];
|
|
1602
1444
|
};
|
|
1603
|
-
|
|
1604
|
-
const
|
|
1605
|
-
const
|
|
1606
|
-
const
|
|
1607
|
-
return
|
|
1445
|
+
const getHitConnectorPoint = (point, hitElement) => {
|
|
1446
|
+
const rectangle = RectangleClient.getRectangleByPoints(hitElement.points);
|
|
1447
|
+
const shape = getElementShape(hitElement);
|
|
1448
|
+
const connectorPoints = getEngine(shape).getConnectorPoints(rectangle);
|
|
1449
|
+
return connectorPoints.find((connectorPoint) => {
|
|
1450
|
+
return distanceBetweenPointAndPoint(...connectorPoint, ...point) <= LINE_SNAPPING_CONNECTOR_BUFFER;
|
|
1451
|
+
});
|
|
1608
1452
|
};
|
|
1609
|
-
const
|
|
1610
|
-
const
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1453
|
+
const getArrowLineTextRectangle = (board, element, index) => {
|
|
1454
|
+
const text = element.texts[index];
|
|
1455
|
+
const elbowPoints = getArrowLinePoints(board, element);
|
|
1456
|
+
const point = getPointOnPolyline(elbowPoints, text.position);
|
|
1457
|
+
return {
|
|
1458
|
+
x: point[0] - text.width / 2,
|
|
1459
|
+
y: point[1] - text.height / 2,
|
|
1460
|
+
width: text.width,
|
|
1461
|
+
height: text.height
|
|
1462
|
+
};
|
|
1615
1463
|
};
|
|
1616
|
-
const
|
|
1617
|
-
return
|
|
1464
|
+
const getArrowLines = (board) => {
|
|
1465
|
+
return findElements(board, {
|
|
1466
|
+
match: (element) => PlaitDrawElement.isArrowLine(element),
|
|
1467
|
+
recursion: (element) => PlaitDrawElement.isDrawElement(element)
|
|
1468
|
+
});
|
|
1618
1469
|
};
|
|
1619
|
-
|
|
1620
|
-
const
|
|
1621
|
-
const
|
|
1622
|
-
const
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1470
|
+
// quadratic Bezier to cubic Bezier
|
|
1471
|
+
const Q2C = (points) => {
|
|
1472
|
+
const result = [];
|
|
1473
|
+
const numSegments = points.length / 3;
|
|
1474
|
+
for (let i = 0; i < numSegments; i++) {
|
|
1475
|
+
const start = points[i];
|
|
1476
|
+
const qControl = points[i + 1];
|
|
1477
|
+
const end = points[i + 2];
|
|
1478
|
+
const startDistance = distanceBetweenPointAndPoint(...start, ...qControl);
|
|
1479
|
+
const endDistance = distanceBetweenPointAndPoint(...end, ...qControl);
|
|
1480
|
+
const cControl1 = getExtendPoint(start, qControl, (startDistance * 2) / 3);
|
|
1481
|
+
const cControl2 = getExtendPoint(end, qControl, (endDistance * 2) / 3);
|
|
1482
|
+
result.push(start, cControl1, cControl2, end);
|
|
1629
1483
|
}
|
|
1630
|
-
return
|
|
1484
|
+
return result;
|
|
1631
1485
|
};
|
|
1632
|
-
|
|
1633
|
-
const
|
|
1634
|
-
|
|
1635
|
-
|
|
1486
|
+
const handleArrowLineCreating = (board, lineShape, sourcePoint, movingPoint, sourceElement, lineShapeG) => {
|
|
1487
|
+
const hitElement = getSnappingShape(board, movingPoint);
|
|
1488
|
+
const targetConnection = hitElement ? getHitConnection(board, movingPoint, hitElement) : undefined;
|
|
1489
|
+
const sourceConnection = sourceElement ? getHitConnection(board, sourcePoint, sourceElement) : undefined;
|
|
1490
|
+
const targetBoundId = hitElement ? hitElement.id : undefined;
|
|
1491
|
+
const lineGenerator = new ArrowLineShapeGenerator(board);
|
|
1492
|
+
const memorizedLatest = getLineMemorizedLatest();
|
|
1493
|
+
let sourceMarker, targetMarker;
|
|
1494
|
+
sourceMarker = memorizedLatest.source;
|
|
1495
|
+
targetMarker = memorizedLatest.target;
|
|
1496
|
+
sourceMarker && delete memorizedLatest.source;
|
|
1497
|
+
targetMarker && delete memorizedLatest.target;
|
|
1498
|
+
const temporaryLineElement = createArrowLineElement(lineShape, [sourcePoint, movingPoint], { marker: sourceMarker || ArrowLineMarkerType.none, connection: sourceConnection, boundId: sourceElement?.id }, { marker: targetMarker || ArrowLineMarkerType.arrow, connection: targetConnection, boundId: targetBoundId }, [], {
|
|
1499
|
+
strokeWidth: DefaultLineStyle.strokeWidth,
|
|
1500
|
+
...memorizedLatest
|
|
1501
|
+
});
|
|
1502
|
+
const linePoints = getArrowLinePoints(board, temporaryLineElement);
|
|
1503
|
+
const otherPoint = linePoints[0];
|
|
1504
|
+
temporaryLineElement.points[1] = alignPoints(otherPoint, movingPoint);
|
|
1505
|
+
lineGenerator.processDrawing(temporaryLineElement, lineShapeG);
|
|
1506
|
+
PlaitBoard.getElementTopHost(board).append(lineShapeG);
|
|
1507
|
+
return temporaryLineElement;
|
|
1508
|
+
};
|
|
1509
|
+
function drawArrowLineMask(board, element, id) {
|
|
1510
|
+
const mask = createMask();
|
|
1511
|
+
mask.setAttribute('id', id);
|
|
1512
|
+
const points = getArrowLinePoints(board, element);
|
|
1513
|
+
let rectangle = RectangleClient.getRectangleByPoints(points);
|
|
1514
|
+
rectangle = RectangleClient.getOutlineRectangle(rectangle, -30);
|
|
1515
|
+
const maskFillRect = createRect(rectangle, {
|
|
1516
|
+
fill: 'white'
|
|
1517
|
+
});
|
|
1518
|
+
mask.appendChild(maskFillRect);
|
|
1519
|
+
const texts = element.texts;
|
|
1520
|
+
texts.forEach((text, index) => {
|
|
1521
|
+
let textRectangle = getArrowLineTextRectangle(board, element, index);
|
|
1522
|
+
textRectangle = RectangleClient.inflate(textRectangle, LINE_TEXT_SPACE * 2);
|
|
1523
|
+
const rect = createRect(textRectangle, {
|
|
1524
|
+
fill: 'black'
|
|
1525
|
+
});
|
|
1526
|
+
mask.appendChild(rect);
|
|
1527
|
+
});
|
|
1528
|
+
// open line
|
|
1529
|
+
const maskTargetFillRect = createRect(rectangle);
|
|
1530
|
+
maskTargetFillRect.setAttribute('opacity', '0');
|
|
1531
|
+
maskTargetFillRect.setAttribute('fill', 'none');
|
|
1532
|
+
return { mask, maskTargetFillRect };
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
const getHitArrowLineTextIndex = (board, element, point) => {
|
|
1536
|
+
const texts = element.texts;
|
|
1537
|
+
if (!texts.length)
|
|
1538
|
+
return -1;
|
|
1539
|
+
const points = getArrowLinePoints(board, element);
|
|
1540
|
+
return texts.findIndex(text => {
|
|
1541
|
+
const center = getPointOnPolyline(points, text.position);
|
|
1542
|
+
const rectangle = {
|
|
1543
|
+
x: center[0] - text.width / 2,
|
|
1544
|
+
y: center[1] - text.height / 2,
|
|
1545
|
+
width: text.width,
|
|
1546
|
+
height: text.height
|
|
1547
|
+
};
|
|
1548
|
+
return RectangleClient.isHit(rectangle, RectangleClient.getRectangleByPoints([point, point]));
|
|
1549
|
+
});
|
|
1550
|
+
};
|
|
1551
|
+
|
|
1552
|
+
const isMultipleTextShape = (shape) => {
|
|
1553
|
+
return GEOMETRY_WITH_MULTIPLE_TEXT.includes(shape);
|
|
1554
|
+
};
|
|
1555
|
+
const isMultipleTextGeometry = (geometry) => {
|
|
1556
|
+
return PlaitDrawElement.isGeometry(geometry) && isMultipleTextShape(geometry.shape);
|
|
1557
|
+
};
|
|
1558
|
+
const getMultipleTextGeometryTextKeys = (shape) => {
|
|
1559
|
+
return MultipleTextGeometryTextKeys[shape];
|
|
1560
|
+
};
|
|
1561
|
+
const createMultipleTextGeometryElement = (shape, points, options = {}) => {
|
|
1562
|
+
const id = idCreator();
|
|
1563
|
+
const drawShapeTexts = buildDefaultTextsByShape(shape);
|
|
1564
|
+
return {
|
|
1565
|
+
id,
|
|
1566
|
+
type: 'geometry',
|
|
1567
|
+
shape,
|
|
1568
|
+
angle: 0,
|
|
1569
|
+
opacity: 1,
|
|
1570
|
+
texts: drawShapeTexts,
|
|
1571
|
+
points,
|
|
1572
|
+
...options
|
|
1636
1573
|
};
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
const
|
|
1640
|
-
const
|
|
1641
|
-
const
|
|
1642
|
-
const
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1574
|
+
};
|
|
1575
|
+
const buildDefaultTextsByShape = (shape) => {
|
|
1576
|
+
const memorizedLatest = getMemorizedLatestByPointer(shape);
|
|
1577
|
+
const textProperties = { ...memorizedLatest.textProperties };
|
|
1578
|
+
const alignment = textProperties?.align;
|
|
1579
|
+
const textHeight = textProperties?.textHeight || DefaultTextProperty.height;
|
|
1580
|
+
delete textProperties?.align;
|
|
1581
|
+
delete textProperties?.textHeight;
|
|
1582
|
+
const defaultTexts = getDefaultGeometryProperty(shape)?.texts || [];
|
|
1583
|
+
const textKeys = getMultipleTextGeometryTextKeys(shape);
|
|
1584
|
+
return (textKeys || []).map((textKey) => {
|
|
1585
|
+
const text = defaultTexts?.find((item) => item?.key === textKey);
|
|
1586
|
+
return {
|
|
1587
|
+
id: textKey,
|
|
1588
|
+
text: buildText(text?.text || '', alignment || text?.align || Alignment.center, textProperties),
|
|
1589
|
+
textHeight: textHeight
|
|
1590
|
+
};
|
|
1591
|
+
});
|
|
1592
|
+
};
|
|
1593
|
+
const getHitMultipleGeometryText = (element, point) => {
|
|
1594
|
+
const engine = getEngine(element.shape);
|
|
1595
|
+
const rectangle = RectangleClient.getRectangleByPoints([point, point]);
|
|
1596
|
+
let hitText;
|
|
1597
|
+
if (engine.getTextRectangle) {
|
|
1598
|
+
hitText = element.texts.find(text => {
|
|
1599
|
+
const textRectangle = engine.getTextRectangle(element, { id: text.id });
|
|
1600
|
+
return RectangleClient.isHit(rectangle, textRectangle);
|
|
1601
|
+
});
|
|
1646
1602
|
}
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1603
|
+
return hitText;
|
|
1604
|
+
};
|
|
1605
|
+
|
|
1606
|
+
class VectorLineShapeGenerator extends Generator {
|
|
1607
|
+
canDraw(element) {
|
|
1608
|
+
return true;
|
|
1609
|
+
}
|
|
1610
|
+
draw(element) {
|
|
1611
|
+
let lineG;
|
|
1612
|
+
lineG = drawVectorLine(this.board, element);
|
|
1613
|
+
return lineG;
|
|
1651
1614
|
}
|
|
1652
|
-
return referencePoint;
|
|
1653
1615
|
}
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
let pointY = startKeyPoint[1] + offsetY;
|
|
1660
|
-
if (resizedPreviousAndNextPoint.previous && Math.abs(resizedPreviousAndNextPoint.previous[1] - pointY) < LINE_ALIGN_TOLERANCE) {
|
|
1661
|
-
pointY = resizedPreviousAndNextPoint.previous[1];
|
|
1616
|
+
|
|
1617
|
+
const getVectorLinePoints = (board, element) => {
|
|
1618
|
+
switch (element.shape) {
|
|
1619
|
+
case VectorLineShape.straight: {
|
|
1620
|
+
return element.points;
|
|
1662
1621
|
}
|
|
1663
|
-
|
|
1664
|
-
|
|
1622
|
+
case VectorLineShape.curve: {
|
|
1623
|
+
if (element.points.length === 2) {
|
|
1624
|
+
return pointsOnBezierCurves(element.points);
|
|
1625
|
+
}
|
|
1626
|
+
else {
|
|
1627
|
+
let dataPoints = element.points;
|
|
1628
|
+
const points = catmullRomFitting(dataPoints);
|
|
1629
|
+
return pointsOnBezierCurves(points);
|
|
1630
|
+
}
|
|
1665
1631
|
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1632
|
+
default:
|
|
1633
|
+
return null;
|
|
1668
1634
|
}
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1635
|
+
};
|
|
1636
|
+
const createVectorLineElement = (shape, points, options) => {
|
|
1637
|
+
return {
|
|
1638
|
+
id: idCreator(),
|
|
1639
|
+
type: 'vector-line',
|
|
1640
|
+
shape,
|
|
1641
|
+
opacity: 1,
|
|
1642
|
+
points,
|
|
1643
|
+
...options
|
|
1644
|
+
};
|
|
1645
|
+
};
|
|
1646
|
+
const vectorLineCreating = (board, lineShape, points, movingPoint, lineShapeG) => {
|
|
1647
|
+
const lineGenerator = new VectorLineShapeGenerator(board);
|
|
1648
|
+
const memorizedLatest = getLineMemorizedLatest();
|
|
1649
|
+
const temporaryLineElement = createVectorLineElement(lineShape, [...points, movingPoint], {
|
|
1650
|
+
strokeWidth: DefaultLineStyle.strokeWidth,
|
|
1651
|
+
...memorizedLatest
|
|
1652
|
+
});
|
|
1653
|
+
const otherPoint = points[points.length - 1];
|
|
1654
|
+
temporaryLineElement.points[temporaryLineElement.points.length - 1] = alignPoints(otherPoint, movingPoint);
|
|
1655
|
+
lineGenerator.processDrawing(temporaryLineElement, lineShapeG);
|
|
1656
|
+
PlaitBoard.getElementTopHost(board).append(lineShapeG);
|
|
1657
|
+
return temporaryLineElement;
|
|
1658
|
+
};
|
|
1659
|
+
const drawVectorLine = (board, element) => {
|
|
1660
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1661
|
+
const strokeColor = getStrokeColorByElement(board, element);
|
|
1662
|
+
const strokeStyle = getStrokeStyleByElement(board, element);
|
|
1663
|
+
const strokeLineDash = getStrokeLineDash(strokeStyle, strokeWidth);
|
|
1664
|
+
const fill = getFillByElement(board, element);
|
|
1665
|
+
const options = { stroke: strokeColor, strokeWidth, strokeLineDash, fill };
|
|
1666
|
+
const lineG = createG();
|
|
1667
|
+
let points = getVectorLinePoints(board, element);
|
|
1668
|
+
const line = drawLinearPath(points, options);
|
|
1669
|
+
const id = idCreator();
|
|
1670
|
+
line.setAttribute('mask', `url(#${id})`);
|
|
1671
|
+
if (element.strokeStyle === StrokeStyle.dotted) {
|
|
1672
|
+
setStrokeLinecap(line, 'round');
|
|
1680
1673
|
}
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
const
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
index,
|
|
1691
|
-
deleteCount
|
|
1692
|
-
};
|
|
1674
|
+
lineG.appendChild(line);
|
|
1675
|
+
return lineG;
|
|
1676
|
+
};
|
|
1677
|
+
|
|
1678
|
+
const getCenterPointsOnPolygon$1 = (points) => {
|
|
1679
|
+
const centerPoints = [];
|
|
1680
|
+
for (let i = 0; i < points.length; i++) {
|
|
1681
|
+
let j = i == points.length - 1 ? 0 : i + 1;
|
|
1682
|
+
centerPoints.push([(points[i][0] + points[j][0]) / 2, (points[i][1] + points[j][1]) / 2]);
|
|
1693
1683
|
}
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
}
|
|
1704
|
-
if (startIndex > -1 && endIndex === -1) {
|
|
1705
|
-
const isReplace = startIndex < midDataPoints.length - 1 &&
|
|
1706
|
-
Point.isAlign([midDataPoints[startIndex], midDataPoints[startIndex + 1], startKeyPoint, endKeyPoint]);
|
|
1707
|
-
if (isReplace) {
|
|
1708
|
-
return {
|
|
1709
|
-
index: startIndex,
|
|
1710
|
-
deleteCount: 2
|
|
1711
|
-
};
|
|
1712
|
-
}
|
|
1713
|
-
return {
|
|
1714
|
-
index: startIndex,
|
|
1715
|
-
deleteCount: 1
|
|
1716
|
-
};
|
|
1717
|
-
}
|
|
1718
|
-
if (startIndex === -1 && endIndex > -1) {
|
|
1719
|
-
const isReplace = endIndex > 0 && Point.isAlign([midDataPoints[endIndex], midDataPoints[endIndex - 1], startKeyPoint, endKeyPoint]);
|
|
1720
|
-
if (isReplace) {
|
|
1721
|
-
return {
|
|
1722
|
-
index: endIndex - 1,
|
|
1723
|
-
deleteCount: 2
|
|
1724
|
-
};
|
|
1725
|
-
}
|
|
1726
|
-
return {
|
|
1727
|
-
index: endIndex,
|
|
1728
|
-
deleteCount: 1
|
|
1729
|
-
};
|
|
1730
|
-
}
|
|
1684
|
+
return centerPoints;
|
|
1685
|
+
};
|
|
1686
|
+
const getCrossingPointBetweenPointAndPolygon = (corners, point) => {
|
|
1687
|
+
const result = [];
|
|
1688
|
+
for (let index = 1; index <= corners.length; index++) {
|
|
1689
|
+
let start = corners[index - 1];
|
|
1690
|
+
let end = index === corners.length ? corners[0] : corners[index];
|
|
1691
|
+
const crossingPoint = getCrossingPointsBetweenPointAndSegment(point, start, end);
|
|
1692
|
+
result.push(...crossingPoint);
|
|
1731
1693
|
}
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
}
|
|
1741
|
-
if (Point.isAlign([currentPoint, nextPoint, startKeyPoint])) {
|
|
1742
|
-
index = Math.min(i + 1, midDataPoints.length - 1);
|
|
1743
|
-
deleteCount = 1;
|
|
1744
|
-
break;
|
|
1745
|
-
}
|
|
1746
|
-
if (Point.isAlign([currentPoint, nextPoint, endKeyPoint])) {
|
|
1747
|
-
index = Math.max(i - 1, 0);
|
|
1748
|
-
deleteCount = 1;
|
|
1749
|
-
break;
|
|
1750
|
-
}
|
|
1694
|
+
return result;
|
|
1695
|
+
};
|
|
1696
|
+
const getPolygonEdgeByConnectionPoint = (corners, point) => {
|
|
1697
|
+
for (let index = 1; index <= corners.length; index++) {
|
|
1698
|
+
let start = corners[index - 1];
|
|
1699
|
+
let end = index === corners.length ? corners[0] : corners[index];
|
|
1700
|
+
if (isPointOnSegment(point, start, end)) {
|
|
1701
|
+
return [start, end];
|
|
1751
1702
|
}
|
|
1752
1703
|
}
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1704
|
+
return null;
|
|
1705
|
+
};
|
|
1706
|
+
|
|
1707
|
+
function generateCloudPath(rectangle) {
|
|
1708
|
+
const divisionWidth = rectangle.width / 7;
|
|
1709
|
+
const divisionHeight = rectangle.height / 3.2;
|
|
1710
|
+
const xRadius = divisionWidth / 8.5;
|
|
1711
|
+
const yRadius = divisionHeight / 20;
|
|
1712
|
+
const startPoint = [rectangle.x + divisionWidth, rectangle.y + divisionHeight];
|
|
1713
|
+
const arcCommands = [
|
|
1714
|
+
{
|
|
1715
|
+
rx: xRadius,
|
|
1716
|
+
ry: yRadius * 1.2,
|
|
1717
|
+
xAxisRotation: 0,
|
|
1718
|
+
largeArcFlag: 1,
|
|
1719
|
+
sweepFlag: 1,
|
|
1720
|
+
endX: rectangle.x + divisionWidth * 2,
|
|
1721
|
+
endY: rectangle.y + divisionHeight / 2
|
|
1722
|
+
},
|
|
1723
|
+
{
|
|
1724
|
+
rx: xRadius,
|
|
1725
|
+
ry: yRadius,
|
|
1726
|
+
xAxisRotation: 0,
|
|
1727
|
+
largeArcFlag: 1,
|
|
1728
|
+
sweepFlag: 1,
|
|
1729
|
+
endX: rectangle.x + divisionWidth * 4.2,
|
|
1730
|
+
endY: rectangle.y + divisionHeight / 2.2
|
|
1731
|
+
},
|
|
1732
|
+
{
|
|
1733
|
+
rx: xRadius,
|
|
1734
|
+
ry: yRadius,
|
|
1735
|
+
xAxisRotation: 0,
|
|
1736
|
+
largeArcFlag: 1,
|
|
1737
|
+
sweepFlag: 1,
|
|
1738
|
+
endX: rectangle.x + divisionWidth * 5.8,
|
|
1739
|
+
endY: rectangle.y + divisionHeight
|
|
1740
|
+
},
|
|
1741
|
+
{
|
|
1742
|
+
rx: xRadius,
|
|
1743
|
+
ry: yRadius * 1.3,
|
|
1744
|
+
xAxisRotation: 0,
|
|
1745
|
+
largeArcFlag: 1,
|
|
1746
|
+
sweepFlag: 1,
|
|
1747
|
+
endX: rectangle.x + divisionWidth * 6,
|
|
1748
|
+
endY: rectangle.y + divisionHeight * 2.2
|
|
1749
|
+
},
|
|
1750
|
+
{
|
|
1751
|
+
rx: xRadius,
|
|
1752
|
+
ry: yRadius * 1.2,
|
|
1753
|
+
xAxisRotation: 0,
|
|
1754
|
+
largeArcFlag: 1,
|
|
1755
|
+
sweepFlag: 1,
|
|
1756
|
+
endX: rectangle.x + divisionWidth * 5,
|
|
1757
|
+
endY: rectangle.y + divisionHeight * 2.8
|
|
1758
|
+
},
|
|
1759
|
+
{
|
|
1760
|
+
rx: xRadius,
|
|
1761
|
+
ry: yRadius / 1.2,
|
|
1762
|
+
xAxisRotation: 0,
|
|
1763
|
+
largeArcFlag: 1,
|
|
1764
|
+
sweepFlag: 1,
|
|
1765
|
+
endX: rectangle.x + divisionWidth * 2.8,
|
|
1766
|
+
endY: rectangle.y + divisionHeight * 2.8
|
|
1767
|
+
},
|
|
1768
|
+
{
|
|
1769
|
+
rx: xRadius,
|
|
1770
|
+
ry: yRadius,
|
|
1771
|
+
xAxisRotation: 0,
|
|
1772
|
+
largeArcFlag: 1,
|
|
1773
|
+
sweepFlag: 1,
|
|
1774
|
+
endX: rectangle.x + divisionWidth,
|
|
1775
|
+
endY: rectangle.y + divisionHeight * 2.2
|
|
1776
|
+
},
|
|
1777
|
+
{
|
|
1778
|
+
rx: xRadius,
|
|
1779
|
+
ry: yRadius * 1.42,
|
|
1780
|
+
xAxisRotation: 0,
|
|
1781
|
+
largeArcFlag: 1,
|
|
1782
|
+
sweepFlag: 1,
|
|
1783
|
+
endX: rectangle.x + divisionWidth,
|
|
1784
|
+
endY: rectangle.y + divisionHeight
|
|
1780
1785
|
}
|
|
1781
|
-
|
|
1782
|
-
return {
|
|
1783
|
-
index,
|
|
1784
|
-
deleteCount
|
|
1785
|
-
};
|
|
1786
|
-
}
|
|
1787
|
-
function getMirrorDataPoints(board, nextDataPoints, nextKeyPoints, params) {
|
|
1788
|
-
for (let index = 1; index < nextDataPoints.length - 2; index++) {
|
|
1789
|
-
adjustByCustomPointStartIndex(board, index, nextDataPoints, nextKeyPoints, params);
|
|
1790
|
-
}
|
|
1791
|
-
return nextDataPoints;
|
|
1786
|
+
];
|
|
1787
|
+
return { startPoint, arcCommands };
|
|
1792
1788
|
}
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
const
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
const
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
nextDataPoints.splice(customPointStartIndex + 1, 1, mirrorSegment[1]);
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
else {
|
|
1828
|
-
const isHorizontal = Point.isHorizontal(startPoint, endPoint);
|
|
1829
|
-
const adjustIndex = isHorizontal ? 0 : 1;
|
|
1830
|
-
if (isAdjustStart) {
|
|
1831
|
-
const newStartPoint = [startPoint[0], startPoint[1]];
|
|
1832
|
-
newStartPoint[adjustIndex] = beforePoint[adjustIndex];
|
|
1833
|
-
nextDataPoints.splice(customPointStartIndex, 1, newStartPoint);
|
|
1834
|
-
}
|
|
1835
|
-
if (isAdjustEnd) {
|
|
1836
|
-
const newEndPoint = [endPoint[0], endPoint[1]];
|
|
1837
|
-
newEndPoint[adjustIndex] = afterPoint[adjustIndex];
|
|
1838
|
-
nextDataPoints.splice(customPointStartIndex + 1, 1, newEndPoint);
|
|
1789
|
+
const CloudEngine = {
|
|
1790
|
+
draw(board, rectangle, options) {
|
|
1791
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
1792
|
+
const { startPoint, arcCommands } = generateCloudPath(rectangle);
|
|
1793
|
+
const pathData = `M ${startPoint[0]} ${startPoint[1]} ` +
|
|
1794
|
+
arcCommands
|
|
1795
|
+
.map((command) => `A ${command.rx} ${command.ry} ${command.xAxisRotation} ${command.largeArcFlag} ${command.sweepFlag} ${command.endX} ${command.endY}`)
|
|
1796
|
+
.join('\n') +
|
|
1797
|
+
' Z';
|
|
1798
|
+
const svgElement = rs.path(pathData, { ...options, fillStyle: 'solid' });
|
|
1799
|
+
setPathStrokeLinecap(svgElement, 'round');
|
|
1800
|
+
return svgElement;
|
|
1801
|
+
},
|
|
1802
|
+
isInsidePoint(rectangle, point) {
|
|
1803
|
+
const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
|
|
1804
|
+
return RectangleClient.isHit(rectangle, rangeRectangle);
|
|
1805
|
+
},
|
|
1806
|
+
getCornerPoints(rectangle) {
|
|
1807
|
+
return RectangleClient.getCornerPoints(rectangle);
|
|
1808
|
+
},
|
|
1809
|
+
getNearestPoint(rectangle, point) {
|
|
1810
|
+
const { startPoint, arcCommands } = generateCloudPath(rectangle);
|
|
1811
|
+
let minDistance = Infinity;
|
|
1812
|
+
let nearestPoint = point;
|
|
1813
|
+
let currentStart = startPoint;
|
|
1814
|
+
for (const arcCommand of arcCommands) {
|
|
1815
|
+
const arcNearestPoint = getNearestPointBetweenPointAndArc(point, currentStart, arcCommand);
|
|
1816
|
+
const distance = distanceBetweenPointAndPoint(point[0], point[1], arcNearestPoint[0], arcNearestPoint[1]);
|
|
1817
|
+
if (distance < minDistance) {
|
|
1818
|
+
minDistance = distance;
|
|
1819
|
+
nearestPoint = arcNearestPoint;
|
|
1839
1820
|
}
|
|
1821
|
+
currentStart = [arcCommand.endX, arcCommand.endY];
|
|
1840
1822
|
}
|
|
1823
|
+
return nearestPoint;
|
|
1824
|
+
},
|
|
1825
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
1826
|
+
const corners = CloudEngine.getCornerPoints(rectangle);
|
|
1827
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
1828
|
+
return getPolygonEdgeByConnectionPoint(corners, point);
|
|
1829
|
+
},
|
|
1830
|
+
getConnectorPoints(rectangle) {
|
|
1831
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
1832
|
+
},
|
|
1833
|
+
getTextRectangle(element) {
|
|
1834
|
+
const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
|
|
1835
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1836
|
+
const height = element.textHeight;
|
|
1837
|
+
const originWidth = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
|
|
1838
|
+
const width = originWidth / 1.5;
|
|
1839
|
+
return {
|
|
1840
|
+
height,
|
|
1841
|
+
width: width > 0 ? width : 0,
|
|
1842
|
+
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth + originWidth / 6,
|
|
1843
|
+
y: elementRectangle.y + elementRectangle.height / 6 + ((elementRectangle.height * 4) / 6 - height) / 2
|
|
1844
|
+
};
|
|
1841
1845
|
}
|
|
1842
1846
|
};
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1847
|
+
|
|
1848
|
+
const isTextExceedingBounds = (geometry) => {
|
|
1849
|
+
const client = RectangleClient.getRectangleByPoints(geometry.points);
|
|
1850
|
+
if (geometry.textHeight && geometry.textHeight > client.height) {
|
|
1846
1851
|
return true;
|
|
1847
1852
|
}
|
|
1848
1853
|
return false;
|
|
1849
|
-
}
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1854
|
+
};
|
|
1855
|
+
const isHitArrowLineText = (board, element, point) => {
|
|
1856
|
+
return getHitArrowLineTextIndex(board, element, point) !== -1;
|
|
1857
|
+
};
|
|
1858
|
+
const isHitPolyLine = (pathPoints, point) => {
|
|
1859
|
+
const distance = distanceBetweenPointAndSegments(point, pathPoints);
|
|
1860
|
+
return distance <= HIT_DISTANCE_BUFFER;
|
|
1861
|
+
};
|
|
1862
|
+
const isHitArrowLine = (board, element, point) => {
|
|
1863
|
+
const points = getArrowLinePoints(board, element);
|
|
1864
|
+
const isHitText = isHitArrowLineText(board, element, point);
|
|
1865
|
+
return isHitText || isHitPolyLine(points, point);
|
|
1866
|
+
};
|
|
1867
|
+
const isHitVectorLine = (board, element, point) => {
|
|
1868
|
+
const points = getVectorLinePoints(board, element);
|
|
1869
|
+
if (isClosedPoints(element.points)) {
|
|
1870
|
+
return isPointInPolygon(point, points) || isHitPolyLine(points, point);
|
|
1862
1871
|
}
|
|
1863
|
-
|
|
1864
|
-
|
|
1872
|
+
else {
|
|
1873
|
+
return isHitPolyLine(points, point);
|
|
1865
1874
|
}
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
if (isHorizontalSegment && isHorizontal) {
|
|
1876
|
-
parallelSegments.push([current, next]);
|
|
1877
|
-
}
|
|
1878
|
-
if (!isHorizontalSegment && !isHorizontal) {
|
|
1879
|
-
parallelSegments.push([current, next]);
|
|
1880
|
-
}
|
|
1875
|
+
};
|
|
1876
|
+
const isRectangleHitElementText = (element, rectangle) => {
|
|
1877
|
+
const engine = getEngine(element.shape);
|
|
1878
|
+
if (isMultipleTextGeometry(element)) {
|
|
1879
|
+
const texts = element.texts;
|
|
1880
|
+
return texts.some((item) => {
|
|
1881
|
+
const textClient = engine.getTextRectangle(element, { id: item.id });
|
|
1882
|
+
return isRectangleHitRotatedPoints(rectangle, RectangleClient.getCornerPoints(textClient), element.angle);
|
|
1883
|
+
});
|
|
1881
1884
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
debugGenerator$3.isDebug() && debugGenerator$3.clear();
|
|
1886
|
-
const mirrorSegments = [];
|
|
1887
|
-
for (let index = 0; index < parallelSegments.length; index++) {
|
|
1888
|
-
const parallelPath = parallelSegments[index];
|
|
1889
|
-
const startPoint = [segment[0][0], segment[0][1]];
|
|
1890
|
-
const endPoint = [segment[1][0], segment[1][1]];
|
|
1891
|
-
const isHorizontal = Point.isHorizontal(startPoint, endPoint);
|
|
1892
|
-
const adjustDataIndex = isHorizontal ? 0 : 1;
|
|
1893
|
-
startPoint[adjustDataIndex] = parallelPath[0][adjustDataIndex];
|
|
1894
|
-
endPoint[adjustDataIndex] = parallelPath[1][adjustDataIndex];
|
|
1895
|
-
const fakeRectangle = RectangleClient.getRectangleByPoints([startPoint, endPoint, ...parallelPath]);
|
|
1896
|
-
const isValid = !RectangleClient.isHit(fakeRectangle, sourceRectangle) && !RectangleClient.isHit(fakeRectangle, targetRectangle);
|
|
1897
|
-
if (isValid) {
|
|
1898
|
-
mirrorSegments.push([startPoint, endPoint]);
|
|
1899
|
-
debugGenerator$3.isDebug() && debugGenerator$3.drawPolygon(board, RectangleClient.getCornerPoints(fakeRectangle));
|
|
1900
|
-
}
|
|
1885
|
+
else {
|
|
1886
|
+
const textClient = engine.getTextRectangle ? engine.getTextRectangle(element) : getTextRectangle(element);
|
|
1887
|
+
return isRectangleHitRotatedPoints(rectangle, RectangleClient.getCornerPoints(textClient), element.angle);
|
|
1901
1888
|
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
const
|
|
1905
|
-
if (
|
|
1889
|
+
};
|
|
1890
|
+
const isHitElementText = (element, point) => {
|
|
1891
|
+
const engine = getEngine(element.shape);
|
|
1892
|
+
if (isMultipleTextGeometry(element)) {
|
|
1893
|
+
const texts = element.texts;
|
|
1894
|
+
return texts.some((item) => {
|
|
1895
|
+
const textClient = engine.getTextRectangle(element, { id: item.id });
|
|
1896
|
+
return RectangleClient.isPointInRectangle(textClient, point);
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
else {
|
|
1900
|
+
const textClient = engine.getTextRectangle ? engine.getTextRectangle(element) : getTextRectangle(element);
|
|
1901
|
+
return RectangleClient.isPointInRectangle(textClient, point);
|
|
1902
|
+
}
|
|
1903
|
+
};
|
|
1904
|
+
const isEmptyTextElement = (element) => {
|
|
1905
|
+
if (!isDrawElementIncludeText(element)) {
|
|
1906
1906
|
return true;
|
|
1907
1907
|
}
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
const afterPoint = midDataPoints[index + 1];
|
|
1911
|
-
const beforeSegment = beforePoint && [beforePoint, item];
|
|
1912
|
-
const afterSegment = afterPoint && [item, afterPoint];
|
|
1913
|
-
const isStraightWithBefore = beforeSegment && Point.isAlign(beforeSegment);
|
|
1914
|
-
const isStraightWithAfter = afterSegment && Point.isAlign(afterSegment);
|
|
1915
|
-
if (index === 0) {
|
|
1916
|
-
return !isStraightWithAfter;
|
|
1917
|
-
}
|
|
1918
|
-
if (index === midDataPoints.length - 1) {
|
|
1919
|
-
return !isStraightWithBefore;
|
|
1920
|
-
}
|
|
1921
|
-
return !isStraightWithBefore && !isStraightWithAfter;
|
|
1922
|
-
});
|
|
1908
|
+
const editor = getFirstTextEditor(element);
|
|
1909
|
+
return Editor.isEmpty(editor, editor.children[0]);
|
|
1923
1910
|
};
|
|
1924
|
-
|
|
1925
|
-
const
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1911
|
+
const isRectangleHitDrawElement = (board, element, selection) => {
|
|
1912
|
+
const rangeRectangle = RectangleClient.getRectangleByPoints([selection.anchor, selection.focus]);
|
|
1913
|
+
if (PlaitDrawElement.isGeometry(element)) {
|
|
1914
|
+
const isHitElement = isRectangleHitRotatedElement(board, rangeRectangle, element);
|
|
1915
|
+
if (isHitElement) {
|
|
1916
|
+
return isHitElement;
|
|
1917
|
+
}
|
|
1918
|
+
return !isEmptyTextElement(element) && isRectangleHitElementText(element, rangeRectangle);
|
|
1930
1919
|
}
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
if (points.length === 1) {
|
|
1934
|
-
points = [points[0], [points[0][0] + 0.1, points[0][1]]];
|
|
1920
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
1921
|
+
return isRectangleHitRotatedElement(board, rangeRectangle, element);
|
|
1935
1922
|
}
|
|
1936
|
-
if (
|
|
1937
|
-
const
|
|
1938
|
-
|
|
1939
|
-
sourceArrow && arrowG.appendChild(sourceArrow);
|
|
1923
|
+
if (PlaitDrawElement.isArrowLine(element)) {
|
|
1924
|
+
const points = getArrowLinePoints(board, element);
|
|
1925
|
+
return isLineHitRectangle(points, rangeRectangle);
|
|
1940
1926
|
}
|
|
1941
|
-
if (
|
|
1942
|
-
const
|
|
1943
|
-
|
|
1944
|
-
arrow && arrowG.appendChild(arrow);
|
|
1927
|
+
if (PlaitDrawElement.isVectorLine(element)) {
|
|
1928
|
+
const points = getVectorLinePoints(board, element);
|
|
1929
|
+
return isLineHitRectangle(points, rangeRectangle);
|
|
1945
1930
|
}
|
|
1946
|
-
return
|
|
1931
|
+
return null;
|
|
1947
1932
|
};
|
|
1948
|
-
const
|
|
1949
|
-
const
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1933
|
+
const isRectangleHitRotatedElement = (board, rectangle, element) => {
|
|
1934
|
+
const client = RectangleClient.getRectangleByPoints(element.points);
|
|
1935
|
+
return isRectangleHitRotatedPoints(rectangle, RectangleClient.getCornerPoints(client), element.angle);
|
|
1936
|
+
};
|
|
1937
|
+
const isRectangleHitRotatedPoints = (rectangle, points, angle) => {
|
|
1938
|
+
let rotatedPoints = rotatePointsByAngle(points, angle) || points;
|
|
1939
|
+
return isLineHitRectangle(rotatedPoints, rectangle);
|
|
1940
|
+
};
|
|
1941
|
+
const getHitDrawElement = (board, elements) => {
|
|
1942
|
+
let firstFilledElement = getFirstFilledDrawElement(board, elements);
|
|
1943
|
+
let endIndex = elements.length;
|
|
1944
|
+
if (firstFilledElement) {
|
|
1945
|
+
endIndex = elements.indexOf(firstFilledElement) + 1;
|
|
1946
|
+
}
|
|
1947
|
+
const newElements = elements.slice(0, endIndex);
|
|
1948
|
+
const element = getFirstTextOrLineElement(newElements);
|
|
1949
|
+
if (element) {
|
|
1950
|
+
return element;
|
|
1951
|
+
}
|
|
1952
|
+
const sortElements = sortElementsByArea(board, newElements, 'asc');
|
|
1953
|
+
return sortElements[0];
|
|
1954
|
+
};
|
|
1955
|
+
const getFirstFilledDrawElement = (board, elements) => {
|
|
1956
|
+
let filledElement = null;
|
|
1957
|
+
for (let i = 0; i < elements.length; i++) {
|
|
1958
|
+
const element = elements[i];
|
|
1959
|
+
if (isClosedCustomGeometry(board, element) || isClosedDrawElement(element)) {
|
|
1960
|
+
const fill = getFillByElement(board, element);
|
|
1961
|
+
if (isFilled(fill)) {
|
|
1962
|
+
filledElement = element;
|
|
1963
|
+
break;
|
|
1964
|
+
}
|
|
1967
1965
|
}
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1966
|
+
}
|
|
1967
|
+
return filledElement;
|
|
1968
|
+
};
|
|
1969
|
+
const isFilledDrawElement = (board, element) => {
|
|
1970
|
+
return getFirstFilledDrawElement(board, [element]) !== null;
|
|
1971
|
+
};
|
|
1972
|
+
const getFirstTextOrLineElement = (elements) => {
|
|
1973
|
+
const texts = elements.filter((item) => PlaitDrawElement.isText(item));
|
|
1974
|
+
if (texts.length) {
|
|
1975
|
+
return texts[0];
|
|
1976
|
+
}
|
|
1977
|
+
const lines = elements.filter((item) => PlaitDrawElement.isArrowLine(item));
|
|
1978
|
+
if (lines.length) {
|
|
1979
|
+
return lines[0];
|
|
1980
|
+
}
|
|
1981
|
+
return null;
|
|
1982
|
+
};
|
|
1983
|
+
const debugKey$3 = 'debug:plait:hit:shape:edge:sample-points';
|
|
1984
|
+
const debugGenerator$3 = createDebugGenerator(debugKey$3);
|
|
1985
|
+
const shapes = [BasicShapes.cloud];
|
|
1986
|
+
const isHitDrawElement = (board, element, point, isStrict = true) => {
|
|
1987
|
+
const rectangle = board.getRectangle(element);
|
|
1988
|
+
point = rotateAntiPointsByElement(board, point, element) || point;
|
|
1989
|
+
if (PlaitDrawElement.isGeometry(element) && rectangle) {
|
|
1990
|
+
if (debugGenerator$3.isDebug() && shapes.includes(element.shape)) {
|
|
1991
|
+
debugGenerator$3.clear();
|
|
1992
|
+
const { startPoint, arcCommands } = generateCloudPath(rectangle);
|
|
1993
|
+
const points = [startPoint, ...arcCommands.map((arc) => [arc.endX, arc.endY])];
|
|
1994
|
+
debugGenerator$3.drawCircles(board, points, 5, false);
|
|
1995
|
+
let minDistance = Infinity;
|
|
1996
|
+
let nearestPoint = point;
|
|
1997
|
+
let currentStart = startPoint;
|
|
1998
|
+
for (const arc of arcCommands) {
|
|
1999
|
+
const arcNearestPoint = getNearestPointBetweenPointAndArc(point, currentStart, arc);
|
|
2000
|
+
const distance = distanceBetweenPointAndPoint(point[0], point[1], arcNearestPoint[0], arcNearestPoint[1]);
|
|
2001
|
+
const { center } = getEllipseArcCenter(currentStart, arc);
|
|
2002
|
+
debugGenerator$3.drawCircles(board, [center], 8, false, { fill: 'yellow' });
|
|
2003
|
+
if (distance < minDistance) {
|
|
2004
|
+
minDistance = distance;
|
|
2005
|
+
nearestPoint = arcNearestPoint;
|
|
2006
|
+
}
|
|
2007
|
+
currentStart = [arc.endX, arc.endY];
|
|
2008
|
+
}
|
|
2009
|
+
debugGenerator$3.drawCircles(board, [point], 12, false, { fill: 'black', stroke: 'black' });
|
|
2010
|
+
debugGenerator$3.drawCircles(board, [nearestPoint], 12, false, { fill: 'green', stroke: 'green' });
|
|
1971
2011
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
break;
|
|
2012
|
+
if (isHitEdgeOfShape(board, element, point, HIT_DISTANCE_BUFFER)) {
|
|
2013
|
+
return true;
|
|
1975
2014
|
}
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
2015
|
+
const engine = getEngine(getElementShape(element));
|
|
2016
|
+
if (PlaitDrawElement.isText(element)) {
|
|
2017
|
+
const textClient = getTextRectangle(element);
|
|
2018
|
+
return RectangleClient.isPointInRectangle(textClient, point);
|
|
1979
2019
|
}
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
break;
|
|
2020
|
+
if (!!isStrict && isEmptyTextElement(element) && !isFilledDrawElement(board, element)) {
|
|
2021
|
+
return false;
|
|
1983
2022
|
}
|
|
2023
|
+
const isHitText = isHitElementText(element, point);
|
|
2024
|
+
return isHitText || engine.isInsidePoint(rectangle, point);
|
|
1984
2025
|
}
|
|
1985
|
-
|
|
2026
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2027
|
+
const client = RectangleClient.getRectangleByPoints(element.points);
|
|
2028
|
+
return RectangleClient.isPointInRectangle(client, point);
|
|
2029
|
+
}
|
|
2030
|
+
if (PlaitDrawElement.isArrowLine(element)) {
|
|
2031
|
+
return isHitArrowLine(board, element, point);
|
|
2032
|
+
}
|
|
2033
|
+
if (PlaitDrawElement.isVectorLine(element)) {
|
|
2034
|
+
return isHitVectorLine(board, element, point);
|
|
2035
|
+
}
|
|
2036
|
+
return null;
|
|
1986
2037
|
};
|
|
1987
|
-
const
|
|
1988
|
-
const
|
|
1989
|
-
const
|
|
1990
|
-
|
|
1991
|
-
const path = createPath();
|
|
1992
|
-
let polylinePath = `M${pointRight[0]},${pointRight[1]}A25,25,20,0,1,${pointLeft[0]},${pointLeft[1]}L${startPoint[0]},${startPoint[1]}Z`;
|
|
1993
|
-
path.setAttribute('d', polylinePath);
|
|
1994
|
-
path.setAttribute('stroke', `${options?.stroke}`);
|
|
1995
|
-
path.setAttribute('stroke-width', `${options?.strokeWidth}`);
|
|
1996
|
-
path.setAttribute('fill', `${options?.stroke}`);
|
|
1997
|
-
g.appendChild(path);
|
|
1998
|
-
return g;
|
|
2038
|
+
const isHitEdgeOfShape = (board, element, point, hitDistanceBuffer) => {
|
|
2039
|
+
const nearestPoint = getNearestPoint(element, point);
|
|
2040
|
+
const distance = distanceBetweenPointAndPoint(nearestPoint[0], nearestPoint[1], point[0], point[1]);
|
|
2041
|
+
return distance <= hitDistanceBuffer;
|
|
1999
2042
|
};
|
|
2000
|
-
const
|
|
2001
|
-
const
|
|
2002
|
-
|
|
2003
|
-
const endPoint = [target[0] + (strokeWidth * unitVector[0]) / 2, target[1] + (strokeWidth * unitVector[1]) / 2];
|
|
2004
|
-
const distance = distanceBetweenPointAndPoint(...source, ...endPoint);
|
|
2005
|
-
const middlePoint = [
|
|
2006
|
-
endPoint[0] - (((distance * 3) / 5 + strokeWidth) / 2) * unitVector[0],
|
|
2007
|
-
endPoint[1] - (((distance * 3) / 5 + strokeWidth) / 2) * unitVector[1]
|
|
2008
|
-
];
|
|
2009
|
-
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 30);
|
|
2010
|
-
const arrowG = drawLinearPath([pointLeft, endPoint, pointRight, middlePoint], { ...options, fill: options.stroke }, true);
|
|
2011
|
-
const path = arrowG.querySelector('path');
|
|
2012
|
-
path.setAttribute('stroke-linejoin', 'round');
|
|
2013
|
-
return arrowG;
|
|
2043
|
+
const isInsideOfShape = (board, element, point, hitDistanceBuffer) => {
|
|
2044
|
+
const client = RectangleClient.inflate(RectangleClient.getRectangleByPoints(element.points), hitDistanceBuffer);
|
|
2045
|
+
return getEngine(getElementShape(element)).isInsidePoint(client, point);
|
|
2014
2046
|
};
|
|
2015
|
-
const
|
|
2016
|
-
const
|
|
2017
|
-
|
|
2018
|
-
|
|
2047
|
+
const isHitElementInside = (board, element, point) => {
|
|
2048
|
+
const rectangle = board.getRectangle(element);
|
|
2049
|
+
point = rotateAntiPointsByElement(board, point, element) || point;
|
|
2050
|
+
if (PlaitDrawElement.isGeometry(element) && !PlaitDrawElement.isGeometryByTable(element)) {
|
|
2051
|
+
const engine = getEngine(getElementShape(element));
|
|
2052
|
+
const isHitInside = engine.isInsidePoint(rectangle, point);
|
|
2053
|
+
if (isHitInside) {
|
|
2054
|
+
return isHitInside;
|
|
2055
|
+
}
|
|
2056
|
+
if (engine.getTextRectangle) {
|
|
2057
|
+
const isHitText = isHitElementText(element, point);
|
|
2058
|
+
if (isHitText) {
|
|
2059
|
+
return isHitText;
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2064
|
+
const client = RectangleClient.getRectangleByPoints(element.points);
|
|
2065
|
+
return RectangleClient.isPointInRectangle(client, point);
|
|
2066
|
+
}
|
|
2067
|
+
if (PlaitDrawElement.isArrowLine(element)) {
|
|
2068
|
+
return isHitArrowLine(board, element, point);
|
|
2069
|
+
}
|
|
2070
|
+
if (PlaitDrawElement.isVectorLine(element)) {
|
|
2071
|
+
return isHitVectorLine(board, element, point);
|
|
2072
|
+
}
|
|
2073
|
+
return null;
|
|
2019
2074
|
};
|
|
2020
|
-
|
|
2021
|
-
|
|
2075
|
+
|
|
2076
|
+
const getTextRectangle = (element) => {
|
|
2077
|
+
const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
|
|
2022
2078
|
const strokeWidth = getStrokeWidthByElement(element);
|
|
2023
|
-
const
|
|
2024
|
-
const
|
|
2025
|
-
return
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2079
|
+
const height = element.textHeight;
|
|
2080
|
+
const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
|
|
2081
|
+
return {
|
|
2082
|
+
height,
|
|
2083
|
+
width: width > 0 ? width : 0,
|
|
2084
|
+
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
|
|
2085
|
+
y: elementRectangle.y + (elementRectangle.height - height) / 2
|
|
2086
|
+
};
|
|
2030
2087
|
};
|
|
2031
|
-
const
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
const
|
|
2036
|
-
|
|
2037
|
-
return drawLinearPath([start, end], options);
|
|
2088
|
+
const getStrokeWidthByElement = (element) => {
|
|
2089
|
+
if (PlaitDrawElement.isText(element)) {
|
|
2090
|
+
return 0;
|
|
2091
|
+
}
|
|
2092
|
+
const strokeWidth = element.strokeWidth || DefaultDrawStyle.strokeWidth;
|
|
2093
|
+
return strokeWidth;
|
|
2038
2094
|
};
|
|
2039
|
-
const
|
|
2040
|
-
|
|
2041
|
-
|
|
2095
|
+
const insertElement = (board, element) => {
|
|
2096
|
+
memorizeLatestShape(board, element.shape);
|
|
2097
|
+
Transforms.insertNode(board, element, [board.children.length]);
|
|
2098
|
+
clearSelectedElement(board);
|
|
2099
|
+
addSelectedElement(board, element);
|
|
2100
|
+
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
2042
2101
|
};
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
canDraw(element) {
|
|
2102
|
+
const isDrawElementIncludeText = (element) => {
|
|
2103
|
+
if (PlaitDrawElement.isText(element)) {
|
|
2046
2104
|
return true;
|
|
2047
2105
|
}
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
lineG = drawArrowLine(this.board, element);
|
|
2051
|
-
return lineG;
|
|
2106
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2107
|
+
return false;
|
|
2052
2108
|
}
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
points,
|
|
2065
|
-
...options
|
|
2066
|
-
};
|
|
2109
|
+
if (PlaitDrawElement.isGeometry(element)) {
|
|
2110
|
+
return isGeometryIncludeText(element);
|
|
2111
|
+
}
|
|
2112
|
+
if (PlaitDrawElement.isArrowLine(element)) {
|
|
2113
|
+
const editors = getTextEditorsByElement(element);
|
|
2114
|
+
return editors.length > 0;
|
|
2115
|
+
}
|
|
2116
|
+
if (PlaitDrawElement.isElementByTable(element)) {
|
|
2117
|
+
return element.cells.some((cell) => isCellIncludeText(cell));
|
|
2118
|
+
}
|
|
2119
|
+
return true;
|
|
2067
2120
|
};
|
|
2068
|
-
const
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2121
|
+
const isDrawElementsIncludeText = (elements) => {
|
|
2122
|
+
return elements.some((item) => {
|
|
2123
|
+
return isDrawElementIncludeText(item);
|
|
2124
|
+
});
|
|
2125
|
+
};
|
|
2126
|
+
const isClosedDrawElement = (element) => {
|
|
2127
|
+
if (PlaitDrawElement.isDrawElement(element)) {
|
|
2128
|
+
if (PlaitDrawElement.isText(element) || PlaitDrawElement.isArrowLine(element) || PlaitDrawElement.isImage(element)) {
|
|
2129
|
+
return false;
|
|
2072
2130
|
}
|
|
2073
|
-
|
|
2074
|
-
return
|
|
2131
|
+
if (PlaitDrawElement.isVectorLine(element)) {
|
|
2132
|
+
return isClosedPoints(element.points);
|
|
2075
2133
|
}
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
const handleRefPair = getArrowLineHandleRefPair(board, element);
|
|
2079
|
-
points[0] = handleRefPair.source.point;
|
|
2080
|
-
points[points.length - 1] = handleRefPair.target.point;
|
|
2081
|
-
return points;
|
|
2134
|
+
if (PlaitDrawElement.isGeometry(element)) {
|
|
2135
|
+
return isGeometryClosed(element);
|
|
2082
2136
|
}
|
|
2137
|
+
return true;
|
|
2083
2138
|
}
|
|
2139
|
+
return false;
|
|
2084
2140
|
};
|
|
2085
|
-
const
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
if (sourceBoundElement) {
|
|
2095
|
-
curvePoints.push(getPointByVectorComponent(source.point, source.vector, offset));
|
|
2096
|
-
}
|
|
2097
|
-
if (targetBoundElement) {
|
|
2098
|
-
curvePoints.push(getPointByVectorComponent(target.point, target.vector, offset));
|
|
2141
|
+
const isClosedCustomGeometry = (board, value) => {
|
|
2142
|
+
return PlaitDrawElement.isCustomGeometryElement(board, value) && isClosedPoints(value.points);
|
|
2143
|
+
};
|
|
2144
|
+
const getSnappingShape = (board, point) => {
|
|
2145
|
+
let hitElement = getHitShape(board, point);
|
|
2146
|
+
if (hitElement) {
|
|
2147
|
+
const ref = getSnappingRef(board, hitElement, point);
|
|
2148
|
+
if (ref.isHitConnector || ref.isHitEdge) {
|
|
2149
|
+
return hitElement;
|
|
2099
2150
|
}
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2151
|
+
}
|
|
2152
|
+
return null;
|
|
2153
|
+
};
|
|
2154
|
+
const getSnappingRef = (board, hitElement, point) => {
|
|
2155
|
+
const rotatedPoint = rotateAntiPointsByElement(board, point, hitElement) || point;
|
|
2156
|
+
const connectorPoint = getHitConnectorPoint(rotatedPoint, hitElement);
|
|
2157
|
+
const edgePoint = getNearestPoint(hitElement, rotatedPoint);
|
|
2158
|
+
const isHitEdge = isHitEdgeOfShape(board, hitElement, rotatedPoint, LINE_SNAPPING_BUFFER);
|
|
2159
|
+
return { isHitEdge, isHitConnector: !!connectorPoint, connectorPoint, edgePoint };
|
|
2160
|
+
};
|
|
2161
|
+
const getHitShape = (board, point, offset = LINE_HIT_GEOMETRY_BUFFER) => {
|
|
2162
|
+
let hitShape = null;
|
|
2163
|
+
traverseDrawShapes(board, (element) => {
|
|
2164
|
+
if (hitShape === null && isInsideOfShape(board, element, rotateAntiPointsByElement(board, point, element) || point, offset * 2)) {
|
|
2165
|
+
hitShape = element;
|
|
2105
2166
|
}
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2167
|
+
});
|
|
2168
|
+
return hitShape;
|
|
2169
|
+
};
|
|
2170
|
+
const traverseDrawShapes = (board, callback) => {
|
|
2171
|
+
depthFirstRecursion(board, (node) => {
|
|
2172
|
+
if (!PlaitBoard.isBoard(node) && PlaitDrawElement.isShapeElement(node)) {
|
|
2173
|
+
callback(node);
|
|
2109
2174
|
}
|
|
2110
|
-
|
|
2111
|
-
|
|
2175
|
+
}, getIsRecursionFunc(board), true);
|
|
2176
|
+
};
|
|
2177
|
+
const drawShape = (board, outerRectangle, shape, roughOptions, drawOptions) => {
|
|
2178
|
+
return getEngine(shape).draw(board, outerRectangle, roughOptions, drawOptions);
|
|
2179
|
+
};
|
|
2180
|
+
const drawBoundReaction = (board, element, roughOptions = { hasMask: true, hasConnector: true }) => {
|
|
2181
|
+
const g = createG();
|
|
2182
|
+
const rectangle = RectangleClient.getRectangleByPoints(element.points);
|
|
2183
|
+
const activeRectangle = RectangleClient.inflate(rectangle, SNAPPING_STROKE_WIDTH);
|
|
2184
|
+
const shape = getElementShape(element);
|
|
2185
|
+
let drawOptions;
|
|
2186
|
+
if (PlaitDrawElement.isElementByTable(element)) {
|
|
2187
|
+
drawOptions = { element };
|
|
2112
2188
|
}
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2189
|
+
const strokeG = drawShape(board, activeRectangle, shape, {
|
|
2190
|
+
stroke: SELECTION_BORDER_COLOR,
|
|
2191
|
+
strokeWidth: SNAPPING_STROKE_WIDTH
|
|
2192
|
+
}, drawOptions);
|
|
2193
|
+
g.appendChild(strokeG);
|
|
2194
|
+
if (roughOptions.hasMask) {
|
|
2195
|
+
const maskG = drawShape(board, activeRectangle, shape, {
|
|
2196
|
+
stroke: SELECTION_BORDER_COLOR,
|
|
2197
|
+
strokeWidth: 0,
|
|
2198
|
+
fill: isClosedDrawElement(element) ? SELECTION_FILL_COLOR : DefaultDrawStyle.fill,
|
|
2199
|
+
fillStyle: 'solid'
|
|
2200
|
+
}, drawOptions);
|
|
2201
|
+
g.appendChild(maskG);
|
|
2202
|
+
}
|
|
2203
|
+
if (roughOptions.hasConnector) {
|
|
2204
|
+
const connectorPoints = getEngine(shape).getConnectorPoints(rectangle);
|
|
2205
|
+
connectorPoints.forEach((point) => {
|
|
2206
|
+
const circleG = drawCircle(PlaitBoard.getRoughSVG(board), point, 8, {
|
|
2207
|
+
stroke: SELECTION_BORDER_COLOR,
|
|
2208
|
+
strokeWidth: ACTIVE_STROKE_WIDTH,
|
|
2209
|
+
fill: '#FFF',
|
|
2210
|
+
fillStyle: 'solid'
|
|
2211
|
+
});
|
|
2212
|
+
g.appendChild(circleG);
|
|
2213
|
+
});
|
|
2118
2214
|
}
|
|
2215
|
+
return g;
|
|
2119
2216
|
};
|
|
2120
|
-
const
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
const strokeStyle = getStrokeStyleByElement(board, element);
|
|
2124
|
-
const strokeLineDash = getStrokeLineDash(strokeStyle, strokeWidth);
|
|
2125
|
-
const options = { stroke: strokeColor, strokeWidth, strokeLineDash };
|
|
2126
|
-
const lineG = createG();
|
|
2127
|
-
let points = getArrowLinePoints(board, element);
|
|
2128
|
-
let line;
|
|
2129
|
-
if (element.shape === ArrowLineShape.curve) {
|
|
2130
|
-
line = PlaitBoard.getRoughSVG(board).curve(points, options);
|
|
2217
|
+
const getTextKey = (element, text) => {
|
|
2218
|
+
if (element && isMultipleTextGeometry(element)) {
|
|
2219
|
+
return `${element.id}-${text.id}`;
|
|
2131
2220
|
}
|
|
2132
2221
|
else {
|
|
2133
|
-
|
|
2134
|
-
}
|
|
2135
|
-
const id = idCreator();
|
|
2136
|
-
line.setAttribute('mask', `url(#${id})`);
|
|
2137
|
-
if (element.strokeStyle === StrokeStyle.dotted) {
|
|
2138
|
-
setStrokeLinecap(line, 'round');
|
|
2222
|
+
return text.id;
|
|
2139
2223
|
}
|
|
2140
|
-
lineG.appendChild(line);
|
|
2141
|
-
const { mask, maskTargetFillRect } = drawArrowLineMask(board, element, id);
|
|
2142
|
-
lineG.appendChild(mask);
|
|
2143
|
-
line.appendChild(maskTargetFillRect);
|
|
2144
|
-
const arrow = drawArrowLineArrow(element, points, { stroke: strokeColor, strokeWidth });
|
|
2145
|
-
arrow && lineG.appendChild(arrow);
|
|
2146
|
-
return lineG;
|
|
2147
|
-
};
|
|
2148
|
-
const getHitConnection = (board, point, hitElement) => {
|
|
2149
|
-
let rectangle = RectangleClient.getRectangleByPoints(hitElement.points);
|
|
2150
|
-
const ref = getSnappingRef(board, hitElement, point);
|
|
2151
|
-
const connectionPoint = ref.connectorPoint || ref.edgePoint;
|
|
2152
|
-
return [(connectionPoint[0] - rectangle.x) / rectangle.width, (connectionPoint[1] - rectangle.y) / rectangle.height];
|
|
2153
|
-
};
|
|
2154
|
-
const getHitConnectorPoint = (point, hitElement) => {
|
|
2155
|
-
const rectangle = RectangleClient.getRectangleByPoints(hitElement.points);
|
|
2156
|
-
const shape = getElementShape(hitElement);
|
|
2157
|
-
const connectorPoints = getEngine(shape).getConnectorPoints(rectangle);
|
|
2158
|
-
return connectorPoints.find(connectorPoint => {
|
|
2159
|
-
return distanceBetweenPointAndPoint(...connectorPoint, ...point) <= LINE_SNAPPING_CONNECTOR_BUFFER;
|
|
2160
|
-
});
|
|
2161
|
-
};
|
|
2162
|
-
const getArrowLineTextRectangle = (board, element, index) => {
|
|
2163
|
-
const text = element.texts[index];
|
|
2164
|
-
const elbowPoints = getArrowLinePoints(board, element);
|
|
2165
|
-
const point = getPointOnPolyline(elbowPoints, text.position);
|
|
2166
|
-
return {
|
|
2167
|
-
x: point[0] - text.width / 2,
|
|
2168
|
-
y: point[1] - text.height / 2,
|
|
2169
|
-
width: text.width,
|
|
2170
|
-
height: text.height
|
|
2171
|
-
};
|
|
2172
|
-
};
|
|
2173
|
-
const getArrowLines = (board) => {
|
|
2174
|
-
return findElements(board, {
|
|
2175
|
-
match: (element) => PlaitDrawElement.isArrowLine(element),
|
|
2176
|
-
recursion: (element) => PlaitDrawElement.isDrawElement(element)
|
|
2177
|
-
});
|
|
2178
2224
|
};
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
for (let i = 0; i < numSegments; i++) {
|
|
2184
|
-
const start = points[i];
|
|
2185
|
-
const qControl = points[i + 1];
|
|
2186
|
-
const end = points[i + 2];
|
|
2187
|
-
const startDistance = distanceBetweenPointAndPoint(...start, ...qControl);
|
|
2188
|
-
const endDistance = distanceBetweenPointAndPoint(...end, ...qControl);
|
|
2189
|
-
const cControl1 = getExtendPoint(start, qControl, (startDistance * 2) / 3);
|
|
2190
|
-
const cControl2 = getExtendPoint(end, qControl, (endDistance * 2) / 3);
|
|
2191
|
-
result.push(start, cControl1, cControl2, end);
|
|
2225
|
+
const getGeometryAlign = (board, element) => {
|
|
2226
|
+
if (isMultipleTextGeometry(element)) {
|
|
2227
|
+
const drawShapeText = element.texts.find((item) => item.id.includes(GeometryCommonTextKeys.content));
|
|
2228
|
+
return drawShapeText?.text.align || Alignment.center;
|
|
2192
2229
|
}
|
|
2193
|
-
|
|
2230
|
+
if (isSingleTextGeometry(element)) {
|
|
2231
|
+
return element.text?.align || Alignment.center;
|
|
2232
|
+
}
|
|
2233
|
+
if (PlaitDrawElement.isElementByTable(element)) {
|
|
2234
|
+
const firstTextCell = element.cells.find((item) => item.text);
|
|
2235
|
+
return firstTextCell?.text?.align || Alignment.center;
|
|
2236
|
+
}
|
|
2237
|
+
return Alignment.center;
|
|
2194
2238
|
};
|
|
2195
|
-
const
|
|
2196
|
-
const
|
|
2197
|
-
const
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
let sourceMarker, targetMarker;
|
|
2203
|
-
sourceMarker = memorizedLatest.source;
|
|
2204
|
-
targetMarker = memorizedLatest.target;
|
|
2205
|
-
sourceMarker && delete memorizedLatest.source;
|
|
2206
|
-
targetMarker && delete memorizedLatest.target;
|
|
2207
|
-
const temporaryLineElement = createArrowLineElement(lineShape, [sourcePoint, movingPoint], { marker: sourceMarker || ArrowLineMarkerType.none, connection: sourceConnection, boundId: sourceElement?.id }, { marker: targetMarker || ArrowLineMarkerType.arrow, connection: targetConnection, boundId: targetBoundId }, [], {
|
|
2208
|
-
strokeWidth: DefaultLineStyle.strokeWidth,
|
|
2209
|
-
...memorizedLatest
|
|
2210
|
-
});
|
|
2211
|
-
const linePoints = getArrowLinePoints(board, temporaryLineElement);
|
|
2212
|
-
const otherPoint = linePoints[0];
|
|
2213
|
-
temporaryLineElement.points[1] = alignPoints(otherPoint, movingPoint);
|
|
2214
|
-
lineGenerator.processDrawing(temporaryLineElement, lineShapeG);
|
|
2215
|
-
PlaitBoard.getElementActiveHost(board).append(lineShapeG);
|
|
2216
|
-
return temporaryLineElement;
|
|
2239
|
+
const isClosedPoints = (points) => {
|
|
2240
|
+
const startPoint = points[0];
|
|
2241
|
+
const endPoint = points[points.length - 1];
|
|
2242
|
+
return startPoint[0] === endPoint[0] && startPoint[1] === endPoint[1];
|
|
2243
|
+
};
|
|
2244
|
+
const getDefaultGeometryText = (board) => {
|
|
2245
|
+
return getI18nValue(board, DrawI18nKey.geometryText, DefaultTextProperty.text);
|
|
2217
2246
|
};
|
|
2218
|
-
function drawArrowLineMask(board, element, id) {
|
|
2219
|
-
const mask = createMask();
|
|
2220
|
-
mask.setAttribute('id', id);
|
|
2221
|
-
const points = getArrowLinePoints(board, element);
|
|
2222
|
-
let rectangle = RectangleClient.getRectangleByPoints(points);
|
|
2223
|
-
rectangle = RectangleClient.getOutlineRectangle(rectangle, -30);
|
|
2224
|
-
const maskFillRect = createRect(rectangle, {
|
|
2225
|
-
fill: 'white'
|
|
2226
|
-
});
|
|
2227
|
-
mask.appendChild(maskFillRect);
|
|
2228
|
-
const texts = element.texts;
|
|
2229
|
-
texts.forEach((text, index) => {
|
|
2230
|
-
let textRectangle = getArrowLineTextRectangle(board, element, index);
|
|
2231
|
-
textRectangle = RectangleClient.inflate(textRectangle, LINE_TEXT_SPACE * 2);
|
|
2232
|
-
const rect = createRect(textRectangle, {
|
|
2233
|
-
fill: 'black'
|
|
2234
|
-
});
|
|
2235
|
-
mask.appendChild(rect);
|
|
2236
|
-
});
|
|
2237
|
-
// open line
|
|
2238
|
-
const maskTargetFillRect = createRect(rectangle);
|
|
2239
|
-
maskTargetFillRect.setAttribute('opacity', '0');
|
|
2240
|
-
maskTargetFillRect.setAttribute('fill', 'none');
|
|
2241
|
-
return { mask, maskTargetFillRect };
|
|
2242
|
-
}
|
|
2243
2247
|
|
|
2244
2248
|
const createUMLClassOrInterfaceGeometryElement = (board, shape, points) => {
|
|
2245
2249
|
const memorizedLatest = getMemorizedLatestByPointer(shape);
|
|
@@ -2301,8 +2305,9 @@ const buildTableCellsForGeometry = (board, rows, columns, shape) => {
|
|
|
2301
2305
|
const memorizedLatest = getMemorizedLatestByPointer(shape);
|
|
2302
2306
|
const cellCount = rows.length * columns.length;
|
|
2303
2307
|
const defaultTexts = getDefaultGeometryProperty(shape)?.texts || [];
|
|
2304
|
-
const
|
|
2305
|
-
return getTextShapeProperty(board, textItem.text ||
|
|
2308
|
+
const textHeights = defaultTexts.map((textItem) => {
|
|
2309
|
+
return getTextShapeProperty(board, textItem.text || getDefaultGeometryText(board), memorizedLatest.textProperties['font-size'])
|
|
2310
|
+
.height;
|
|
2306
2311
|
});
|
|
2307
2312
|
return new Array(cellCount).fill('').map((item, index) => {
|
|
2308
2313
|
const rowIndex = Math.floor(index / columns.length);
|
|
@@ -2311,7 +2316,7 @@ const buildTableCellsForGeometry = (board, rows, columns, shape) => {
|
|
|
2311
2316
|
id: idCreator(),
|
|
2312
2317
|
rowId: rows[rowIndex].id,
|
|
2313
2318
|
columnId: columns[columnIndex].id,
|
|
2314
|
-
textHeight:
|
|
2319
|
+
textHeight: textHeights[index],
|
|
2315
2320
|
text: {
|
|
2316
2321
|
children: [
|
|
2317
2322
|
{
|
|
@@ -2394,66 +2399,12 @@ const getDefaultBasicShapeProperty = (shape) => {
|
|
|
2394
2399
|
const getDefaultUMLProperty = (shape) => {
|
|
2395
2400
|
return DefaultUMLPropertyMap[shape];
|
|
2396
2401
|
};
|
|
2397
|
-
const
|
|
2398
|
-
const decisionProperty = getDefaultFlowchartProperty(FlowchartSymbols.decision);
|
|
2399
|
-
const processProperty = getDefaultFlowchartProperty(FlowchartSymbols.process);
|
|
2400
|
-
const terminalProperty = getDefaultFlowchartProperty(FlowchartSymbols.terminal);
|
|
2401
|
-
const options = {
|
|
2402
|
-
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
2403
|
-
};
|
|
2404
|
-
const lineOptions = {
|
|
2405
|
-
strokeWidth: DefaultLineStyle.strokeWidth
|
|
2406
|
-
};
|
|
2407
|
-
const startElement = createGeometryElement(FlowchartSymbols.terminal, getDefaultGeometryPoints(FlowchartSymbols.terminal, point), '开始', options);
|
|
2408
|
-
const processPoint1 = [point[0], point[1] + terminalProperty.height / 2 + 55 + processProperty.height / 2];
|
|
2409
|
-
const processElement1 = createGeometryElement(FlowchartSymbols.process, getDefaultGeometryPoints(FlowchartSymbols.process, processPoint1), '过程', options);
|
|
2410
|
-
const decisionPoint = [processPoint1[0], processPoint1[1] + processProperty.height / 2 + 55 + decisionProperty.height / 2];
|
|
2411
|
-
const decisionElement = createGeometryElement(FlowchartSymbols.decision, getDefaultGeometryPoints(FlowchartSymbols.decision, decisionPoint), '判断', options);
|
|
2412
|
-
const processPoint2 = [decisionPoint[0] + decisionProperty.width / 2 + 75 + processProperty.width / 2, decisionPoint[1]];
|
|
2413
|
-
const processElement2 = createGeometryElement(FlowchartSymbols.process, getDefaultGeometryPoints(FlowchartSymbols.process, processPoint2), '过程', options);
|
|
2414
|
-
const endPoint = [decisionPoint[0], decisionPoint[1] + decisionProperty.height / 2 + 95 + terminalProperty.height / 2];
|
|
2415
|
-
const endElement = createGeometryElement(FlowchartSymbols.terminal, getDefaultGeometryPoints(FlowchartSymbols.terminal, endPoint), '结束', options);
|
|
2416
|
-
const line1 = createArrowLineElement(ArrowLineShape.elbow, [
|
|
2417
|
-
[0, 0],
|
|
2418
|
-
[0, 0]
|
|
2419
|
-
], { marker: ArrowLineMarkerType.none, connection: [0.5, 1], boundId: startElement.id }, { marker: ArrowLineMarkerType.arrow, connection: [0.5, 0], boundId: processElement1.id }, [], lineOptions);
|
|
2420
|
-
const line2 = createArrowLineElement(ArrowLineShape.elbow, [
|
|
2421
|
-
[0, 0],
|
|
2422
|
-
[0, 0]
|
|
2423
|
-
], { marker: ArrowLineMarkerType.none, connection: [0.5, 1], boundId: processElement1.id }, { marker: ArrowLineMarkerType.arrow, connection: [0.5, 0], boundId: decisionElement.id }, [], lineOptions);
|
|
2424
|
-
const line3 = createArrowLineElement(ArrowLineShape.elbow, [
|
|
2425
|
-
[0, 0],
|
|
2426
|
-
[0, 0]
|
|
2427
|
-
], { marker: ArrowLineMarkerType.none, connection: [0.5, 1], boundId: decisionElement.id }, { marker: ArrowLineMarkerType.arrow, connection: [0.5, 0], boundId: endElement.id }, [
|
|
2428
|
-
{
|
|
2429
|
-
text: buildText('是'),
|
|
2430
|
-
position: 0.5,
|
|
2431
|
-
width: 14,
|
|
2432
|
-
height: 20
|
|
2433
|
-
}
|
|
2434
|
-
], lineOptions);
|
|
2435
|
-
const line4 = createArrowLineElement(ArrowLineShape.elbow, [
|
|
2436
|
-
[0, 0],
|
|
2437
|
-
[0, 0]
|
|
2438
|
-
], { marker: ArrowLineMarkerType.none, connection: [1, 0.5], boundId: decisionElement.id }, { marker: ArrowLineMarkerType.arrow, connection: [0, 0.5], boundId: processElement2.id }, [
|
|
2439
|
-
{
|
|
2440
|
-
text: buildText('否'),
|
|
2441
|
-
position: 0.5,
|
|
2442
|
-
width: 14,
|
|
2443
|
-
height: 20
|
|
2444
|
-
}
|
|
2445
|
-
], lineOptions);
|
|
2446
|
-
const line5 = createArrowLineElement(ArrowLineShape.elbow, [
|
|
2447
|
-
[0, 0],
|
|
2448
|
-
[0, 0]
|
|
2449
|
-
], { marker: ArrowLineMarkerType.none, connection: [0.5, 1], boundId: processElement2.id }, { marker: ArrowLineMarkerType.arrow, connection: [1, 0.5], boundId: endElement.id }, [], lineOptions);
|
|
2450
|
-
return [startElement, processElement1, decisionElement, processElement2, endElement, line1, line2, line3, line4, line5];
|
|
2451
|
-
};
|
|
2452
|
-
const getAutoCompletePoints = (element) => {
|
|
2402
|
+
const getAutoCompletePoints = (board, element, isToActive = false) => {
|
|
2453
2403
|
const AutoCompleteMargin = (12 + RESIZE_HANDLE_DIAMETER / 2) * 2;
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2404
|
+
const rectangle = RectangleClient.getRectangleByPoints(element.points);
|
|
2405
|
+
const activeRectangle = toActiveRectangleFromViewBoxRectangle(board, rectangle);
|
|
2406
|
+
const targetRectangle = isToActive ? activeRectangle : rectangle;
|
|
2407
|
+
return RectangleClient.getEdgeCenterPoints(RectangleClient.inflate(targetRectangle, AutoCompleteMargin));
|
|
2457
2408
|
};
|
|
2458
2409
|
const getHitIndexOfAutoCompletePoint = (movingPoint, points) => {
|
|
2459
2410
|
return points.findIndex((point) => {
|
|
@@ -2469,7 +2420,7 @@ const getDrawDefaultStrokeColor = (theme) => {
|
|
|
2469
2420
|
const getFlowchartDefaultFill = (theme) => {
|
|
2470
2421
|
return DrawThemeColors[theme].fill;
|
|
2471
2422
|
};
|
|
2472
|
-
const getTextShapeProperty = (board, text
|
|
2423
|
+
const getTextShapeProperty = (board, text, fontSize) => {
|
|
2473
2424
|
fontSize = fontSize ? Number(fontSize) : DEFAULT_FONT_SIZE;
|
|
2474
2425
|
const textSize = measureElement(buildText(text), { fontSize, fontFamily: DEFAULT_FONT_FAMILY });
|
|
2475
2426
|
return {
|
|
@@ -2498,7 +2449,7 @@ const getDefaultTextPoints = (board, centerPoint, fontSize) => {
|
|
|
2498
2449
|
const property = getTextShapeProperty(board, DefaultTextProperty.text, fontSize);
|
|
2499
2450
|
return RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(centerPoint, property.width, property.height));
|
|
2500
2451
|
};
|
|
2501
|
-
const createTextElement = (board, points, text
|
|
2452
|
+
const createTextElement = (board, points, text, textHeight) => {
|
|
2502
2453
|
const memorizedLatest = getMemorizedLatestByPointer(BasicShapes.text);
|
|
2503
2454
|
textHeight = textHeight ? textHeight : RectangleClient.getRectangleByPoints(points).height;
|
|
2504
2455
|
return createGeometryElement(BasicShapes.text, points, text, memorizedLatest.geometryProperties, {
|
|
@@ -2531,12 +2482,6 @@ const editText = (board, element, text) => {
|
|
|
2531
2482
|
textManage.edit(() => { });
|
|
2532
2483
|
}
|
|
2533
2484
|
};
|
|
2534
|
-
const rerenderGeometryActive = (board, element) => {
|
|
2535
|
-
const elementRef = PlaitElement.getElementRef(element);
|
|
2536
|
-
const activeGenerator = elementRef.getGenerator(ActiveGenerator.key);
|
|
2537
|
-
const selected = getSelectedElements(board).includes(element);
|
|
2538
|
-
activeGenerator.processDrawing(element, PlaitBoard.getElementActiveHost(board), { selected });
|
|
2539
|
-
};
|
|
2540
2485
|
const isGeometryIncludeText = (element) => {
|
|
2541
2486
|
return isSingleTextGeometry(element) || isMultipleTextGeometry(element);
|
|
2542
2487
|
};
|
|
@@ -3392,7 +3337,7 @@ function withDrawResize(board) {
|
|
|
3392
3337
|
const resizeSnapRef = getSnapResizingRef(board, resizeRef.element, resizeSnapRefOptions);
|
|
3393
3338
|
resizeActivePoints = resizeSnapRef.activePoints;
|
|
3394
3339
|
snapG = resizeSnapRef.snapG;
|
|
3395
|
-
PlaitBoard.
|
|
3340
|
+
PlaitBoard.getElementTopHost(board).append(snapG);
|
|
3396
3341
|
if (bulkRotationRef) {
|
|
3397
3342
|
const boundingBoxCornerPoints = RectangleClient.getPoints(resizeRef.rectangle);
|
|
3398
3343
|
const resizedBoundingBoxCornerPoints = boundingBoxCornerPoints.map((p) => {
|
|
@@ -3485,29 +3430,17 @@ function withDrawResize(board) {
|
|
|
3485
3430
|
handleG.remove();
|
|
3486
3431
|
handleG = null;
|
|
3487
3432
|
}
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
? RectangleClient.getRectangleByPoints(resizeActivePoints)
|
|
3493
|
-
: getRectangleByElements(board, elements, false);
|
|
3494
|
-
let corners = RectangleClient.getCornerPoints(boundingRectangle);
|
|
3495
|
-
const angle = getSelectionAngle(elements);
|
|
3496
|
-
if (angle) {
|
|
3497
|
-
const centerPoint = RectangleClient.getCenterPoint(boundingRectangle);
|
|
3498
|
-
corners = rotatePoints(corners, centerPoint, angle);
|
|
3499
|
-
}
|
|
3500
|
-
corners.forEach((corner) => {
|
|
3501
|
-
const g = drawHandle(board, corner);
|
|
3502
|
-
handleG && handleG.append(g);
|
|
3503
|
-
});
|
|
3504
|
-
PlaitBoard.getElementActiveHost(board).append(handleG);
|
|
3433
|
+
const selectedElements = getSelectedElements(board);
|
|
3434
|
+
if (canResize() && !isSelectionMoving(board) && selectedElements.length > 1) {
|
|
3435
|
+
handleG = generatorResizeHandles(board, resizeActivePoints, needCustomActiveRectangle);
|
|
3436
|
+
PlaitBoard.getActiveHost(board).append(handleG);
|
|
3505
3437
|
}
|
|
3506
3438
|
};
|
|
3507
3439
|
board.drawSelectionRectangle = () => {
|
|
3508
3440
|
if (needCustomActiveRectangle) {
|
|
3509
3441
|
const rectangle = RectangleClient.getRectangleByPoints(resizeActivePoints);
|
|
3510
|
-
|
|
3442
|
+
const activeRectangle = toActiveRectangleFromViewBoxRectangle(board, rectangle);
|
|
3443
|
+
return drawRectangle(board, RectangleClient.inflate(activeRectangle, ACTIVE_STROKE_WIDTH), {
|
|
3511
3444
|
stroke: SELECTION_BORDER_COLOR,
|
|
3512
3445
|
strokeWidth: ACTIVE_STROKE_WIDTH
|
|
3513
3446
|
});
|
|
@@ -3585,6 +3518,25 @@ const getResizePointsByOtherwiseAxis = (board, points, resizeOriginPoint, xZoom,
|
|
|
3585
3518
|
const newRectangle = RectangleClient.getRectangleByPoints(resultPoints);
|
|
3586
3519
|
return rotatePoints(resultPoints, RectangleClient.getCenterPoint(newRectangle), -(1 / 2) * Math.PI);
|
|
3587
3520
|
};
|
|
3521
|
+
const generatorResizeHandles = (board, resizeActivePoints, needCustomActiveRectangle) => {
|
|
3522
|
+
const handleG = createG();
|
|
3523
|
+
const elements = getSelectedElements(board);
|
|
3524
|
+
const boundingRectangle = needCustomActiveRectangle
|
|
3525
|
+
? RectangleClient.getRectangleByPoints(resizeActivePoints)
|
|
3526
|
+
: getRectangleByElements(board, elements, false);
|
|
3527
|
+
const boundingActiveRectangle = toActiveRectangleFromViewBoxRectangle(board, boundingRectangle);
|
|
3528
|
+
let corners = RectangleClient.getCornerPoints(boundingActiveRectangle);
|
|
3529
|
+
const angle = getSelectionAngle(elements);
|
|
3530
|
+
if (angle) {
|
|
3531
|
+
const centerPoint = RectangleClient.getCenterPoint(boundingActiveRectangle);
|
|
3532
|
+
corners = rotatePoints(corners, centerPoint, angle);
|
|
3533
|
+
}
|
|
3534
|
+
corners.forEach((corner) => {
|
|
3535
|
+
const g = drawHandle(board, corner);
|
|
3536
|
+
handleG.append(g);
|
|
3537
|
+
});
|
|
3538
|
+
return handleG;
|
|
3539
|
+
};
|
|
3588
3540
|
|
|
3589
3541
|
const debugKey$1 = 'debug:plait:point-for-geometry';
|
|
3590
3542
|
const debugGenerator$1 = createDebugGenerator(debugKey$1);
|
|
@@ -7094,7 +7046,7 @@ class GeometryShapeGenerator extends Generator {
|
|
|
7094
7046
|
class ArrowLineAutoCompleteGenerator extends Generator {
|
|
7095
7047
|
static { this.key = 'line-auto-complete-generator'; }
|
|
7096
7048
|
constructor(board) {
|
|
7097
|
-
super(board);
|
|
7049
|
+
super(board, { active: true });
|
|
7098
7050
|
this.board = board;
|
|
7099
7051
|
this.hoverElement = null;
|
|
7100
7052
|
}
|
|
@@ -7109,7 +7061,7 @@ class ArrowLineAutoCompleteGenerator extends Generator {
|
|
|
7109
7061
|
}
|
|
7110
7062
|
draw(element, data) {
|
|
7111
7063
|
this.autoCompleteG = createG();
|
|
7112
|
-
const middlePoints = getAutoCompletePoints(element);
|
|
7064
|
+
const middlePoints = getAutoCompletePoints(this.board, element, true);
|
|
7113
7065
|
middlePoints.forEach((point, index) => {
|
|
7114
7066
|
const circle = drawCircle(PlaitBoard.getRoughSVG(this.board), point, LINE_AUTO_COMPLETE_DIAMETER, {
|
|
7115
7067
|
stroke: 'none',
|
|
@@ -7152,7 +7104,7 @@ class GeometryComponent extends CommonElementFlavour {
|
|
|
7152
7104
|
super();
|
|
7153
7105
|
}
|
|
7154
7106
|
initializeGenerator() {
|
|
7155
|
-
this.activeGenerator =
|
|
7107
|
+
this.activeGenerator = createActiveGenerator(this.board, {
|
|
7156
7108
|
getStrokeWidth: () => {
|
|
7157
7109
|
const selectedElements = getSelectedElements(this.board);
|
|
7158
7110
|
if (selectedElements.length === 1 && !isSelectionMoving(this.board)) {
|
|
@@ -7185,15 +7137,23 @@ class GeometryComponent extends CommonElementFlavour {
|
|
|
7185
7137
|
}
|
|
7186
7138
|
this.getRef().addGenerator(ArrowLineAutoCompleteGenerator.key, this.lineAutoCompleteGenerator);
|
|
7187
7139
|
this.getRef().addGenerator(ActiveGenerator.key, this.activeGenerator);
|
|
7140
|
+
this.getRef().updateActiveSection = () => {
|
|
7141
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7142
|
+
selected: this.selected
|
|
7143
|
+
});
|
|
7144
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7145
|
+
selected: this.selected
|
|
7146
|
+
});
|
|
7147
|
+
};
|
|
7188
7148
|
}
|
|
7189
7149
|
initialize() {
|
|
7190
7150
|
super.initialize();
|
|
7191
7151
|
this.initializeGenerator();
|
|
7192
7152
|
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
7193
|
-
this.activeGenerator.processDrawing(this.element, PlaitBoard.
|
|
7153
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7194
7154
|
selected: this.selected
|
|
7195
7155
|
});
|
|
7196
|
-
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.
|
|
7156
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementTopHost(this.board), {
|
|
7197
7157
|
selected: this.selected
|
|
7198
7158
|
});
|
|
7199
7159
|
this.textGenerator && this.textGenerator.draw(this.getElementG());
|
|
@@ -7201,18 +7161,19 @@ class GeometryComponent extends CommonElementFlavour {
|
|
|
7201
7161
|
onContextChanged(value, previous) {
|
|
7202
7162
|
if (value.element !== previous.element || value.hasThemeChanged) {
|
|
7203
7163
|
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
7204
|
-
this.activeGenerator.processDrawing(this.element, PlaitBoard.
|
|
7205
|
-
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.
|
|
7164
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), { selected: this.selected });
|
|
7165
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7206
7166
|
selected: this.selected
|
|
7207
7167
|
});
|
|
7208
7168
|
this.textGenerator && this.updateText(previous.element, value.element);
|
|
7209
7169
|
}
|
|
7210
7170
|
else {
|
|
7211
7171
|
const hasSameSelected = value.selected === previous.selected;
|
|
7212
|
-
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7172
|
+
if (!hasSameSelected || value.selected) {
|
|
7173
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7174
|
+
selected: this.selected
|
|
7175
|
+
});
|
|
7176
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7216
7177
|
selected: this.selected
|
|
7217
7178
|
});
|
|
7218
7179
|
}
|
|
@@ -7321,8 +7282,9 @@ function getHitPointIndex(points, movingPoint) {
|
|
|
7321
7282
|
}
|
|
7322
7283
|
|
|
7323
7284
|
class LineActiveGenerator extends Generator {
|
|
7324
|
-
constructor() {
|
|
7325
|
-
super(
|
|
7285
|
+
constructor(board, options = { active: true }) {
|
|
7286
|
+
super(board, options);
|
|
7287
|
+
this.board = board;
|
|
7326
7288
|
this.onlySelectedCurrentLine = false;
|
|
7327
7289
|
}
|
|
7328
7290
|
canDraw(element, data) {
|
|
@@ -7346,16 +7308,18 @@ class LineActiveGenerator extends Generator {
|
|
|
7346
7308
|
updatePoints = points.slice(0, 1).concat(points.slice(-1));
|
|
7347
7309
|
elbowNextRenderPoints = getNextRenderPoints(this.board, element, data.linePoints);
|
|
7348
7310
|
}
|
|
7349
|
-
updatePoints.
|
|
7311
|
+
const activePoints = updatePoints.map((point) => toActivePointFromViewBoxPoint(this.board, point));
|
|
7312
|
+
activePoints.forEach((point) => {
|
|
7350
7313
|
const updateHandle = drawPrimaryHandle(this.board, point);
|
|
7351
7314
|
activeG.appendChild(updateHandle);
|
|
7352
7315
|
});
|
|
7353
7316
|
const middlePoints = getMiddlePoints(this.board, element);
|
|
7317
|
+
const activeMiddlePoints = middlePoints.map((point) => toActivePointFromViewBoxPoint(this.board, point));
|
|
7354
7318
|
if (!PlaitBoard.hasBeenTextEditing(this.board)) {
|
|
7355
|
-
for (let i = 0; i <
|
|
7356
|
-
const point =
|
|
7319
|
+
for (let i = 0; i < activeMiddlePoints.length; i++) {
|
|
7320
|
+
const point = activeMiddlePoints[i];
|
|
7357
7321
|
if (element.shape === ArrowLineShape.elbow && elbowNextRenderPoints.length) {
|
|
7358
|
-
const handleIndex = getHitPointIndex(
|
|
7322
|
+
const handleIndex = getHitPointIndex(activeMiddlePoints, point);
|
|
7359
7323
|
const isUpdateHandleIndex = isUpdatedHandleIndex(this.board, element, [...points], elbowNextRenderPoints, handleIndex);
|
|
7360
7324
|
if (isUpdateHandleIndex) {
|
|
7361
7325
|
const updateHandle = drawPrimaryHandle(this.board, point);
|
|
@@ -7369,8 +7333,9 @@ class LineActiveGenerator extends Generator {
|
|
|
7369
7333
|
}
|
|
7370
7334
|
}
|
|
7371
7335
|
else {
|
|
7372
|
-
const
|
|
7373
|
-
if (
|
|
7336
|
+
const rectangle = this.board.getRectangle(element);
|
|
7337
|
+
if (rectangle) {
|
|
7338
|
+
const activeRectangle = toActiveRectangleFromViewBoxRectangle(this.board, rectangle);
|
|
7374
7339
|
let opacity = '0.5';
|
|
7375
7340
|
if (activeRectangle.height === 0 || activeRectangle.width === 0) {
|
|
7376
7341
|
opacity = '0.8';
|
|
@@ -7408,13 +7373,20 @@ class ArrowLineComponent extends CommonElementFlavour {
|
|
|
7408
7373
|
this.initializeGenerator();
|
|
7409
7374
|
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
7410
7375
|
const linePoints = getArrowLinePoints(this.board, this.element);
|
|
7411
|
-
this.activeGenerator.processDrawing(this.element, PlaitBoard.
|
|
7376
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7412
7377
|
selected: this.selected,
|
|
7413
7378
|
linePoints
|
|
7414
7379
|
});
|
|
7415
7380
|
super.initialize();
|
|
7416
7381
|
this.boundedElements = this.getBoundedElements();
|
|
7417
7382
|
this.drawText();
|
|
7383
|
+
this.getRef().updateActiveSection = () => {
|
|
7384
|
+
const linePoints = getArrowLinePoints(this.board, this.element);
|
|
7385
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7386
|
+
selected: this.selected,
|
|
7387
|
+
linePoints
|
|
7388
|
+
});
|
|
7389
|
+
};
|
|
7418
7390
|
debugGenerator.isDebug() && debugGenerator.drawCircles(this.board, this.element.points.slice(1, -1), 4, true);
|
|
7419
7391
|
}
|
|
7420
7392
|
getBoundedElements() {
|
|
@@ -7440,7 +7412,7 @@ class ArrowLineComponent extends CommonElementFlavour {
|
|
|
7440
7412
|
const linePoints = getArrowLinePoints(this.board, this.element);
|
|
7441
7413
|
if (value.element !== previous.element || value.hasThemeChanged) {
|
|
7442
7414
|
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
7443
|
-
this.activeGenerator.processDrawing(this.element, PlaitBoard.
|
|
7415
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7444
7416
|
selected: this.selected,
|
|
7445
7417
|
linePoints
|
|
7446
7418
|
});
|
|
@@ -7449,8 +7421,8 @@ class ArrowLineComponent extends CommonElementFlavour {
|
|
|
7449
7421
|
}
|
|
7450
7422
|
else {
|
|
7451
7423
|
const needUpdate = value.selected !== previous.selected || this.activeGenerator.needUpdate();
|
|
7452
|
-
if (needUpdate) {
|
|
7453
|
-
this.activeGenerator.processDrawing(this.element, PlaitBoard.
|
|
7424
|
+
if (needUpdate || value.selected) {
|
|
7425
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7454
7426
|
selected: this.selected,
|
|
7455
7427
|
linePoints
|
|
7456
7428
|
});
|
|
@@ -7458,7 +7430,7 @@ class ArrowLineComponent extends CommonElementFlavour {
|
|
|
7458
7430
|
}
|
|
7459
7431
|
if (isBoundedElementsChanged) {
|
|
7460
7432
|
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
7461
|
-
this.activeGenerator.processDrawing(this.element, PlaitBoard.
|
|
7433
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7462
7434
|
selected: this.selected,
|
|
7463
7435
|
linePoints
|
|
7464
7436
|
});
|
|
@@ -7530,7 +7502,7 @@ class ArrowLineComponent extends CommonElementFlavour {
|
|
|
7530
7502
|
}
|
|
7531
7503
|
updateTextRectangle() {
|
|
7532
7504
|
const textManages = this.getRef().getTextManages();
|
|
7533
|
-
textManages.forEach(manage => {
|
|
7505
|
+
textManages.forEach((manage) => {
|
|
7534
7506
|
manage.updateRectangle();
|
|
7535
7507
|
});
|
|
7536
7508
|
}
|
|
@@ -7548,12 +7520,19 @@ class VectorLineComponent extends CommonElementFlavour {
|
|
|
7548
7520
|
initializeGenerator() {
|
|
7549
7521
|
this.shapeGenerator = new VectorLineShapeGenerator(this.board);
|
|
7550
7522
|
this.activeGenerator = new LineActiveGenerator(this.board);
|
|
7523
|
+
this.getRef().updateActiveSection = () => {
|
|
7524
|
+
const linePoints = getVectorLinePoints(this.board, this.element);
|
|
7525
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7526
|
+
selected: this.selected,
|
|
7527
|
+
linePoints
|
|
7528
|
+
});
|
|
7529
|
+
};
|
|
7551
7530
|
}
|
|
7552
7531
|
initialize() {
|
|
7553
7532
|
this.initializeGenerator();
|
|
7554
7533
|
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
7555
7534
|
const linePoints = getVectorLinePoints(this.board, this.element);
|
|
7556
|
-
this.activeGenerator.processDrawing(this.element, PlaitBoard.
|
|
7535
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7557
7536
|
selected: this.selected,
|
|
7558
7537
|
linePoints
|
|
7559
7538
|
});
|
|
@@ -7563,15 +7542,15 @@ class VectorLineComponent extends CommonElementFlavour {
|
|
|
7563
7542
|
const linePoints = getVectorLinePoints(this.board, this.element);
|
|
7564
7543
|
if (value.element !== previous.element || value.hasThemeChanged) {
|
|
7565
7544
|
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
7566
|
-
this.activeGenerator.processDrawing(this.element, PlaitBoard.
|
|
7545
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7567
7546
|
selected: this.selected,
|
|
7568
7547
|
linePoints
|
|
7569
7548
|
});
|
|
7570
7549
|
}
|
|
7571
7550
|
else {
|
|
7572
|
-
const needUpdate = value.selected !== previous.selected || this.activeGenerator.needUpdate();
|
|
7551
|
+
const needUpdate = value.selected !== previous.selected || this.activeGenerator.needUpdate() || value.selected;
|
|
7573
7552
|
if (needUpdate) {
|
|
7574
|
-
this.activeGenerator.processDrawing(this.element, PlaitBoard.
|
|
7553
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
7575
7554
|
selected: this.selected,
|
|
7576
7555
|
linePoints
|
|
7577
7556
|
});
|
|
@@ -7681,9 +7660,9 @@ const withGeometryCreateByDrag = (board) => {
|
|
|
7681
7660
|
if (dragMode) {
|
|
7682
7661
|
const memorizedLatest = getMemorizedLatestByPointer(pointer);
|
|
7683
7662
|
if (pointer === BasicShapes.text) {
|
|
7684
|
-
const property = getTextShapeProperty(board,
|
|
7663
|
+
const property = getTextShapeProperty(board, getDefaultGeometryText(board), memorizedLatest.textProperties['font-size']);
|
|
7685
7664
|
const points = RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(movingPoint, property.width, property.height));
|
|
7686
|
-
temporaryElement = createTextElement(board, points);
|
|
7665
|
+
temporaryElement = createTextElement(board, points, getDefaultGeometryText(board));
|
|
7687
7666
|
if (!fakeCreateTextRef) {
|
|
7688
7667
|
const textManage = new TextManage(board, {
|
|
7689
7668
|
getRectangle: () => {
|
|
@@ -7707,7 +7686,7 @@ const withGeometryCreateByDrag = (board) => {
|
|
|
7707
7686
|
const points = getDefaultGeometryPoints(pointer, movingPoint);
|
|
7708
7687
|
temporaryElement = createDefaultGeometry(board, points, pointer);
|
|
7709
7688
|
geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
|
|
7710
|
-
PlaitBoard.
|
|
7689
|
+
PlaitBoard.getElementTopHost(board).append(geometryShapeG);
|
|
7711
7690
|
}
|
|
7712
7691
|
}
|
|
7713
7692
|
pointerMove(event);
|
|
@@ -7754,9 +7733,9 @@ const withGeometryCreateByDrawing = (board) => {
|
|
|
7754
7733
|
const pointer = PlaitBoard.getPointer(board);
|
|
7755
7734
|
if (pointer === BasicShapes.text) {
|
|
7756
7735
|
const memorizedLatest = getMemorizedLatestByPointer(pointer);
|
|
7757
|
-
const property = getTextShapeProperty(board,
|
|
7736
|
+
const property = getTextShapeProperty(board, getDefaultGeometryText(board), memorizedLatest.textProperties['font-size']);
|
|
7758
7737
|
const points = RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(point, property.width, property.height));
|
|
7759
|
-
const textElement = createTextElement(board, points);
|
|
7738
|
+
const textElement = createTextElement(board, points, getDefaultGeometryText(board));
|
|
7760
7739
|
insertElement(board, textElement);
|
|
7761
7740
|
start = null;
|
|
7762
7741
|
}
|
|
@@ -7783,11 +7762,11 @@ const withGeometryCreateByDrawing = (board) => {
|
|
|
7783
7762
|
isCreate: true
|
|
7784
7763
|
});
|
|
7785
7764
|
snapG = resizeSnapRef.snapG;
|
|
7786
|
-
PlaitBoard.
|
|
7765
|
+
PlaitBoard.getElementTopHost(board).append(snapG);
|
|
7787
7766
|
points = normalizeShapePoints(resizeSnapRef.activePoints, isShift);
|
|
7788
7767
|
temporaryElement = createDefaultGeometry(board, points, pointer);
|
|
7789
7768
|
geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
|
|
7790
|
-
PlaitBoard.
|
|
7769
|
+
PlaitBoard.getElementTopHost(board).append(geometryShapeG);
|
|
7791
7770
|
}
|
|
7792
7771
|
pointerMove(event);
|
|
7793
7772
|
};
|
|
@@ -8112,7 +8091,7 @@ const withArrowLineBoundReaction = (board) => {
|
|
|
8112
8091
|
const linePointers = Object.keys(ArrowLineShape);
|
|
8113
8092
|
const isLinePointer = PlaitBoard.isInPointer(board, linePointers);
|
|
8114
8093
|
const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
8115
|
-
const isLineResizing = isResizingByCondition(board, resizeRef => {
|
|
8094
|
+
const isLineResizing = isResizingByCondition(board, (resizeRef) => {
|
|
8116
8095
|
const { element, handle } = resizeRef;
|
|
8117
8096
|
const isSourceOrTarget = handle === LineResizeHandle.target || handle === LineResizeHandle.source;
|
|
8118
8097
|
return PlaitDrawElement.isArrowLine(element) && isSourceOrTarget;
|
|
@@ -8135,12 +8114,12 @@ const withArrowLineBoundReaction = (board) => {
|
|
|
8135
8114
|
if (hasValidAngle(hitElement)) {
|
|
8136
8115
|
setAngleForG(boundShapeG, RectangleClient.getCenterPointByPoints(hitElement.points), hitElement.angle);
|
|
8137
8116
|
}
|
|
8138
|
-
PlaitBoard.
|
|
8117
|
+
PlaitBoard.getElementTopHost(board).append(boundShapeG);
|
|
8139
8118
|
}
|
|
8140
8119
|
}
|
|
8141
8120
|
pointerMove(event);
|
|
8142
8121
|
};
|
|
8143
|
-
board.pointerUp = event => {
|
|
8122
|
+
board.pointerUp = (event) => {
|
|
8144
8123
|
boundShapeG?.remove();
|
|
8145
8124
|
boundShapeG = null;
|
|
8146
8125
|
pointerUp(event);
|
|
@@ -8148,6 +8127,9 @@ const withArrowLineBoundReaction = (board) => {
|
|
|
8148
8127
|
return board;
|
|
8149
8128
|
};
|
|
8150
8129
|
|
|
8130
|
+
const getDefaultLineText = (board) => {
|
|
8131
|
+
return getI18nValue(board, DrawI18nKey.lineText, LINE_TEXT);
|
|
8132
|
+
};
|
|
8151
8133
|
const withArrowLineText = (board) => {
|
|
8152
8134
|
const { dblClick } = board;
|
|
8153
8135
|
board.dblClick = (event) => {
|
|
@@ -8165,13 +8147,19 @@ const withArrowLineText = (board) => {
|
|
|
8165
8147
|
editHandle(board, hitTarget, textIndex);
|
|
8166
8148
|
}
|
|
8167
8149
|
else {
|
|
8168
|
-
const
|
|
8150
|
+
const defaultLineText = getDefaultLineText(board);
|
|
8169
8151
|
const textMemory = getMemorizedLatest('arrow-line')?.text || {};
|
|
8152
|
+
const textElement = buildText(defaultLineText, undefined, textMemory);
|
|
8153
|
+
const { width, height } = measureElement(textElement, {
|
|
8154
|
+
fontSize: DEFAULT_FONT_SIZE,
|
|
8155
|
+
fontFamily: DEFAULT_FONT_FAMILY
|
|
8156
|
+
});
|
|
8157
|
+
const ratio = getRatioByPoint(points, point);
|
|
8170
8158
|
texts.push({
|
|
8171
|
-
text:
|
|
8159
|
+
text: textElement,
|
|
8172
8160
|
position: ratio,
|
|
8173
|
-
width
|
|
8174
|
-
height
|
|
8161
|
+
width,
|
|
8162
|
+
height
|
|
8175
8163
|
});
|
|
8176
8164
|
DrawTransforms.setArrowLineTexts(board, hitTarget, texts);
|
|
8177
8165
|
setTimeout(() => {
|
|
@@ -8193,7 +8181,8 @@ function editHandle(board, element, manageIndex, isFirstEdit = false) {
|
|
|
8193
8181
|
const textManage = textManages[manageIndex];
|
|
8194
8182
|
textManage.edit(() => {
|
|
8195
8183
|
const text = Node.string(textManage.getText());
|
|
8196
|
-
const
|
|
8184
|
+
const defaultLineText = getDefaultLineText(board);
|
|
8185
|
+
const shouldRemove = !text || (isFirstEdit && text === defaultLineText);
|
|
8197
8186
|
if (shouldRemove) {
|
|
8198
8187
|
DrawTransforms.removeArrowLineText(board, element, manageIndex);
|
|
8199
8188
|
}
|
|
@@ -8214,7 +8203,7 @@ class ImageComponent extends CommonElementFlavour {
|
|
|
8214
8203
|
height: element.points[1][1] - element.points[0][1]
|
|
8215
8204
|
};
|
|
8216
8205
|
},
|
|
8217
|
-
getImageItem: element => {
|
|
8206
|
+
getImageItem: (element) => {
|
|
8218
8207
|
return {
|
|
8219
8208
|
url: element.url,
|
|
8220
8209
|
width: element.points[1][0] - element.points[0][0],
|
|
@@ -8224,12 +8213,18 @@ class ImageComponent extends CommonElementFlavour {
|
|
|
8224
8213
|
});
|
|
8225
8214
|
this.lineAutoCompleteGenerator = new ArrowLineAutoCompleteGenerator(this.board);
|
|
8226
8215
|
this.getRef().addGenerator(ArrowLineAutoCompleteGenerator.key, this.lineAutoCompleteGenerator);
|
|
8216
|
+
this.getRef().updateActiveSection = () => {
|
|
8217
|
+
this.imageGenerator.setFocus(this.element, this.selected);
|
|
8218
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
8219
|
+
selected: this.selected
|
|
8220
|
+
});
|
|
8221
|
+
};
|
|
8227
8222
|
}
|
|
8228
8223
|
initialize() {
|
|
8229
8224
|
super.initialize();
|
|
8230
8225
|
this.initializeGenerator();
|
|
8231
8226
|
this.imageGenerator.processDrawing(this.element, this.getElementG());
|
|
8232
|
-
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.
|
|
8227
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
8233
8228
|
selected: this.selected
|
|
8234
8229
|
});
|
|
8235
8230
|
}
|
|
@@ -8237,17 +8232,15 @@ class ImageComponent extends CommonElementFlavour {
|
|
|
8237
8232
|
if (value.element !== previous.element) {
|
|
8238
8233
|
this.imageGenerator.updateImage(this.getElementG(), previous.element, value.element);
|
|
8239
8234
|
this.imageGenerator.setFocus(this.element, this.selected);
|
|
8240
|
-
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.
|
|
8235
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
8241
8236
|
selected: this.selected
|
|
8242
8237
|
});
|
|
8243
8238
|
}
|
|
8244
8239
|
else {
|
|
8245
8240
|
const hasSameSelected = value.selected === previous.selected;
|
|
8246
|
-
|
|
8247
|
-
this.imageGenerator.activeGenerator.options.hasResizeHandle() === this.imageGenerator.activeGenerator.hasResizeHandle;
|
|
8248
|
-
if (!hasSameSelected || !hasSameHandleState) {
|
|
8241
|
+
if (!hasSameSelected || value.selected) {
|
|
8249
8242
|
this.imageGenerator.setFocus(this.element, this.selected);
|
|
8250
|
-
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.
|
|
8243
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
8251
8244
|
selected: this.selected
|
|
8252
8245
|
});
|
|
8253
8246
|
}
|
|
@@ -8268,10 +8261,10 @@ const withArrowLineAutoCompleteReaction = (board) => {
|
|
|
8268
8261
|
PlaitBoard.getBoardContainer(board).classList.remove(CursorClass.crosshair);
|
|
8269
8262
|
const selectedElements = getSelectedDrawElements(board);
|
|
8270
8263
|
const targetElement = selectedElements.length === 1 && selectedElements[0];
|
|
8271
|
-
const
|
|
8264
|
+
const activePoint = toActivePoint(board, event.x, event.y);
|
|
8272
8265
|
if (!PlaitBoard.isReadonly(board) && !isSelectionMoving(board) && targetElement && PlaitDrawElement.isShapeElement(targetElement)) {
|
|
8273
|
-
const points = getAutoCompletePoints(targetElement);
|
|
8274
|
-
const hitIndex = getHitIndexOfAutoCompletePoint(rotateAntiPointsByElement(
|
|
8266
|
+
const points = getAutoCompletePoints(board, targetElement, true);
|
|
8267
|
+
const hitIndex = getHitIndexOfAutoCompletePoint(rotateAntiPointsByElement(board, activePoint, targetElement, true) || activePoint, points);
|
|
8275
8268
|
const hitPoint = points[hitIndex];
|
|
8276
8269
|
const ref = PlaitElement.getElementRef(targetElement);
|
|
8277
8270
|
const lineAutoCompleteGenerator = ref.getGenerator(ArrowLineAutoCompleteGenerator.key);
|
|
@@ -8283,10 +8276,12 @@ const withArrowLineAutoCompleteReaction = (board) => {
|
|
|
8283
8276
|
fill: RgbaToHEX(PRIMARY_COLOR, LINE_AUTO_COMPLETE_HOVERED_OPACITY),
|
|
8284
8277
|
fillStyle: 'solid'
|
|
8285
8278
|
});
|
|
8286
|
-
PlaitBoard.
|
|
8279
|
+
PlaitBoard.getActiveHost(board).append(reactionG);
|
|
8287
8280
|
PlaitBoard.getBoardContainer(board).classList.add(CursorClass.crosshair);
|
|
8288
8281
|
if (hasValidAngle(targetElement)) {
|
|
8289
|
-
|
|
8282
|
+
const rectangle = board.getRectangle(targetElement);
|
|
8283
|
+
const activeRectangle = toActiveRectangleFromViewBoxRectangle(board, rectangle);
|
|
8284
|
+
setAngleForG(reactionG, RectangleClient.getCenterPoint(activeRectangle), targetElement.angle);
|
|
8290
8285
|
}
|
|
8291
8286
|
}
|
|
8292
8287
|
}
|
|
@@ -8305,14 +8300,15 @@ const withArrowLineAutoComplete = (board) => {
|
|
|
8305
8300
|
board.pointerDown = (event) => {
|
|
8306
8301
|
const selectedElements = getSelectedDrawElements(board);
|
|
8307
8302
|
const targetElement = selectedElements.length === 1 && selectedElements[0];
|
|
8308
|
-
const
|
|
8303
|
+
const activePoint = toActivePoint(board, event.x, event.y);
|
|
8309
8304
|
if (!PlaitBoard.isReadonly(board) && targetElement && PlaitDrawElement.isShapeElement(targetElement)) {
|
|
8310
|
-
const points = getAutoCompletePoints(targetElement);
|
|
8311
|
-
const index = getHitIndexOfAutoCompletePoint(rotateAntiPointsByElement(
|
|
8305
|
+
const points = getAutoCompletePoints(board, targetElement, true);
|
|
8306
|
+
const index = getHitIndexOfAutoCompletePoint(rotateAntiPointsByElement(board, activePoint, targetElement, true) || activePoint, points);
|
|
8312
8307
|
const hitPoint = points[index];
|
|
8313
8308
|
if (hitPoint) {
|
|
8314
8309
|
temporaryDisableSelection(board);
|
|
8315
|
-
|
|
8310
|
+
const screenPoint = toScreenPointFromActivePoint(board, hitPoint);
|
|
8311
|
+
autoCompletePoint = toViewBoxPoint(board, toHostPoint(board, screenPoint[0], screenPoint[1]));
|
|
8316
8312
|
sourceElement = targetElement;
|
|
8317
8313
|
BoardTransforms.updatePointerType(board, ArrowLineShape.elbow);
|
|
8318
8314
|
}
|
|
@@ -8324,7 +8320,7 @@ const withArrowLineAutoComplete = (board) => {
|
|
|
8324
8320
|
lineShapeG = createG();
|
|
8325
8321
|
let movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
8326
8322
|
if (autoCompletePoint && sourceElement) {
|
|
8327
|
-
const distance = distanceBetweenPointAndPoint(...(rotateAntiPointsByElement(movingPoint, sourceElement) || movingPoint), ...autoCompletePoint);
|
|
8323
|
+
const distance = distanceBetweenPointAndPoint(...(rotateAntiPointsByElement(board, movingPoint, sourceElement) || movingPoint), ...autoCompletePoint);
|
|
8328
8324
|
if (distance > PRESS_AND_MOVE_BUFFER) {
|
|
8329
8325
|
const rectangle = RectangleClient.getRectangleByPoints(sourceElement.points);
|
|
8330
8326
|
const shape = getElementShape(sourceElement);
|
|
@@ -8342,7 +8338,7 @@ const withArrowLineAutoComplete = (board) => {
|
|
|
8342
8338
|
}
|
|
8343
8339
|
pointerMove(event);
|
|
8344
8340
|
};
|
|
8345
|
-
board.globalPointerUp = event => {
|
|
8341
|
+
board.globalPointerUp = (event) => {
|
|
8346
8342
|
if (temporaryElement) {
|
|
8347
8343
|
Transforms.insertNode(board, temporaryElement, [board.children.length]);
|
|
8348
8344
|
clearSelectedElement(board);
|
|
@@ -8418,7 +8414,7 @@ const withDrawRotate = (board) => {
|
|
|
8418
8414
|
const canRotate = () => {
|
|
8419
8415
|
const elements = getSelectedElements(board);
|
|
8420
8416
|
return (elements.length > 0 &&
|
|
8421
|
-
elements.every(el => (PlaitDrawElement.isDrawElement(el) && !PlaitDrawElement.isArrowLine(el)) ||
|
|
8417
|
+
elements.every((el) => (PlaitDrawElement.isDrawElement(el) && !PlaitDrawElement.isArrowLine(el)) ||
|
|
8422
8418
|
PlaitDrawElement.isCustomGeometryElement(board, el)));
|
|
8423
8419
|
};
|
|
8424
8420
|
board.pointerDown = (event) => {
|
|
@@ -8426,16 +8422,17 @@ const withDrawRotate = (board) => {
|
|
|
8426
8422
|
pointerDown(event);
|
|
8427
8423
|
return;
|
|
8428
8424
|
}
|
|
8429
|
-
const
|
|
8425
|
+
const activePoint = toActivePoint(board, event.x, event.y);
|
|
8430
8426
|
const elements = getSelectedElements(board);
|
|
8431
|
-
const
|
|
8432
|
-
const
|
|
8427
|
+
const rectangle = getRectangleByElements(board, elements, false);
|
|
8428
|
+
const activeRectangle = toActiveRectangleFromViewBoxRectangle(board, rectangle);
|
|
8429
|
+
const handleRectangle = getRotateHandleRectangle(activeRectangle);
|
|
8433
8430
|
const angle = getSelectionAngle(elements);
|
|
8434
|
-
const rotatedPoint = angle ? rotatePoints(
|
|
8431
|
+
const rotatedPoint = angle ? rotatePoints(activePoint, RectangleClient.getCenterPoint(activeRectangle), -angle) : activePoint;
|
|
8435
8432
|
if (handleRectangle && RectangleClient.isHit(RectangleClient.getRectangleByPoints([rotatedPoint, rotatedPoint]), handleRectangle)) {
|
|
8436
8433
|
rotateRef = {
|
|
8437
8434
|
elements: [...elements],
|
|
8438
|
-
startPoint:
|
|
8435
|
+
startPoint: activePoint
|
|
8439
8436
|
};
|
|
8440
8437
|
}
|
|
8441
8438
|
pointerDown(event);
|
|
@@ -8445,9 +8442,10 @@ const withDrawRotate = (board) => {
|
|
|
8445
8442
|
event.preventDefault();
|
|
8446
8443
|
const isShift = !!event.shiftKey;
|
|
8447
8444
|
addRotating(board, rotateRef);
|
|
8448
|
-
const endPoint =
|
|
8449
|
-
const
|
|
8450
|
-
const
|
|
8445
|
+
const endPoint = toActivePoint(board, event.x, event.y);
|
|
8446
|
+
const rectangle = getRectangleByElements(board, rotateRef.elements, false);
|
|
8447
|
+
const activeRectangle = toActiveRectangleFromViewBoxRectangle(board, rectangle);
|
|
8448
|
+
const selectionCenterPoint = RectangleClient.getCenterPoint(activeRectangle);
|
|
8451
8449
|
if (!getSelectionAngle(rotateRef.elements) && rotateRef.elements.length > 1) {
|
|
8452
8450
|
needCustomActiveRectangle = true;
|
|
8453
8451
|
}
|
|
@@ -8499,32 +8497,35 @@ const withDrawRotate = (board) => {
|
|
|
8499
8497
|
if (canRotate() && !isSelectionMoving(board)) {
|
|
8500
8498
|
if (needCustomActiveRectangle && rotateRef) {
|
|
8501
8499
|
const boundingRectangle = getRectangleByElements(board, rotateRef.elements, false);
|
|
8502
|
-
|
|
8500
|
+
const boundingActiveRectangle = toActiveRectangleFromViewBoxRectangle(board, boundingRectangle);
|
|
8501
|
+
rotateHandleG = drawRotateHandle(board, boundingActiveRectangle);
|
|
8503
8502
|
rotateHandleG.classList.add(ROTATE_HANDLE_CLASS_NAME);
|
|
8504
8503
|
if (rotateRef.angle) {
|
|
8505
|
-
setAngleForG(rotateHandleG, RectangleClient.getCenterPoint(
|
|
8504
|
+
setAngleForG(rotateHandleG, RectangleClient.getCenterPoint(boundingActiveRectangle), rotateRef.angle);
|
|
8506
8505
|
}
|
|
8507
8506
|
}
|
|
8508
8507
|
else {
|
|
8509
8508
|
const elements = getSelectedElements(board);
|
|
8510
8509
|
const boundingRectangle = getRectangleByElements(board, elements, false);
|
|
8511
|
-
|
|
8510
|
+
const boundingActiveRectangle = toActiveRectangleFromViewBoxRectangle(board, boundingRectangle);
|
|
8511
|
+
rotateHandleG = drawRotateHandle(board, boundingActiveRectangle);
|
|
8512
8512
|
rotateHandleG.classList.add(ROTATE_HANDLE_CLASS_NAME);
|
|
8513
|
-
setAngleForG(rotateHandleG, RectangleClient.getCenterPoint(
|
|
8513
|
+
setAngleForG(rotateHandleG, RectangleClient.getCenterPoint(boundingActiveRectangle), getSelectionAngle(elements));
|
|
8514
8514
|
}
|
|
8515
|
-
PlaitBoard.
|
|
8515
|
+
PlaitBoard.getActiveHost(board).append(rotateHandleG);
|
|
8516
8516
|
}
|
|
8517
8517
|
};
|
|
8518
8518
|
board.drawSelectionRectangle = () => {
|
|
8519
8519
|
if (needCustomActiveRectangle && rotateRef) {
|
|
8520
8520
|
const rectangle = getRectangleByElements(board, rotateRef.elements, false);
|
|
8521
|
-
const
|
|
8521
|
+
const activeRectangle = toActiveRectangleFromViewBoxRectangle(board, rectangle);
|
|
8522
|
+
const rectangleG = drawRectangle(board, RectangleClient.inflate(activeRectangle, ACTIVE_STROKE_WIDTH), {
|
|
8522
8523
|
stroke: SELECTION_BORDER_COLOR,
|
|
8523
8524
|
strokeWidth: ACTIVE_STROKE_WIDTH
|
|
8524
8525
|
});
|
|
8525
8526
|
rectangleG.classList.add(SELECTION_RECTANGLE_CLASS_NAME);
|
|
8526
8527
|
if (rotateRef.angle) {
|
|
8527
|
-
setAngleForG(rectangleG, RectangleClient.getCenterPoint(
|
|
8528
|
+
setAngleForG(rectangleG, RectangleClient.getCenterPoint(activeRectangle), rotateRef.angle);
|
|
8528
8529
|
}
|
|
8529
8530
|
return rectangleG;
|
|
8530
8531
|
}
|
|
@@ -8538,7 +8539,7 @@ class TableComponent extends CommonElementFlavour {
|
|
|
8538
8539
|
super();
|
|
8539
8540
|
}
|
|
8540
8541
|
initializeGenerator() {
|
|
8541
|
-
this.activeGenerator =
|
|
8542
|
+
this.activeGenerator = createActiveGenerator(this.board, {
|
|
8542
8543
|
getStrokeWidth: () => {
|
|
8543
8544
|
return ACTIVE_STROKE_WIDTH;
|
|
8544
8545
|
},
|
|
@@ -8564,6 +8565,14 @@ class TableComponent extends CommonElementFlavour {
|
|
|
8564
8565
|
this.initializeTextManage();
|
|
8565
8566
|
this.lineAutoCompleteGenerator = new ArrowLineAutoCompleteGenerator(this.board);
|
|
8566
8567
|
this.getRef().addGenerator(ArrowLineAutoCompleteGenerator.key, this.lineAutoCompleteGenerator);
|
|
8568
|
+
this.getRef().updateActiveSection = () => {
|
|
8569
|
+
this.activeGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
8570
|
+
selected: this.selected
|
|
8571
|
+
});
|
|
8572
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
8573
|
+
selected: this.selected
|
|
8574
|
+
});
|
|
8575
|
+
};
|
|
8567
8576
|
}
|
|
8568
8577
|
initialize() {
|
|
8569
8578
|
super.initialize();
|
|
@@ -8574,13 +8583,13 @@ class TableComponent extends CommonElementFlavour {
|
|
|
8574
8583
|
this.tableGenerator.processDrawing(this.element, this.getElementG());
|
|
8575
8584
|
this.textGenerator.draw(this.getElementG());
|
|
8576
8585
|
this.rotateVerticalText();
|
|
8577
|
-
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.
|
|
8586
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
8578
8587
|
selected: this.selected
|
|
8579
8588
|
});
|
|
8580
8589
|
}
|
|
8581
8590
|
rotateVerticalText() {
|
|
8582
8591
|
const table = this.board.buildTable(this.element);
|
|
8583
|
-
table.cells.forEach(item => {
|
|
8592
|
+
table.cells.forEach((item) => {
|
|
8584
8593
|
if (PlaitTableElement.isVerticalText(item)) {
|
|
8585
8594
|
const textManage = getTextManageByCell(this.board, item);
|
|
8586
8595
|
if (textManage) {
|
|
@@ -8594,8 +8603,8 @@ class TableComponent extends CommonElementFlavour {
|
|
|
8594
8603
|
}
|
|
8595
8604
|
getDrawShapeTexts(cells) {
|
|
8596
8605
|
return cells
|
|
8597
|
-
.filter(item => isCellIncludeText(item))
|
|
8598
|
-
.map(item => {
|
|
8606
|
+
.filter((item) => isCellIncludeText(item))
|
|
8607
|
+
.map((item) => {
|
|
8599
8608
|
return {
|
|
8600
8609
|
id: item.id,
|
|
8601
8610
|
text: item.text,
|
|
@@ -8643,7 +8652,7 @@ class TableComponent extends CommonElementFlavour {
|
|
|
8643
8652
|
setSelectedCells(value.element, previousSelectedCells);
|
|
8644
8653
|
}
|
|
8645
8654
|
this.tableGenerator.processDrawing(value.element, this.getElementG());
|
|
8646
|
-
this.activeGenerator.processDrawing(value.element, PlaitBoard.
|
|
8655
|
+
this.activeGenerator.processDrawing(value.element, PlaitBoard.getActiveHost(this.board), { selected: this.selected });
|
|
8647
8656
|
const previousTexts = this.getDrawShapeTexts(previous.element.cells);
|
|
8648
8657
|
const currentTexts = this.getDrawShapeTexts(value.element.cells);
|
|
8649
8658
|
this.textGenerator.update(value.element, previousTexts, currentTexts, this.getElementG());
|
|
@@ -8651,10 +8660,9 @@ class TableComponent extends CommonElementFlavour {
|
|
|
8651
8660
|
}
|
|
8652
8661
|
else {
|
|
8653
8662
|
const hasSameSelected = value.selected === previous.selected;
|
|
8654
|
-
const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
|
|
8655
8663
|
const currentSelectedCells = getSelectedCells(value.element);
|
|
8656
|
-
if (!hasSameSelected ||
|
|
8657
|
-
this.activeGenerator.processDrawing(value.element, PlaitBoard.
|
|
8664
|
+
if (!hasSameSelected || currentSelectedCells?.length || value.selected) {
|
|
8665
|
+
this.activeGenerator.processDrawing(value.element, PlaitBoard.getActiveHost(this.board), {
|
|
8658
8666
|
selected: this.selected
|
|
8659
8667
|
});
|
|
8660
8668
|
}
|
|
@@ -8662,7 +8670,7 @@ class TableComponent extends CommonElementFlavour {
|
|
|
8662
8670
|
clearSelectedCells(value.element);
|
|
8663
8671
|
}
|
|
8664
8672
|
}
|
|
8665
|
-
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.
|
|
8673
|
+
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getActiveHost(this.board), {
|
|
8666
8674
|
selected: this.selected
|
|
8667
8675
|
});
|
|
8668
8676
|
}
|
|
@@ -8681,17 +8689,21 @@ function withTableResize(board) {
|
|
|
8681
8689
|
const options = {
|
|
8682
8690
|
key: 'draw-table',
|
|
8683
8691
|
canResize: () => {
|
|
8684
|
-
|
|
8692
|
+
const selectedElements = getSelectedElements(board);
|
|
8693
|
+
return isSingleSelectTable(board) && !hasValidAngle(selectedElements[0]);
|
|
8685
8694
|
},
|
|
8686
8695
|
hitTest: (point) => {
|
|
8687
|
-
const
|
|
8696
|
+
const selectedElements = getSelectedElements(board);
|
|
8697
|
+
const hitElement = selectedElements[0];
|
|
8698
|
+
// debugGenerator.clear();
|
|
8688
8699
|
if (hitElement && PlaitDrawElement.isElementByTable(hitElement)) {
|
|
8689
8700
|
let rectangle = board.getRectangle(hitElement);
|
|
8701
|
+
// debugGenerator.drawRectangle(board, rectangle);
|
|
8702
|
+
// debugGenerator.drawCircles(board, [point], 5);
|
|
8690
8703
|
let handleRef = getHitRectangleResizeHandleRef(board, rectangle, point, hitElement.angle);
|
|
8691
8704
|
if (handleRef) {
|
|
8692
8705
|
const selectElement = isSelectedElement(board, hitElement);
|
|
8693
|
-
if ((selectElement &&
|
|
8694
|
-
(!selectElement && !isCornerHandle(board, handleRef.handle))) {
|
|
8706
|
+
if ((selectElement && isSingleSelectTable(board)) || (!selectElement && !isCornerHandle(board, handleRef.handle))) {
|
|
8695
8707
|
return {
|
|
8696
8708
|
element: hitElement,
|
|
8697
8709
|
handle: handleRef.handle,
|
|
@@ -8728,7 +8740,7 @@ function withTableResize(board) {
|
|
|
8728
8740
|
const resizePoints = [resizeState.startPoint, resizeState.endPoint];
|
|
8729
8741
|
const { xZoom, yZoom } = getResizeZoom(resizePoints, originPoint, handlePoint, false, false);
|
|
8730
8742
|
const originPoints = resizeRef.options?.cell.points;
|
|
8731
|
-
const targetPoints = originPoints.map(p => {
|
|
8743
|
+
const targetPoints = originPoints.map((p) => {
|
|
8732
8744
|
return movePointByZoomAndOriginPoint(p, originPoint, xZoom, yZoom);
|
|
8733
8745
|
});
|
|
8734
8746
|
const offsetX = targetPoints[1][0] - originPoints[1][0];
|
|
@@ -8755,7 +8767,7 @@ function withTableResize(board) {
|
|
|
8755
8767
|
}, isAspectRatio, isFromCorner);
|
|
8756
8768
|
const resizeSnapRef = getSnapResizingRef(board, [resizeRef.element], resizeSnapRefOptions);
|
|
8757
8769
|
snapG = resizeSnapRef.snapG;
|
|
8758
|
-
PlaitBoard.
|
|
8770
|
+
PlaitBoard.getElementTopHost(board).append(snapG);
|
|
8759
8771
|
const points = resizeSnapRef.activePoints;
|
|
8760
8772
|
const originPoints = resizeRef.element.points;
|
|
8761
8773
|
const originRect = RectangleClient.getRectangleByPoints(originPoints);
|
|
@@ -8765,7 +8777,7 @@ function withTableResize(board) {
|
|
|
8765
8777
|
let columns = [...resizeRef.element.columns];
|
|
8766
8778
|
let rows = [...resizeRef.element.rows];
|
|
8767
8779
|
if (offsetWidth !== 0) {
|
|
8768
|
-
columns = columns.map(item => {
|
|
8780
|
+
columns = columns.map((item) => {
|
|
8769
8781
|
if (item.width) {
|
|
8770
8782
|
return {
|
|
8771
8783
|
...item,
|
|
@@ -8776,7 +8788,7 @@ function withTableResize(board) {
|
|
|
8776
8788
|
});
|
|
8777
8789
|
}
|
|
8778
8790
|
if (offsetHeight !== 0) {
|
|
8779
|
-
rows = rows.map(item => {
|
|
8791
|
+
rows = rows.map((item) => {
|
|
8780
8792
|
if (item.height) {
|
|
8781
8793
|
return {
|
|
8782
8794
|
...item,
|
|
@@ -8810,7 +8822,9 @@ const withTable = (board) => {
|
|
|
8810
8822
|
tableBoard.isHit = (element, point, isStrict) => {
|
|
8811
8823
|
if (PlaitDrawElement.isElementByTable(element)) {
|
|
8812
8824
|
const client = RectangleClient.getRectangleByPoints(element.points);
|
|
8813
|
-
|
|
8825
|
+
const nearestPoint = TableEngine.getNearestPoint(client, point);
|
|
8826
|
+
const distance = distanceBetweenPointAndPoint(nearestPoint[0], nearestPoint[1], point[0], point[1]);
|
|
8827
|
+
return distance <= HIT_DISTANCE_BUFFER || RectangleClient.isPointInRectangle(client, point);
|
|
8814
8828
|
}
|
|
8815
8829
|
return isHit(element, point, isStrict);
|
|
8816
8830
|
};
|
|
@@ -8847,9 +8861,9 @@ const withTable = (board) => {
|
|
|
8847
8861
|
event.preventDefault();
|
|
8848
8862
|
if (PlaitDrawElement.isElementByTable(targetElement)) {
|
|
8849
8863
|
const cells = getSelectedCells(targetElement);
|
|
8850
|
-
let cell = targetElement.cells.find(item => item.text && item.textHeight);
|
|
8864
|
+
let cell = targetElement.cells.find((item) => item.text && item.textHeight);
|
|
8851
8865
|
if (cells?.length) {
|
|
8852
|
-
cell = cells.find(item => item.text && item.textHeight);
|
|
8866
|
+
cell = cells.find((item) => item.text && item.textHeight);
|
|
8853
8867
|
}
|
|
8854
8868
|
if (cell) {
|
|
8855
8869
|
editCell(board, cell);
|
|
@@ -8922,7 +8936,7 @@ const withSwimlaneCreateByDrag = (board) => {
|
|
|
8922
8936
|
const points = getDefaultSwimlanePoints(pointer, movingPoint);
|
|
8923
8937
|
temporaryElement = createDefaultSwimlane(pointer, points);
|
|
8924
8938
|
tableGenerator.processDrawing(temporaryElement, swimlaneG);
|
|
8925
|
-
PlaitBoard.
|
|
8939
|
+
PlaitBoard.getElementTopHost(board).append(swimlaneG);
|
|
8926
8940
|
}
|
|
8927
8941
|
pointerMove(event);
|
|
8928
8942
|
};
|
|
@@ -8985,11 +8999,11 @@ const withSwimlaneCreateByDrawing = (board) => {
|
|
|
8985
8999
|
isCreate: true
|
|
8986
9000
|
});
|
|
8987
9001
|
snapG = resizeSnapRef.snapG;
|
|
8988
|
-
PlaitBoard.
|
|
9002
|
+
PlaitBoard.getElementTopHost(board).append(snapG);
|
|
8989
9003
|
points = normalizeShapePoints(resizeSnapRef.activePoints, isShift);
|
|
8990
9004
|
temporaryElement = createDefaultSwimlane(pointer, points);
|
|
8991
9005
|
tableGenerator.processDrawing(temporaryElement, swimlaneG);
|
|
8992
|
-
PlaitBoard.
|
|
9006
|
+
PlaitBoard.getElementTopHost(board).append(swimlaneG);
|
|
8993
9007
|
}
|
|
8994
9008
|
pointerMove(event);
|
|
8995
9009
|
};
|
|
@@ -9291,5 +9305,5 @@ const withDraw = (board) => {
|
|
|
9291
9305
|
* Generated bundle index. Do not edit.
|
|
9292
9306
|
*/
|
|
9293
9307
|
|
|
9294
|
-
export { ArrowLineAutoCompleteGenerator, ArrowLineComponent, ArrowLineHandleKey, ArrowLineMarkerType, ArrowLineShape, BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultActivationProperty, DefaultActorProperty, DefaultArrowProperty, DefaultAssemblyProperty, DefaultBasicShapeProperty, DefaultBasicShapePropertyMap, DefaultClassProperty, DefaultCloudProperty, DefaultCombinedFragmentProperty, DefaultComponentBoxProperty, DefaultConnectorProperty, DefaultContainerProperty, DefaultDataBaseProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultDeletionProperty, DefaultDocumentProperty, DefaultDrawActiveStyle, DefaultDrawStyle, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultInterfaceProperty, DefaultInternalStorageProperty, DefaultManualInputProperty, DefaultMergeProperty, DefaultMultiDocumentProperty, DefaultNoteProperty, DefaultObjectProperty, DefaultPackageProperty, DefaultPentagonArrowProperty, DefaultPortProperty, DefaultProvidedInterfaceProperty, DefaultRequiredInterfaceProperty, DefaultSwimlaneHorizontalProperty, DefaultSwimlaneHorizontalWithHeaderProperty, DefaultSwimlanePropertyMap, DefaultSwimlaneVerticalProperty, DefaultSwimlaneVerticalWithHeaderProperty, DefaultTextProperty, DefaultTwoWayArrowProperty, DefaultUMLPropertyMap, DrawThemeColors, DrawTransforms, FlowchartSymbols, GEOMETRY_NOT_CLOSED, GEOMETRY_WITHOUT_TEXT, GEOMETRY_WITH_MULTIPLE_TEXT, GeometryCommonTextKeys, GeometryComponent, GeometryShapeGenerator, GeometryThreshold, KEY_TO_TEXT_MANAGE, LINE_HIT_GEOMETRY_BUFFER, LINE_SNAPPING_BUFFER, LINE_SNAPPING_CONNECTOR_BUFFER, LineActiveGenerator, MIN_TEXT_WIDTH, MemorizeKey, MultipleTextGeometryTextKeys, PlaitArrowLine, PlaitDrawElement, PlaitGeometry, PlaitTableElement, Q2C, SELECTED_CELLS, SWIMLANE_HEADER_SIZE, ShapeDefaultSpace, SingleTextGenerator, SwimlaneDrawSymbols, SwimlaneSymbols, TableGenerator, TableSymbols, TextGenerator, UMLSymbols, VectorLineComponent, VectorLinePointerType, VectorLineShape, WithArrowLineAutoCompletePluginKey, WithDrawPluginKey, adjustSwimlaneShape, alignElbowSegment, alignPoints, buildClipboardData, buildDefaultTextsByShape, buildSwimlaneTable, clearSelectedCells, collectArrowLineUpdatedRefsByGeometry, createArrowLineElement, createCell, createDefaultCells,
|
|
9308
|
+
export { ArrowLineAutoCompleteGenerator, ArrowLineComponent, ArrowLineHandleKey, ArrowLineMarkerType, ArrowLineShape, BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultActivationProperty, DefaultActorProperty, DefaultArrowProperty, DefaultAssemblyProperty, DefaultBasicShapeProperty, DefaultBasicShapePropertyMap, DefaultClassProperty, DefaultCloudProperty, DefaultCombinedFragmentProperty, DefaultComponentBoxProperty, DefaultConnectorProperty, DefaultContainerProperty, DefaultDataBaseProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultDeletionProperty, DefaultDocumentProperty, DefaultDrawActiveStyle, DefaultDrawStyle, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultInterfaceProperty, DefaultInternalStorageProperty, DefaultLineStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultMultiDocumentProperty, DefaultNoteProperty, DefaultObjectProperty, DefaultPackageProperty, DefaultPentagonArrowProperty, DefaultPortProperty, DefaultProvidedInterfaceProperty, DefaultRequiredInterfaceProperty, DefaultSwimlaneHorizontalProperty, DefaultSwimlaneHorizontalWithHeaderProperty, DefaultSwimlanePropertyMap, DefaultSwimlaneVerticalProperty, DefaultSwimlaneVerticalWithHeaderProperty, DefaultTextProperty, DefaultTwoWayArrowProperty, DefaultUMLPropertyMap, DrawI18nKey, DrawThemeColors, DrawTransforms, FlowchartSymbols, GEOMETRY_NOT_CLOSED, GEOMETRY_WITHOUT_TEXT, GEOMETRY_WITH_MULTIPLE_TEXT, GeometryCommonTextKeys, GeometryComponent, GeometryShapeGenerator, GeometryThreshold, KEY_TO_TEXT_MANAGE, LINE_ALIGN_TOLERANCE, LINE_AUTO_COMPLETE_DIAMETER, LINE_AUTO_COMPLETE_HOVERED_DIAMETER, LINE_AUTO_COMPLETE_HOVERED_OPACITY, LINE_AUTO_COMPLETE_OPACITY, LINE_HIT_GEOMETRY_BUFFER, LINE_SNAPPING_BUFFER, LINE_SNAPPING_CONNECTOR_BUFFER, LINE_TEXT, LINE_TEXT_SPACE, LineActiveGenerator, MIN_TEXT_WIDTH, MemorizeKey, MultipleTextGeometryTextKeys, PlaitArrowLine, PlaitDrawElement, PlaitGeometry, PlaitTableElement, Q2C, SELECTED_CELLS, SWIMLANE_HEADER_SIZE, ShapeDefaultSpace, SingleTextGenerator, SwimlaneDrawSymbols, SwimlaneSymbols, TableGenerator, TableSymbols, TextGenerator, UMLSymbols, VectorLineComponent, VectorLinePointerType, VectorLineShape, WithArrowLineAutoCompletePluginKey, WithDrawPluginKey, adjustSwimlaneShape, alignElbowSegment, alignPoints, buildClipboardData, buildDefaultTextsByShape, buildSwimlaneTable, clearSelectedCells, collectArrowLineUpdatedRefsByGeometry, createArrowLineElement, createCell, createDefaultCells, createDefaultGeometry, createDefaultRowsOrColumns, createDefaultSwimlane, createGeometryElement, createGeometryElementWithText, createGeometryElementWithoutText, createMultipleTextGeometryElement, createTextElement, createUMLClassOrInterfaceGeometryElement, createVectorLineElement, debugGenerator$1 as debugGenerator, deleteTextManage, drawArrowLine, drawArrowLineArrow, drawBoundReaction, drawGeometry, drawShape, drawVectorLine, editCell, editText, getArrowLineHandleRefPair, getArrowLinePointers, getArrowLinePoints, getArrowLineTextRectangle, getArrowLines, getAutoCompletePoints, getBasicPointers, getCellWithPoints, getCellsRectangle, getCellsWithPoints, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultBasicShapeProperty, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultGeometryText, getDefaultSwimlanePoints, getDefaultTextPoints, getDefaultUMLProperty, getDrawDefaultStrokeColor, getElbowLineRouteOptions, getElbowPoints, getFillByElement, getFirstFilledDrawElement, getFirstTextOrLineElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryAlign, getGeometryPointers, getHitCell, getHitConnection, getHitConnectorPoint, getHitDrawElement, getHitIndexOfAutoCompletePoint, getHitMultipleGeometryText, getHitShape, getIndexAndDeleteCountByKeyPoint, getLineMemorizedLatest, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getMidKeyPoints, getMiddlePoints, getMirrorDataPoints, getMultipleTextGeometryTextKeys, getNearestPoint, getNextRenderPoints, getNextSourceAndTargetPoints, getResizedPreviousAndNextPoint, getSelectedArrowLineElements, getSelectedCells, getSelectedCustomGeometryElements, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedSwimlane, getSelectedTableCellsEditor, getSelectedTableElements, getSelectedVectorLineElements, getSnapResizingRef, getSnapResizingRefOptions, getSnappingRef, getSnappingShape, getSourceAndTargetRectangle, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getSwimlaneCount, getSwimlanePointers, getTextKey, getTextManage, getTextManageByCell, getTextRectangle, getTextShapeProperty, getUMLPointers, getVectorByConnection, getVectorLinePointers, getVectorLinePoints, handleArrowLineCreating, hasIllegalElbowPoint, insertClipboardData, insertElement, isCellIncludeText, isClosedCustomGeometry, isClosedDrawElement, isClosedPoints, isDrawElementIncludeText, isDrawElementsIncludeText, isEmptyTextElement, isFilledDrawElement, isGeometryClosed, isGeometryIncludeText, isHitArrowLine, isHitArrowLineText, isHitDrawElement, isHitEdgeOfShape, isHitElementInside, isHitElementText, isHitPolyLine, isHitVectorLine, isInsideOfShape, isMultipleTextGeometry, isMultipleTextShape, isRectangleHitDrawElement, isRectangleHitElementText, isRectangleHitRotatedElement, isRectangleHitRotatedPoints, isSelfLoop, isSingleSelectLine, isSingleSelectSwimlane, isSingleSelectTable, isSingleTextGeometry, isSingleTextShape, isSwimlanePointers, isSwimlaneWithHeader, isTextExceedingBounds, isUpdatedHandleIndex, isUseDefaultOrthogonalRoute, memorizeLatestShape, memorizeLatestText, setSelectedCells, setTextManage, traverseDrawShapes, updateCellIds, updateCellIdsByRowOrColumn, updateColumns, updateRowOrColumnIds, updateRows, vectorLineCreating, withArrowLineAutoComplete, withDraw };
|
|
9295
9309
|
//# sourceMappingURL=plait-draw.mjs.map
|