@plait/draw 0.63.0 → 0.64.1

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.
Files changed (57) hide show
  1. package/arrow-line.component.d.ts +3 -3
  2. package/constants/pointer.d.ts +3 -2
  3. package/esm2022/arrow-line.component.mjs +6 -5
  4. package/esm2022/constants/pointer.mjs +5 -2
  5. package/esm2022/generators/arrow-line.generator.mjs +3 -3
  6. package/esm2022/generators/index.mjs +2 -2
  7. package/esm2022/generators/line-active.generator.mjs +81 -0
  8. package/esm2022/generators/vector-line-generator.mjs +13 -0
  9. package/esm2022/interfaces/index.mjs +8 -5
  10. package/esm2022/interfaces/line.mjs +2 -0
  11. package/esm2022/interfaces/vector-line.mjs +5 -1
  12. package/esm2022/plugins/with-arrow-line-bound-reaction.mjs +3 -3
  13. package/esm2022/plugins/with-arrow-line-resize.mjs +9 -9
  14. package/esm2022/plugins/with-draw-fragment.mjs +7 -5
  15. package/esm2022/plugins/with-draw.mjs +17 -2
  16. package/esm2022/plugins/with-vector-line-resize.mjs +61 -0
  17. package/esm2022/plugins/with-vector-pen-create.mjs +124 -0
  18. package/esm2022/public-api.mjs +2 -1
  19. package/esm2022/transforms/index.mjs +3 -1
  20. package/esm2022/transforms/vector-line.mjs +13 -0
  21. package/esm2022/utils/arrow-line/arrow-line-basic.mjs +5 -58
  22. package/esm2022/utils/common.mjs +5 -1
  23. package/esm2022/utils/hit.mjs +24 -4
  24. package/esm2022/utils/index.mjs +3 -1
  25. package/esm2022/utils/line.mjs +64 -0
  26. package/esm2022/utils/position/arrow-line.mjs +3 -50
  27. package/esm2022/utils/position/line.mjs +51 -0
  28. package/esm2022/utils/selected.mjs +5 -1
  29. package/esm2022/utils/vector-line.mjs +75 -0
  30. package/esm2022/vector-line.component.mjs +50 -0
  31. package/fesm2022/plait-draw.mjs +510 -146
  32. package/fesm2022/plait-draw.mjs.map +1 -1
  33. package/generators/arrow-line.generator.d.ts +3 -5
  34. package/generators/index.d.ts +1 -1
  35. package/generators/line-active.generator.d.ts +13 -0
  36. package/generators/vector-line-generator.d.ts +6 -0
  37. package/interfaces/index.d.ts +3 -0
  38. package/interfaces/line.d.ts +3 -0
  39. package/interfaces/vector-line.d.ts +10 -1
  40. package/package.json +1 -1
  41. package/plugins/with-vector-line-resize.d.ts +2 -0
  42. package/plugins/with-vector-pen-create.d.ts +2 -0
  43. package/public-api.d.ts +1 -0
  44. package/styles/styles.scss +2 -2
  45. package/transforms/index.d.ts +1 -0
  46. package/transforms/vector-line.d.ts +3 -0
  47. package/utils/arrow-line/arrow-line-basic.d.ts +0 -1
  48. package/utils/hit.d.ts +3 -2
  49. package/utils/index.d.ts +2 -0
  50. package/utils/line.d.ts +3 -0
  51. package/utils/position/arrow-line.d.ts +0 -13
  52. package/utils/position/line.d.ts +15 -0
  53. package/utils/selected.d.ts +2 -1
  54. package/utils/vector-line.d.ts +7 -0
  55. package/vector-line.component.d.ts +14 -0
  56. package/esm2022/generators/arrow-line-active.generator.mjs +0 -81
  57. package/generators/arrow-line-active.generator.d.ts +0 -13
@@ -1,5 +1,5 @@
1
- import { ACTIVE_STROKE_WIDTH, ThemeColorMode, RectangleClient, getSelectedElements, idCreator, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, rotatePointsByElement, isPolylineHitRectangle, rotateAntiPointsByElement, distanceBetweenPointAndPoint, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, depthFirstRecursion, PlaitBoard, getIsRecursionFunc, createG, SNAPPING_STROKE_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, createDebugGenerator, Point, arrowPoints, createPath, drawLinearPath, rotate, catmullRomFitting, setStrokeLinecap, findElements, createMask, createRect, PlaitElement, getElementById, PlaitNode, hasValidAngle, toViewBoxPoint, toHostPoint, Direction, rotatePoints, getRectangleByElements, getSelectionAngle, rotatedDataPoints, isAxisChangedByAngle, isSelectionMoving, drawRectangle, getRectangleByAngle, getSnapRectangles, getTripleAxis, getMinPointDelta, SNAP_TOLERANCE, drawPointSnapLines, drawSolidLines, isPointInPolygon, getNearestPointBetweenPointAndSegments, isPointInEllipse, getNearestPointBetweenPointAndEllipse, getEllipseTangentSlope, getVectorFromPointAndSlope, drawRoundRectangle, isPointInRoundRectangle, setPathStrokeLinecap, getCrossingPointsBetweenEllipseAndSegment, drawLine, Path, RgbaToHEX, getHitElementByPoint, preventTouchMove, WritableClipboardOperationType, createClipboardContext, WritableClipboardType, addClipboardContext, setAngleForG, CursorClass, temporaryDisableSelection, PRESS_AND_MOVE_BUFFER, isMainPointer, throttleRAF, getAngleBetweenPoints, normalizeAngle, degreesToRadians, rotateElements, MERGING, ROTATE_HANDLE_CLASS_NAME, SELECTION_RECTANGLE_CLASS_NAME, isSelectedElement, isDragging } from '@plait/core';
2
- import { DEFAULT_FILL, Alignment, WithTextPluginKey, ELEMENT_TO_TEXT_MANAGES, TextManage, getMemorizedLatest, memorizeLatest, RESIZE_HANDLE_DIAMETER, getPointOnPolyline, buildText, sortElementsByArea, isFilled, getTextEditorsByElement, Generator, removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, getExtendPoint, getUnitVectorByPointAndPoint, getPointByVectorComponent, measureElement, DEFAULT_FONT_FAMILY, getFirstTextManage, ActiveGenerator, isSourceAndTargetIntersect, getPoints, DEFAULT_ROUTE_MARGIN, normalizeShapePoints, getFirstTextEditor, resetPointsAfterResize, getDirectionByVector, getRectangleResizeHandleRefs, getRotatedResizeCursorClassByAngle, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, isCornerHandle, getIndexByResizeHandle, withResize, drawHandle, getSymmetricHandleIndex, getResizeHandlePointByIndex, getDirectionFactorByDirectionComponent, getCrossingPointsBetweenPointAndSegment, isPointOnSegment, getDirectionByPointOfRectangle, getDirectionFactor, rotateVector, getOppositeDirection, rotateVectorAnti90, getSourceAndTargetOuterRectangle, getNextPoint, PRIMARY_COLOR, CommonElementFlavour, canResize, drawPrimaryHandle, drawFillPrimaryHandle, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, getElementsText, acceptImageTypes, getElementOfFocusedImage, buildImage, isResizingByCondition, getRatioByPoint, getTextManages, ImageGenerator, ResizeHandle, addRotating, removeRotating, drawRotateHandle } from '@plait/common';
1
+ import { ACTIVE_STROKE_WIDTH, ThemeColorMode, RectangleClient, getSelectedElements, idCreator, catmullRomFitting, PlaitBoard, createG, drawLinearPath, setStrokeLinecap, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, isPointInPolygon, rotatePointsByElement, isPolylineHitRectangle, rotateAntiPointsByElement, distanceBetweenPointAndPoint, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, depthFirstRecursion, getIsRecursionFunc, SNAPPING_STROKE_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, createDebugGenerator, Point, arrowPoints, createPath, rotate, findElements, createMask, createRect, PlaitElement, getElementById, 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, setPathStrokeLinecap, getCrossingPointsBetweenEllipseAndSegment, drawLine, Path, RgbaToHEX, getHitElementByPoint, preventTouchMove, WritableClipboardOperationType, createClipboardContext, WritableClipboardType, addClipboardContext, setAngleForG, CursorClass, temporaryDisableSelection, PRESS_AND_MOVE_BUFFER, isMainPointer, throttleRAF, getAngleBetweenPoints, normalizeAngle, degreesToRadians, rotateElements, MERGING, ROTATE_HANDLE_CLASS_NAME, SELECTION_RECTANGLE_CLASS_NAME, isSelectedElement, isDragging } from '@plait/core';
2
+ import { DEFAULT_FILL, Alignment, WithTextPluginKey, ELEMENT_TO_TEXT_MANAGES, TextManage, getMemorizedLatest, memorizeLatest, getPointOnPolyline, buildText, Generator, sortElementsByArea, isFilled, getTextEditorsByElement, removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, getExtendPoint, getUnitVectorByPointAndPoint, getPointByVectorComponent, RESIZE_HANDLE_DIAMETER, measureElement, DEFAULT_FONT_FAMILY, getFirstTextManage, ActiveGenerator, isSourceAndTargetIntersect, getPoints, DEFAULT_ROUTE_MARGIN, normalizeShapePoints, getFirstTextEditor, resetPointsAfterResize, getDirectionByVector, getRectangleResizeHandleRefs, getRotatedResizeCursorClassByAngle, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, isCornerHandle, getIndexByResizeHandle, withResize, drawHandle, getSymmetricHandleIndex, getResizeHandlePointByIndex, getDirectionFactorByDirectionComponent, getCrossingPointsBetweenPointAndSegment, isPointOnSegment, getDirectionByPointOfRectangle, getDirectionFactor, rotateVector, getOppositeDirection, rotateVectorAnti90, getSourceAndTargetOuterRectangle, getNextPoint, PRIMARY_COLOR, CommonElementFlavour, canResize, drawPrimaryHandle, drawFillPrimaryHandle, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, getElementsText, acceptImageTypes, getElementOfFocusedImage, buildImage, isResizingByCondition, getRatioByPoint, getTextManages, ImageGenerator, ResizeHandle, addRotating, removeRotating, drawRotateHandle } from '@plait/common';
3
3
  import { pointsOnBezierCurves } from 'points-on-curve';
4
4
  import { TEXT_DEFAULT_HEIGHT, DEFAULT_FONT_SIZE, AlignEditor } from '@plait/text-plugins';
5
5
  import { isKeyHotkey } from 'is-hotkey';
@@ -400,6 +400,9 @@ const getUMLPointers = () => {
400
400
  const getArrowLinePointers = () => {
401
401
  return Object.keys(ArrowLineShape);
402
402
  };
403
+ const getVectorPenPointers = () => {
404
+ return Object.keys(VectorPenPointerType);
405
+ };
403
406
 
404
407
  const DEFAULT_IMAGE_WIDTH = 1000;
405
408
 
@@ -866,52 +869,6 @@ const getMemorizedLatestShape = (board) => {
866
869
  return memorizedShape.get(board);
867
870
  };
868
871
 
869
- var ArrowLineResizeHandle;
870
- (function (ArrowLineResizeHandle) {
871
- ArrowLineResizeHandle["source"] = "source";
872
- ArrowLineResizeHandle["target"] = "target";
873
- ArrowLineResizeHandle["addHandle"] = "addHandle";
874
- })(ArrowLineResizeHandle || (ArrowLineResizeHandle = {}));
875
- const getHitArrowLineResizeHandleRef = (board, element, point) => {
876
- let dataPoints = PlaitArrowLine.getPoints(board, element);
877
- const index = getHitPointIndex(dataPoints, point);
878
- if (index !== -1) {
879
- const handleIndex = index;
880
- if (index === 0) {
881
- return { handle: ArrowLineResizeHandle.source, handleIndex };
882
- }
883
- if (index === dataPoints.length - 1) {
884
- return { handle: ArrowLineResizeHandle.target, handleIndex };
885
- }
886
- // elbow line, data points only verify source connection point and target connection point
887
- if (element.shape !== ArrowLineShape.elbow) {
888
- return { handleIndex };
889
- }
890
- }
891
- const middlePoints = getMiddlePoints(board, element);
892
- const indexOfMiddlePoints = getHitPointIndex(middlePoints, point);
893
- if (indexOfMiddlePoints !== -1) {
894
- return {
895
- handle: ArrowLineResizeHandle.addHandle,
896
- handleIndex: indexOfMiddlePoints
897
- };
898
- }
899
- return undefined;
900
- };
901
- function getHitPointIndex(points, movingPoint) {
902
- const rectangles = points.map(point => {
903
- return {
904
- x: point[0] - RESIZE_HANDLE_DIAMETER / 2,
905
- y: point[1] - RESIZE_HANDLE_DIAMETER / 2,
906
- width: RESIZE_HANDLE_DIAMETER,
907
- height: RESIZE_HANDLE_DIAMETER
908
- };
909
- });
910
- const rectangle = rectangles.find(rectangle => {
911
- return RectangleClient.isHit(RectangleClient.getRectangleByPoints([movingPoint, movingPoint]), rectangle);
912
- });
913
- return rectangle ? rectangles.indexOf(rectangle) : -1;
914
- }
915
872
  const getHitArrowLineTextIndex = (board, element, point) => {
916
873
  const texts = element.texts;
917
874
  if (!texts.length)
@@ -983,6 +940,95 @@ const getHitMultipleGeometryText = (element, point) => {
983
940
  return hitText;
984
941
  };
985
942
 
943
+ const DefaultLineStyle = {
944
+ strokeWidth: 2,
945
+ strokeColor: '#000'
946
+ };
947
+ const LINE_TEXT_SPACE = 4;
948
+ const LINE_AUTO_COMPLETE_DIAMETER = 6;
949
+ const LINE_AUTO_COMPLETE_OPACITY = 0.6;
950
+ const LINE_AUTO_COMPLETE_HOVERED_OPACITY = 0.8;
951
+ const LINE_AUTO_COMPLETE_HOVERED_DIAMETER = 10;
952
+ const LINE_ALIGN_TOLERANCE = 3;
953
+ const LINE_TEXT = '文本';
954
+
955
+ class VectorLineShapeGenerator extends Generator {
956
+ canDraw(element) {
957
+ return true;
958
+ }
959
+ draw(element) {
960
+ let lineG;
961
+ lineG = drawVectorLine(this.board, element);
962
+ return lineG;
963
+ }
964
+ }
965
+
966
+ const isClosedVectorLine = (vectorLine) => {
967
+ const points = vectorLine.points;
968
+ const startPoint = points[0];
969
+ const endPoint = points[points.length - 1];
970
+ return startPoint[0] === endPoint[0] && startPoint[1] === endPoint[1];
971
+ };
972
+ const getVectorLinePoints = (board, element) => {
973
+ switch (element.shape) {
974
+ case VectorLineShape.straight: {
975
+ return element.points;
976
+ }
977
+ case VectorLineShape.curve: {
978
+ if (element.points.length === 2) {
979
+ return pointsOnBezierCurves(element.points);
980
+ }
981
+ else {
982
+ let dataPoints = element.points;
983
+ const points = catmullRomFitting(dataPoints);
984
+ return pointsOnBezierCurves(points);
985
+ }
986
+ }
987
+ default:
988
+ return null;
989
+ }
990
+ };
991
+ const createVectorLineElement = (shape, points, options) => {
992
+ return {
993
+ id: idCreator(),
994
+ type: 'vector-line',
995
+ shape,
996
+ opacity: 1,
997
+ points,
998
+ ...options
999
+ };
1000
+ };
1001
+ const vectorLineCreating = (board, lineShape, points, movingPoint, lineShapeG) => {
1002
+ const lineGenerator = new VectorLineShapeGenerator(board);
1003
+ const memorizedLatest = getLineMemorizedLatest();
1004
+ const temporaryLineElement = createVectorLineElement(lineShape, [...points, movingPoint], {
1005
+ strokeWidth: DefaultLineStyle.strokeWidth,
1006
+ ...memorizedLatest
1007
+ });
1008
+ const otherPoint = points[points.length - 1];
1009
+ temporaryLineElement.points[temporaryLineElement.points.length - 1] = alignPoints(otherPoint, movingPoint);
1010
+ lineGenerator.processDrawing(temporaryLineElement, lineShapeG);
1011
+ PlaitBoard.getElementActiveHost(board).append(lineShapeG);
1012
+ return temporaryLineElement;
1013
+ };
1014
+ const drawVectorLine = (board, element) => {
1015
+ const strokeWidth = getStrokeWidthByElement(element);
1016
+ const strokeColor = getStrokeColorByElement(board, element);
1017
+ const strokeLineDash = getLineDashByElement(element);
1018
+ const fill = getFillByElement(board, element);
1019
+ const options = { stroke: strokeColor, strokeWidth, strokeLineDash, fill };
1020
+ const lineG = createG();
1021
+ let points = getVectorLinePoints(board, element);
1022
+ const line = drawLinearPath(points, options);
1023
+ const id = idCreator();
1024
+ line.setAttribute('mask', `url(#${id})`);
1025
+ if (element.strokeStyle === StrokeStyle.dotted) {
1026
+ setStrokeLinecap(line, 'round');
1027
+ }
1028
+ lineG.appendChild(line);
1029
+ return lineG;
1030
+ };
1031
+
986
1032
  const isTextExceedingBounds = (geometry) => {
987
1033
  const client = RectangleClient.getRectangleByPoints(geometry.points);
988
1034
  if (geometry.textHeight && geometry.textHeight > client.height) {
@@ -1002,6 +1048,15 @@ const isHitArrowLine = (board, element, point) => {
1002
1048
  const isHitText = isHitArrowLineText(board, element, point);
1003
1049
  return isHitText || isHitPolyLine(points, point);
1004
1050
  };
1051
+ const isHitVectorLine = (board, element, point) => {
1052
+ const points = getVectorLinePoints(board, element);
1053
+ if (isClosedVectorLine(element)) {
1054
+ return isPointInPolygon(point, points) || isHitPolyLine(points, point);
1055
+ }
1056
+ else {
1057
+ return isHitPolyLine(points, point);
1058
+ }
1059
+ };
1005
1060
  const isRectangleHitElementText = (element, rectangle) => {
1006
1061
  const engine = getEngine(element.shape);
1007
1062
  if (isMultipleTextGeometry(element)) {
@@ -1052,6 +1107,10 @@ const isRectangleHitDrawElement = (board, element, selection) => {
1052
1107
  const points = getArrowLinePoints(board, element);
1053
1108
  return isPolylineHitRectangle(points, rangeRectangle);
1054
1109
  }
1110
+ if (PlaitDrawElement.isVectorLine(element)) {
1111
+ const points = getVectorLinePoints(board, element);
1112
+ return isPolylineHitRectangle(points, rangeRectangle, false);
1113
+ }
1055
1114
  return null;
1056
1115
  };
1057
1116
  const getDrawHitElement = (board, elements) => {
@@ -1072,7 +1131,7 @@ const getFirstFilledDrawElement = (board, elements) => {
1072
1131
  let filledElement = null;
1073
1132
  for (let i = 0; i < elements.length; i++) {
1074
1133
  const element = elements[i];
1075
- if (PlaitDrawElement.isGeometry(element) && !PlaitDrawElement.isText(element)) {
1134
+ if (isDrawElementClosed(element)) {
1076
1135
  const fill = getFillByElement(board, element);
1077
1136
  if (isFilled(fill)) {
1078
1137
  filledElement = element;
@@ -1115,6 +1174,9 @@ const isHitDrawElement = (board, element, point) => {
1115
1174
  if (PlaitDrawElement.isArrowLine(element)) {
1116
1175
  return isHitArrowLine(board, element, point);
1117
1176
  }
1177
+ if (PlaitDrawElement.isVectorLine(element)) {
1178
+ return isHitVectorLine(board, element, point);
1179
+ }
1118
1180
  return null;
1119
1181
  };
1120
1182
  const isHitEdgeOfShape = (board, element, point, hitDistanceBuffer) => {
@@ -1149,6 +1211,9 @@ const isHitElementInside = (board, element, point) => {
1149
1211
  if (PlaitDrawElement.isArrowLine(element)) {
1150
1212
  return isHitArrowLine(board, element, point);
1151
1213
  }
1214
+ if (PlaitDrawElement.isVectorLine(element)) {
1215
+ return isHitVectorLine(board, element, point);
1216
+ }
1152
1217
  return null;
1153
1218
  };
1154
1219
 
@@ -1206,6 +1271,9 @@ const isDrawElementClosed = (element) => {
1206
1271
  if (PlaitDrawElement.isText(element) || PlaitDrawElement.isArrowLine(element) || PlaitDrawElement.isImage(element)) {
1207
1272
  return false;
1208
1273
  }
1274
+ if (PlaitDrawElement.isVectorLine(element)) {
1275
+ return isClosedVectorLine(element);
1276
+ }
1209
1277
  if (PlaitDrawElement.isGeometry(element)) {
1210
1278
  return isGeometryClosed(element);
1211
1279
  }
@@ -1333,29 +1401,6 @@ const getStrokeStyleByElement = (element) => {
1333
1401
  return element.strokeStyle || StrokeStyle.solid;
1334
1402
  };
1335
1403
 
1336
- const DefaultLineStyle = {
1337
- strokeWidth: 2,
1338
- strokeColor: '#000'
1339
- };
1340
- const LINE_TEXT_SPACE = 4;
1341
- const LINE_AUTO_COMPLETE_DIAMETER = 6;
1342
- const LINE_AUTO_COMPLETE_OPACITY = 0.6;
1343
- const LINE_AUTO_COMPLETE_HOVERED_OPACITY = 0.8;
1344
- const LINE_AUTO_COMPLETE_HOVERED_DIAMETER = 10;
1345
- const LINE_ALIGN_TOLERANCE = 3;
1346
- const LINE_TEXT = '文本';
1347
-
1348
- class ArrowLineShapeGenerator extends Generator {
1349
- canDraw(element, data) {
1350
- return true;
1351
- }
1352
- draw(element, data) {
1353
- let lineG;
1354
- lineG = drawArrowLine(this.board, element);
1355
- return lineG;
1356
- }
1357
- }
1358
-
1359
1404
  const debugKey$3 = 'debug:plait:line-mirror';
1360
1405
  const debugGenerator$3 = createDebugGenerator(debugKey$3);
1361
1406
  const alignPoints = (basePoint, movingPoint) => {
@@ -1780,6 +1825,17 @@ const drawHollowTriangleArrow = (source, target, options) => {
1780
1825
  return drawLinearPath([pointLeft, pointRight, target], { ...options, fill: 'white' }, true);
1781
1826
  };
1782
1827
 
1828
+ class ArrowLineShapeGenerator extends Generator {
1829
+ canDraw(element) {
1830
+ return true;
1831
+ }
1832
+ draw(element) {
1833
+ let lineG;
1834
+ lineG = drawArrowLine(this.board, element);
1835
+ return lineG;
1836
+ }
1837
+ }
1838
+
1783
1839
  const createArrowLineElement = (shape, points, source, target, texts, options) => {
1784
1840
  return {
1785
1841
  id: idCreator(),
@@ -1845,59 +1901,6 @@ const getCurvePoints = (board, element) => {
1845
1901
  return pointsOnBezierCurves(points);
1846
1902
  }
1847
1903
  };
1848
- function getMiddlePoints(board, element) {
1849
- const result = [];
1850
- const shape = element.shape;
1851
- const hideBuffer = 10;
1852
- if (shape === ArrowLineShape.straight) {
1853
- const points = PlaitArrowLine.getPoints(board, element);
1854
- for (let i = 0; i < points.length - 1; i++) {
1855
- const distance = distanceBetweenPointAndPoint(...points[i], ...points[i + 1]);
1856
- if (distance < hideBuffer)
1857
- continue;
1858
- result.push([(points[i][0] + points[i + 1][0]) / 2, (points[i][1] + points[i + 1][1]) / 2]);
1859
- }
1860
- }
1861
- if (shape === ArrowLineShape.curve) {
1862
- const points = PlaitArrowLine.getPoints(board, element);
1863
- const pointsOnBezier = getCurvePoints(board, element);
1864
- if (points.length === 2) {
1865
- const start = 0;
1866
- const endIndex = pointsOnBezier.length - 1;
1867
- const middleIndex = Math.round((start + endIndex) / 2);
1868
- result.push(pointsOnBezier[middleIndex]);
1869
- }
1870
- else {
1871
- for (let i = 0; i < points.length - 1; i++) {
1872
- const startIndex = pointsOnBezier.findIndex(point => point[0] === points[i][0] && point[1] === points[i][1]);
1873
- const endIndex = pointsOnBezier.findIndex(point => point[0] === points[i + 1][0] && point[1] === points[i + 1][1]);
1874
- const middleIndex = Math.round((startIndex + endIndex) / 2);
1875
- const distance = distanceBetweenPointAndPoint(...points[i], ...points[i + 1]);
1876
- if (distance < hideBuffer)
1877
- continue;
1878
- result.push(pointsOnBezier[middleIndex]);
1879
- }
1880
- }
1881
- }
1882
- if (shape === ArrowLineShape.elbow) {
1883
- const renderPoints = getElbowPoints(board, element);
1884
- const options = getElbowLineRouteOptions(board, element);
1885
- if (!isUseDefaultOrthogonalRoute(element, options)) {
1886
- const [nextSourcePoint, nextTargetPoint] = getNextSourceAndTargetPoints(board, element);
1887
- for (let i = 0; i < renderPoints.length - 1; i++) {
1888
- if ((i == 0 && Point.isEquals(renderPoints[i + 1], nextSourcePoint)) ||
1889
- (i === renderPoints.length - 2 && Point.isEquals(renderPoints[renderPoints.length - 2], nextTargetPoint))) {
1890
- continue;
1891
- }
1892
- const [currentX, currentY] = renderPoints[i];
1893
- const [nextX, nextY] = renderPoints[i + 1];
1894
- const middlePoint = [(currentX + nextX) / 2, (currentY + nextY) / 2];
1895
- result.push(middlePoint);
1896
- }
1897
- }
1898
- }
1899
- return result;
1900
- }
1901
1904
  const drawArrowLine = (board, element) => {
1902
1905
  const strokeWidth = getStrokeWidthByElement(element);
1903
1906
  const strokeColor = getStrokeColorByElement(board, element);
@@ -2455,6 +2458,10 @@ const getSelectedArrowLineElements = (board) => {
2455
2458
  const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isArrowLine(value));
2456
2459
  return selectedElements;
2457
2460
  };
2461
+ const getSelectedVectorLineElements = (board) => {
2462
+ const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isVectorLine(value));
2463
+ return selectedElements;
2464
+ };
2458
2465
  const getSelectedImageElements = (board) => {
2459
2466
  const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isImage(value));
2460
2467
  return selectedElements;
@@ -3004,6 +3011,17 @@ const setTableFill = (board, element, fill, path) => {
3004
3011
  Transforms.setNode(board, { cells: newCells }, path);
3005
3012
  };
3006
3013
 
3014
+ const setVectorLineShape = (board, newProperties) => {
3015
+ const elements = getSelectedVectorLineElements(board);
3016
+ elements.map(element => {
3017
+ if (element.shape === newProperties.shape) {
3018
+ return;
3019
+ }
3020
+ const path = PlaitBoard.findPath(board, element);
3021
+ Transforms.setNode(board, { ...newProperties }, path);
3022
+ });
3023
+ };
3024
+
3007
3025
  const insertDrawByVector = (board, point, shape, vector) => {
3008
3026
  const swimlanePointers = getSwimlanePointers();
3009
3027
  const isSwimlanePointer = swimlanePointers.includes(shape);
@@ -3047,6 +3065,7 @@ const DrawTransforms = {
3047
3065
  removeArrowLineText,
3048
3066
  setArrowLineMark,
3049
3067
  setArrowLineShape,
3068
+ setVectorLineShape,
3050
3069
  insertImage,
3051
3070
  connectArrowLineToDraw,
3052
3071
  switchGeometryShape,
@@ -3520,6 +3539,66 @@ function drawIsometricSnapLines(board, activePoints, snapRectangles, resizeSnapO
3520
3539
  return drawSolidLines(board, isometricLines);
3521
3540
  }
3522
3541
 
3542
+ function getMiddlePoints(board, element) {
3543
+ const result = [];
3544
+ const shape = element.shape;
3545
+ const hideBuffer = 10;
3546
+ if (shape === ArrowLineShape.straight) {
3547
+ const points = PlaitDrawElement.isArrowLine(element)
3548
+ ? PlaitArrowLine.getPoints(board, element)
3549
+ : element.points;
3550
+ for (let i = 0; i < points.length - 1; i++) {
3551
+ const distance = distanceBetweenPointAndPoint(...points[i], ...points[i + 1]);
3552
+ if (distance < hideBuffer)
3553
+ continue;
3554
+ result.push([(points[i][0] + points[i + 1][0]) / 2, (points[i][1] + points[i + 1][1]) / 2]);
3555
+ }
3556
+ }
3557
+ if (shape === ArrowLineShape.curve) {
3558
+ const points = PlaitDrawElement.isArrowLine(element)
3559
+ ? PlaitArrowLine.getPoints(board, element)
3560
+ : element.points;
3561
+ const pointsOnBezier = PlaitDrawElement.isArrowLine(element)
3562
+ ? getCurvePoints(board, element)
3563
+ : getVectorLinePoints(board, element);
3564
+ if (points.length === 2) {
3565
+ const start = 0;
3566
+ const endIndex = pointsOnBezier.length - 1;
3567
+ const middleIndex = Math.round((start + endIndex) / 2);
3568
+ result.push(pointsOnBezier[middleIndex]);
3569
+ }
3570
+ else {
3571
+ for (let i = 0; i < points.length - 1; i++) {
3572
+ const startIndex = pointsOnBezier.findIndex(point => point[0] === points[i][0] && point[1] === points[i][1]);
3573
+ const endIndex = pointsOnBezier.findIndex(point => point[0] === points[i + 1][0] && point[1] === points[i + 1][1]);
3574
+ const middleIndex = Math.round((startIndex + endIndex) / 2);
3575
+ const distance = distanceBetweenPointAndPoint(...points[i], ...points[i + 1]);
3576
+ if (distance < hideBuffer)
3577
+ continue;
3578
+ result.push(pointsOnBezier[middleIndex]);
3579
+ }
3580
+ }
3581
+ }
3582
+ if (shape === ArrowLineShape.elbow) {
3583
+ const renderPoints = getElbowPoints(board, element);
3584
+ const options = getElbowLineRouteOptions(board, element);
3585
+ if (!isUseDefaultOrthogonalRoute(element, options)) {
3586
+ const [nextSourcePoint, nextTargetPoint] = getNextSourceAndTargetPoints(board, element);
3587
+ for (let i = 0; i < renderPoints.length - 1; i++) {
3588
+ if ((i == 0 && Point.isEquals(renderPoints[i + 1], nextSourcePoint)) ||
3589
+ (i === renderPoints.length - 2 && Point.isEquals(renderPoints[renderPoints.length - 2], nextTargetPoint))) {
3590
+ continue;
3591
+ }
3592
+ const [currentX, currentY] = renderPoints[i];
3593
+ const [nextX, nextY] = renderPoints[i + 1];
3594
+ const middlePoint = [(currentX + nextX) / 2, (currentY + nextY) / 2];
3595
+ result.push(middlePoint);
3596
+ }
3597
+ }
3598
+ }
3599
+ return result;
3600
+ }
3601
+
3523
3602
  const getCenterPointsOnPolygon = (points) => {
3524
3603
  const centerPoints = [];
3525
3604
  for (let i = 0; i < points.length; i++) {
@@ -6378,6 +6457,10 @@ var MemorizeKey;
6378
6457
  MemorizeKey["UML"] = "UML";
6379
6458
  })(MemorizeKey || (MemorizeKey = {}));
6380
6459
 
6460
+ var VectorPenPointerType;
6461
+ (function (VectorPenPointerType) {
6462
+ VectorPenPointerType["vectorPen"] = "vectorPen";
6463
+ })(VectorPenPointerType || (VectorPenPointerType = {}));
6381
6464
  var VectorLineShape;
6382
6465
  (function (VectorLineShape) {
6383
6466
  VectorLineShape["straight"] = "straight";
@@ -6388,12 +6471,15 @@ const PlaitDrawElement = {
6388
6471
  isGeometry: (value) => {
6389
6472
  return value.type === 'geometry';
6390
6473
  },
6391
- // isLine: (value: any): value is PlaitArrowLine => {
6392
- // return value.type === 'arrow-line' || value.type === 'line' || value.type === 'vector-line';
6393
- // },
6394
6474
  isArrowLine: (value) => {
6395
6475
  return value.type === 'arrow-line' || value.type === 'line';
6396
6476
  },
6477
+ isVectorLine: (value) => {
6478
+ return value.type === 'vector-line';
6479
+ },
6480
+ isLine: (value) => {
6481
+ return PlaitDrawElement.isArrowLine(value) || PlaitDrawElement.isVectorLine(value);
6482
+ },
6397
6483
  isText: (value) => {
6398
6484
  return value.type === 'geometry' && value.shape === BasicShapes.text;
6399
6485
  },
@@ -6405,7 +6491,7 @@ const PlaitDrawElement = {
6405
6491
  },
6406
6492
  isDrawElement: (value) => {
6407
6493
  if (PlaitDrawElement.isGeometry(value) ||
6408
- PlaitDrawElement.isArrowLine(value) ||
6494
+ PlaitDrawElement.isLine(value) ||
6409
6495
  PlaitDrawElement.isImage(value) ||
6410
6496
  PlaitDrawElement.isTable(value) ||
6411
6497
  PlaitDrawElement.isSwimlane(value)) {
@@ -6656,7 +6742,54 @@ class GeometryComponent extends CommonElementFlavour {
6656
6742
  }
6657
6743
  }
6658
6744
 
6659
- class ArrowLineActiveGenerator extends Generator {
6745
+ var LineResizeHandle;
6746
+ (function (LineResizeHandle) {
6747
+ LineResizeHandle["source"] = "source";
6748
+ LineResizeHandle["target"] = "target";
6749
+ LineResizeHandle["addHandle"] = "addHandle";
6750
+ })(LineResizeHandle || (LineResizeHandle = {}));
6751
+ const getHitLineResizeHandleRef = (board, element, point) => {
6752
+ let dataPoints = PlaitDrawElement.isArrowLine(element) ? PlaitArrowLine.getPoints(board, element) : element.points;
6753
+ const index = getHitPointIndex(dataPoints, point);
6754
+ if (index !== -1) {
6755
+ const handleIndex = index;
6756
+ if (index === 0) {
6757
+ return { handle: LineResizeHandle.source, handleIndex };
6758
+ }
6759
+ if (index === dataPoints.length - 1) {
6760
+ return { handle: LineResizeHandle.target, handleIndex };
6761
+ }
6762
+ // elbow line, data points only verify source connection point and target connection point
6763
+ if (element.shape !== ArrowLineShape.elbow) {
6764
+ return { handleIndex };
6765
+ }
6766
+ }
6767
+ const middlePoints = getMiddlePoints(board, element);
6768
+ const indexOfMiddlePoints = getHitPointIndex(middlePoints, point);
6769
+ if (indexOfMiddlePoints !== -1) {
6770
+ return {
6771
+ handle: LineResizeHandle.addHandle,
6772
+ handleIndex: indexOfMiddlePoints
6773
+ };
6774
+ }
6775
+ return undefined;
6776
+ };
6777
+ function getHitPointIndex(points, movingPoint) {
6778
+ const rectangles = points.map(point => {
6779
+ return {
6780
+ x: point[0] - RESIZE_HANDLE_DIAMETER / 2,
6781
+ y: point[1] - RESIZE_HANDLE_DIAMETER / 2,
6782
+ width: RESIZE_HANDLE_DIAMETER,
6783
+ height: RESIZE_HANDLE_DIAMETER
6784
+ };
6785
+ });
6786
+ const rectangle = rectangles.find(rectangle => {
6787
+ return RectangleClient.isHit(RectangleClient.getRectangleByPoints([movingPoint, movingPoint]), rectangle);
6788
+ });
6789
+ return rectangle ? rectangles.indexOf(rectangle) : -1;
6790
+ }
6791
+
6792
+ class LineActiveGenerator extends Generator {
6660
6793
  constructor() {
6661
6794
  super(...arguments);
6662
6795
  this.onlySelectedCurrentLine = false;
@@ -6676,7 +6809,7 @@ class ArrowLineActiveGenerator extends Generator {
6676
6809
  if (this.onlySelectedCurrentLine) {
6677
6810
  activeG.classList.add('active');
6678
6811
  activeG.classList.add('line-handle');
6679
- const points = PlaitArrowLine.getPoints(this.board, element);
6812
+ const points = PlaitDrawElement.isArrowLine(element) ? PlaitArrowLine.getPoints(this.board, element) : element.points;
6680
6813
  let updatePoints = [...points];
6681
6814
  let elbowNextRenderPoints = [];
6682
6815
  if (element.shape === ArrowLineShape.elbow) {
@@ -6738,7 +6871,7 @@ class ArrowLineComponent extends CommonElementFlavour {
6738
6871
  }
6739
6872
  initializeGenerator() {
6740
6873
  this.shapeGenerator = new ArrowLineShapeGenerator(this.board);
6741
- this.activeGenerator = new ArrowLineActiveGenerator(this.board);
6874
+ this.activeGenerator = new LineActiveGenerator(this.board);
6742
6875
  this.initializeTextManagesByElement();
6743
6876
  }
6744
6877
  initialize() {
@@ -6878,6 +7011,51 @@ class ArrowLineComponent extends CommonElementFlavour {
6878
7011
  }
6879
7012
  }
6880
7013
 
7014
+ class VectorLineComponent extends CommonElementFlavour {
7015
+ constructor() {
7016
+ super();
7017
+ }
7018
+ initializeGenerator() {
7019
+ this.shapeGenerator = new VectorLineShapeGenerator(this.board);
7020
+ this.activeGenerator = new LineActiveGenerator(this.board);
7021
+ }
7022
+ initialize() {
7023
+ this.initializeGenerator();
7024
+ this.shapeGenerator.processDrawing(this.element, this.getElementG());
7025
+ const linePoints = getVectorLinePoints(this.board, this.element);
7026
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
7027
+ selected: this.selected,
7028
+ linePoints
7029
+ });
7030
+ super.initialize();
7031
+ }
7032
+ onContextChanged(value, previous) {
7033
+ this.initializeWeakMap();
7034
+ const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
7035
+ const linePoints = getVectorLinePoints(this.board, this.element);
7036
+ if (value.element !== previous.element || isChangeTheme) {
7037
+ this.shapeGenerator.processDrawing(this.element, this.getElementG());
7038
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
7039
+ selected: this.selected,
7040
+ linePoints
7041
+ });
7042
+ }
7043
+ else {
7044
+ const needUpdate = value.selected !== previous.selected || this.activeGenerator.needUpdate();
7045
+ if (needUpdate) {
7046
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
7047
+ selected: this.selected,
7048
+ linePoints
7049
+ });
7050
+ }
7051
+ }
7052
+ }
7053
+ destroy() {
7054
+ super.destroy();
7055
+ this.activeGenerator.destroy();
7056
+ }
7057
+ }
7058
+
6881
7059
  const withDrawHotkey = (board) => {
6882
7060
  const { keyDown, dblClick } = board;
6883
7061
  board.keyDown = (event) => {
@@ -7197,7 +7375,8 @@ const withDrawFragment = (baseBoard) => {
7197
7375
  const drawElements = getSelectedDrawElements(board);
7198
7376
  if (drawElements.length) {
7199
7377
  const geometryElements = drawElements.filter(value => PlaitDrawElement.isGeometry(value));
7200
- const lineElements = drawElements.filter(value => PlaitDrawElement.isArrowLine(value));
7378
+ const arrowLineElements = drawElements.filter(value => PlaitDrawElement.isArrowLine(value));
7379
+ const vectorLineElements = drawElements.filter(value => PlaitDrawElement.isVectorLine(value));
7201
7380
  const imageElements = drawElements.filter(value => PlaitDrawElement.isImage(value));
7202
7381
  const tableElements = drawElements.filter(value => PlaitDrawElement.isTable(value));
7203
7382
  const swimlaneElements = drawElements.filter(value => PlaitDrawElement.isSwimlane(value));
@@ -7206,14 +7385,15 @@ const withDrawFragment = (baseBoard) => {
7206
7385
  ...getBoundedArrowLineElements(board, imageElements),
7207
7386
  ...getBoundedArrowLineElements(board, tableElements),
7208
7387
  ...getBoundedArrowLineElements(board, swimlaneElements)
7209
- ].filter(line => !lineElements.includes(line));
7388
+ ].filter(line => !arrowLineElements.includes(line));
7210
7389
  data.push(...[
7211
7390
  ...geometryElements,
7212
- ...lineElements,
7391
+ ...arrowLineElements,
7392
+ ...vectorLineElements,
7213
7393
  ...imageElements,
7214
7394
  ...tableElements,
7215
7395
  ...swimlaneElements,
7216
- ...boundLineElements.filter(line => !lineElements.includes(line))
7396
+ ...boundLineElements.filter(line => !arrowLineElements.includes(line))
7217
7397
  ]);
7218
7398
  }
7219
7399
  return getDeletedFragment(data);
@@ -7407,7 +7587,7 @@ const withArrowLineResize = (board) => {
7407
7587
  if (selectedLineElements.length > 0) {
7408
7588
  let result = null;
7409
7589
  selectedLineElements.forEach(value => {
7410
- const handleRef = getHitArrowLineResizeHandleRef(board, value, point);
7590
+ const handleRef = getHitLineResizeHandleRef(board, value, point);
7411
7591
  if (handleRef) {
7412
7592
  result = {
7413
7593
  element: value,
@@ -7422,8 +7602,8 @@ const withArrowLineResize = (board) => {
7422
7602
  },
7423
7603
  beforeResize: (resizeRef) => {
7424
7604
  if (resizeRef.element.shape === ArrowLineShape.elbow &&
7425
- resizeRef.handle !== ArrowLineResizeHandle.source &&
7426
- resizeRef.handle !== ArrowLineResizeHandle.target) {
7605
+ resizeRef.handle !== LineResizeHandle.source &&
7606
+ resizeRef.handle !== LineResizeHandle.target) {
7427
7607
  const params = getElbowLineRouteOptions(board, resizeRef.element);
7428
7608
  if (isUseDefaultOrthogonalRoute(resizeRef.element, params)) {
7429
7609
  return;
@@ -7445,8 +7625,8 @@ const withArrowLineResize = (board) => {
7445
7625
  let target = { ...resizeRef.element.target };
7446
7626
  let handleIndex = resizeRef.handleIndex;
7447
7627
  const hitElement = getSnappingShape(board, resizeState.endPoint);
7448
- if (resizeRef.handle === ArrowLineResizeHandle.source || resizeRef.handle === ArrowLineResizeHandle.target) {
7449
- const object = resizeRef.handle === ArrowLineResizeHandle.source ? source : target;
7628
+ if (resizeRef.handle === LineResizeHandle.source || resizeRef.handle === LineResizeHandle.target) {
7629
+ const object = resizeRef.handle === LineResizeHandle.source ? source : target;
7450
7630
  points[handleIndex] = resizeState.endPoint;
7451
7631
  if (hitElement) {
7452
7632
  object.connection = getHitConnection(board, resizeState.endPoint, hitElement);
@@ -7477,7 +7657,7 @@ const withArrowLineResize = (board) => {
7477
7657
  }
7478
7658
  }
7479
7659
  else {
7480
- if (resizeRef.handle === ArrowLineResizeHandle.addHandle) {
7660
+ if (resizeRef.handle === LineResizeHandle.addHandle) {
7481
7661
  points.splice(handleIndex + 1, 0, resizeState.endPoint);
7482
7662
  }
7483
7663
  else {
@@ -7486,7 +7666,7 @@ const withArrowLineResize = (board) => {
7486
7666
  }
7487
7667
  }
7488
7668
  if (!hitElement) {
7489
- handleIndex = resizeRef.handle === ArrowLineResizeHandle.addHandle ? handleIndex + 1 : handleIndex;
7669
+ handleIndex = resizeRef.handle === LineResizeHandle.addHandle ? handleIndex + 1 : handleIndex;
7490
7670
  const drawPoints = getArrowLinePoints(board, resizeRef.element);
7491
7671
  const newPoints = [...points];
7492
7672
  newPoints[0] = drawPoints[0];
@@ -7552,7 +7732,7 @@ const withArrowLineBoundReaction = (board) => {
7552
7732
  const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
7553
7733
  const isLineResizing = isResizingByCondition(board, resizeRef => {
7554
7734
  const { element, handle } = resizeRef;
7555
- const isSourceOrTarget = handle === ArrowLineResizeHandle.target || handle === ArrowLineResizeHandle.source;
7735
+ const isSourceOrTarget = handle === LineResizeHandle.target || handle === LineResizeHandle.source;
7556
7736
  return PlaitDrawElement.isArrowLine(element) && isSourceOrTarget;
7557
7737
  });
7558
7738
  if (isLinePointer || isLineResizing) {
@@ -8475,6 +8655,179 @@ const withSwimlane = (board) => {
8475
8655
  return withSwimlaneCreateByDrawing(withSwimlaneCreateByDrag(board));
8476
8656
  };
8477
8657
 
8658
+ const withVectorPenCreateByDraw = (board) => {
8659
+ const { pointerDown, pointerMove, dblClick, globalKeyDown } = board;
8660
+ let lineShapeG = null;
8661
+ let temporaryElement = null;
8662
+ let vectorPenRef;
8663
+ const vectorLineComplete = () => {
8664
+ if (vectorPenRef) {
8665
+ clearSelectedElement(board);
8666
+ if (vectorPenRef?.element) {
8667
+ addSelectedElement(board, vectorPenRef?.element);
8668
+ }
8669
+ }
8670
+ PlaitBoard.getBoardContainer(board).classList.remove(`vector-line-closed`);
8671
+ lineShapeG?.remove();
8672
+ lineShapeG = null;
8673
+ vectorPenRef = null;
8674
+ temporaryElement = null;
8675
+ };
8676
+ board.pointerDown = (event) => {
8677
+ const penPointers = getVectorPenPointers();
8678
+ const isVectorPenPointer = PlaitBoard.isInPointer(board, penPointers);
8679
+ if (isVectorPenPointer && !vectorPenRef) {
8680
+ vectorPenRef = { shape: VectorLineShape.straight };
8681
+ }
8682
+ if (!PlaitBoard.isReadonly(board) && vectorPenRef && isDrawingMode(board)) {
8683
+ let point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
8684
+ if (!temporaryElement) {
8685
+ vectorPenRef = {
8686
+ ...vectorPenRef,
8687
+ start: point
8688
+ };
8689
+ }
8690
+ else {
8691
+ if (!vectorPenRef.element) {
8692
+ vectorPenRef.element = temporaryElement;
8693
+ Transforms.insertNode(board, vectorPenRef.element, [board.children.length]);
8694
+ }
8695
+ else {
8696
+ let points = vectorPenRef.element.points;
8697
+ const isClosed = distanceBetweenPointAndPoint(...point, ...vectorPenRef.start) <= LINE_HIT_GEOMETRY_BUFFER;
8698
+ if (isClosed) {
8699
+ point = vectorPenRef.start;
8700
+ }
8701
+ if (vectorPenRef.path) {
8702
+ const lastPoint = points[points.length - 1];
8703
+ const distance = distanceBetweenPointAndPoint(...point, ...lastPoint);
8704
+ if (distance > 2) {
8705
+ Transforms.setNode(board, { points: [...points, point] }, vectorPenRef.path);
8706
+ }
8707
+ }
8708
+ vectorPenRef.element = getElementById(board, vectorPenRef.element.id);
8709
+ if (isClosed) {
8710
+ vectorLineComplete();
8711
+ }
8712
+ }
8713
+ preventTouchMove(board, event, true);
8714
+ }
8715
+ }
8716
+ pointerDown(event);
8717
+ };
8718
+ board.pointerMove = (event) => {
8719
+ lineShapeG?.remove();
8720
+ lineShapeG = createG();
8721
+ let movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
8722
+ const pointer = PlaitBoard.getPointer(board);
8723
+ if (pointer !== VectorPenPointerType.vectorPen) {
8724
+ vectorLineComplete();
8725
+ }
8726
+ if (vectorPenRef && vectorPenRef.start) {
8727
+ let drawPoints = [vectorPenRef.start];
8728
+ if (vectorPenRef.element) {
8729
+ drawPoints = [vectorPenRef.start, ...vectorPenRef.element.points];
8730
+ const path = PlaitBoard.findPath(board, vectorPenRef.element);
8731
+ vectorPenRef.path = path;
8732
+ }
8733
+ const distance = distanceBetweenPointAndPoint(...movingPoint, ...vectorPenRef.start);
8734
+ if (distance <= LINE_HIT_GEOMETRY_BUFFER) {
8735
+ movingPoint = vectorPenRef.start;
8736
+ PlaitBoard.getBoardContainer(board).classList.add(`vector-line-closed`);
8737
+ }
8738
+ else {
8739
+ PlaitBoard.getBoardContainer(board).classList.remove(`vector-line-closed`);
8740
+ }
8741
+ temporaryElement = vectorLineCreating(board, vectorPenRef.shape, drawPoints, movingPoint, lineShapeG);
8742
+ }
8743
+ pointerMove(event);
8744
+ };
8745
+ board.dblClick = (event) => {
8746
+ if (!PlaitBoard.isReadonly(board)) {
8747
+ if (vectorPenRef) {
8748
+ if (vectorPenRef.path) {
8749
+ Transforms.setNode(board, { points: vectorPenRef?.element?.points }, vectorPenRef.path);
8750
+ }
8751
+ vectorLineComplete();
8752
+ BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
8753
+ }
8754
+ }
8755
+ dblClick(event);
8756
+ };
8757
+ board.globalKeyDown = (event) => {
8758
+ if (!PlaitBoard.isReadonly(board)) {
8759
+ const isEsc = isKeyHotkey('esc', event);
8760
+ const isV = isKeyHotkey('v', event);
8761
+ if ((isEsc || isV) && vectorPenRef) {
8762
+ if (vectorPenRef.path) {
8763
+ Transforms.setNode(board, { points: vectorPenRef.element?.points }, vectorPenRef.path);
8764
+ }
8765
+ vectorLineComplete();
8766
+ if (isV) {
8767
+ BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
8768
+ }
8769
+ }
8770
+ }
8771
+ globalKeyDown(event);
8772
+ };
8773
+ return board;
8774
+ };
8775
+
8776
+ const withVectorLineResize = (board) => {
8777
+ const options = {
8778
+ key: 'draw-vector-line',
8779
+ canResize: () => {
8780
+ return true;
8781
+ },
8782
+ hitTest: (point) => {
8783
+ const selectedVectorLineElements = getSelectedVectorLineElements(board);
8784
+ if (selectedVectorLineElements.length > 0) {
8785
+ let result = null;
8786
+ selectedVectorLineElements.forEach(value => {
8787
+ const handleRef = getHitLineResizeHandleRef(board, value, point);
8788
+ if (handleRef) {
8789
+ result = {
8790
+ element: value,
8791
+ handle: handleRef.handle,
8792
+ handleIndex: handleRef.handleIndex
8793
+ };
8794
+ }
8795
+ });
8796
+ return result;
8797
+ }
8798
+ return null;
8799
+ },
8800
+ onResize: (resizeRef, resizeState) => {
8801
+ let points = [...resizeRef.element.points];
8802
+ let handleIndex = resizeRef.handleIndex;
8803
+ if (resizeRef.handle === LineResizeHandle.source || resizeRef.handle === LineResizeHandle.target) {
8804
+ points[handleIndex] = resizeState.endPoint;
8805
+ if (isClosedVectorLine(resizeRef.element)) {
8806
+ points[points.length - 1] = resizeState.endPoint;
8807
+ }
8808
+ else {
8809
+ const targetPoint = resizeRef.handle === LineResizeHandle.source ? points[points.length - 1] : points[0];
8810
+ const distance = distanceBetweenPointAndPoint(...resizeState.endPoint, ...targetPoint);
8811
+ if (distance <= LINE_HIT_GEOMETRY_BUFFER) {
8812
+ points[handleIndex] = targetPoint;
8813
+ }
8814
+ }
8815
+ }
8816
+ else {
8817
+ if (resizeRef.handle === LineResizeHandle.addHandle) {
8818
+ points.splice(handleIndex + 1, 0, resizeState.endPoint);
8819
+ }
8820
+ else {
8821
+ points[handleIndex] = resizeState.endPoint;
8822
+ }
8823
+ }
8824
+ Transforms.setNode(board, { points }, resizeRef.path);
8825
+ }
8826
+ };
8827
+ withResize(board, options);
8828
+ return board;
8829
+ };
8830
+
8478
8831
  const withDraw = (board) => {
8479
8832
  const { drawElement, getRectangle, isRectangleHit, isHit, isInsidePoint, isMovable, isAlign, getRelatedFragment, getHitElement } = board;
8480
8833
  board.drawElement = (context) => {
@@ -8487,6 +8840,9 @@ const withDraw = (board) => {
8487
8840
  else if (PlaitDrawElement.isArrowLine(context.element)) {
8488
8841
  return ArrowLineComponent;
8489
8842
  }
8843
+ else if (PlaitDrawElement.isVectorLine(context.element)) {
8844
+ return VectorLineComponent;
8845
+ }
8490
8846
  else if (PlaitDrawElement.isImage(context.element)) {
8491
8847
  return ImageComponent;
8492
8848
  }
@@ -8505,6 +8861,11 @@ const withDraw = (board) => {
8505
8861
  const linePointsRectangle = RectangleClient.getRectangleByPoints(points);
8506
8862
  return RectangleClient.getBoundingRectangle([linePointsRectangle, ...lineTextRectangles]);
8507
8863
  }
8864
+ if (PlaitDrawElement.isVectorLine(element)) {
8865
+ const points = getVectorLinePoints(board, element);
8866
+ const linePointsRectangle = RectangleClient.getRectangleByPoints(points);
8867
+ return RectangleClient.getBoundingRectangle([linePointsRectangle]);
8868
+ }
8508
8869
  if (PlaitDrawElement.isImage(element)) {
8509
8870
  return RectangleClient.getRectangleByPoints(element.points);
8510
8871
  }
@@ -8545,6 +8906,9 @@ const withDraw = (board) => {
8545
8906
  if (PlaitDrawElement.isImage(element)) {
8546
8907
  return true;
8547
8908
  }
8909
+ if (PlaitDrawElement.isVectorLine(element)) {
8910
+ return true;
8911
+ }
8548
8912
  if (PlaitDrawElement.isArrowLine(element)) {
8549
8913
  const selectedElements = getSelectedElements(board);
8550
8914
  const isSelected = (boundId) => {
@@ -8580,12 +8944,12 @@ const withDraw = (board) => {
8580
8944
  });
8581
8945
  return getRelatedFragment([...elements, ...activeLines], originData);
8582
8946
  };
8583
- return withSwimlane(withTable(withDrawResize(withArrowLineAutoCompleteReaction(withArrowLineBoundReaction(withArrowLineResize(withArrowLineTextMove(withArrowLineText(withGeometryResize(withDrawRotate(withArrowLineCreateByDraw(withArrowLineAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board))))))))))))))));
8947
+ return withSwimlane(withTable(withDrawResize(withVectorPenCreateByDraw(withArrowLineAutoCompleteReaction(withArrowLineBoundReaction(withVectorLineResize(withArrowLineResize(withArrowLineTextMove(withArrowLineText(withGeometryResize(withDrawRotate(withArrowLineCreateByDraw(withArrowLineAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board))))))))))))))))));
8584
8948
  };
8585
8949
 
8586
8950
  /**
8587
8951
  * Generated bundle index. Do not edit.
8588
8952
  */
8589
8953
 
8590
- export { ArrowLineActiveGenerator, 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, GeometryComponent, GeometryShapeGenerator, GeometryThreshold, KEY_TO_TEXT_MANAGE, LINE_HIT_GEOMETRY_BUFFER, LINE_SNAPPING_BUFFER, LINE_SNAPPING_CONNECTOR_BUFFER, MIN_TEXT_WIDTH, MemorizeKey, MultipleTextGeometryCommonTextKeys, MultipleTextGeometryTextKeys, PlaitArrowLine, PlaitDrawElement, PlaitGeometry, PlaitTableElement, Q2C, SELECTED_CELLS, SWIMLANE_HEADER_SIZE, ShapeDefaultSpace, SingleTextGenerator, StrokeStyle, SwimlaneDrawSymbols, SwimlaneSymbols, TableGenerator, TableSymbols, TextGenerator, UMLSymbols, VectorLineShape, WithArrowLineAutoCompletePluginKey, adjustSwimlaneShape, alignElbowSegment, alignPoints, buildDefaultTextsByShape, buildSwimlaneTable, clearSelectedCells, collectArrowLineUpdatedRefsByGeometry, createArrowLineElement, createCell, createDefaultCells, createDefaultFlowchart, createDefaultGeometry, createDefaultRowsOrColumns, createDefaultSwimlane, createGeometryElement, createGeometryElementWithText, createGeometryElementWithoutText, createMultipleTextGeometryElement, createTextElement, createUMLClassOrInterfaceGeometryElement, debugGenerator$1 as debugGenerator, deleteTextManage, drawArrowLine, drawArrowLineArrow, drawBoundReaction, drawGeometry, drawShape, editCell, editText, getArrowLineHandleRefPair, getArrowLinePointers, getArrowLinePoints, getArrowLineTextRectangle, getArrowLines, getAutoCompletePoints, getBasicPointers, getCellWithPoints, getCellsRectangle, getCellsWithPoints, getCenterPointsOnPolygon$1 as getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultBasicShapeProperty, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultSwimlanePoints, getDefaultTextPoints, getDefaultUMLProperty, getDrawDefaultStrokeColor, getDrawHitElement, getElbowLineRouteOptions, getElbowPoints, getFillByElement, getFirstFilledDrawElement, getFirstTextOrLineElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryAlign, getGeometryPointers, getHitCell, getHitConnection, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitMultipleGeometryText, getHitShape, getIndexAndDeleteCountByKeyPoint, getLineDashByElement, getLineMemorizedLatest, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getMidKeyPoints, getMiddlePoints, getMirrorDataPoints, getMultipleTextGeometryTextKeys, getNearestPoint, getNextRenderPoints, getNextSourceAndTargetPoints, getResizedPreviousAndNextPoint, getSelectedArrowLineElements, getSelectedCells, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedSwimlane, getSelectedTableCellsEditor, getSelectedTableElements, getSnapResizingRef, getSnapResizingRefOptions, getSnappingRef, getSnappingShape, getSourceAndTargetRectangle, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getSwimlaneCount, getSwimlanePointers, getTextKey, getTextManage, getTextManageByCell, getTextRectangle, getTextShapeProperty, getUMLPointers, getVectorByConnection, handleArrowLineCreating, hasIllegalElbowPoint, insertElement, isCellIncludeText, isDrawElementClosed, isDrawElementIncludeText, isDrawElementsIncludeText, isGeometryClosed, isGeometryIncludeText, isHitArrowLine, isHitArrowLineText, isHitDrawElement, isHitEdgeOfShape, isHitElementInside, isHitElementText, isHitPolyLine, isInsideOfShape, isMultipleTextGeometry, isMultipleTextShape, isRectangleHitDrawElement, isRectangleHitElementText, isSelfLoop, isSingleSelectElementByTable, isSingleSelectSwimlane, isSingleSelectTable, isSingleTextGeometry, isSingleTextShape, isSwimlanePointers, isSwimlaneWithHeader, isTextExceedingBounds, isUpdatedHandleIndex, isUseDefaultOrthogonalRoute, memorizeLatestShape, memorizeLatestText, rerenderGeometryActive, setSelectedCells, setTextManage, traverseDrawShapes, updateCellIds, updateCellIdsByRowOrColumn, updateColumns, updateRowOrColumnIds, updateRows, withArrowLineAutoComplete, withDraw };
8954
+ 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, GeometryComponent, GeometryShapeGenerator, GeometryThreshold, KEY_TO_TEXT_MANAGE, LINE_HIT_GEOMETRY_BUFFER, LINE_SNAPPING_BUFFER, LINE_SNAPPING_CONNECTOR_BUFFER, LineActiveGenerator, MIN_TEXT_WIDTH, MemorizeKey, MultipleTextGeometryCommonTextKeys, MultipleTextGeometryTextKeys, PlaitArrowLine, PlaitDrawElement, PlaitGeometry, PlaitTableElement, Q2C, SELECTED_CELLS, SWIMLANE_HEADER_SIZE, ShapeDefaultSpace, SingleTextGenerator, StrokeStyle, SwimlaneDrawSymbols, SwimlaneSymbols, TableGenerator, TableSymbols, TextGenerator, UMLSymbols, VectorLineComponent, VectorLineShape, VectorPenPointerType, WithArrowLineAutoCompletePluginKey, adjustSwimlaneShape, alignElbowSegment, alignPoints, buildDefaultTextsByShape, buildSwimlaneTable, clearSelectedCells, collectArrowLineUpdatedRefsByGeometry, createArrowLineElement, createCell, createDefaultCells, createDefaultFlowchart, 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$1 as getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultBasicShapeProperty, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultSwimlanePoints, getDefaultTextPoints, getDefaultUMLProperty, getDrawDefaultStrokeColor, getDrawHitElement, getElbowLineRouteOptions, getElbowPoints, getFillByElement, getFirstFilledDrawElement, getFirstTextOrLineElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryAlign, getGeometryPointers, getHitCell, getHitConnection, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitMultipleGeometryText, getHitShape, getIndexAndDeleteCountByKeyPoint, getLineDashByElement, getLineMemorizedLatest, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getMidKeyPoints, getMiddlePoints, getMirrorDataPoints, getMultipleTextGeometryTextKeys, getNearestPoint, getNextRenderPoints, getNextSourceAndTargetPoints, getResizedPreviousAndNextPoint, getSelectedArrowLineElements, getSelectedCells, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedSwimlane, getSelectedTableCellsEditor, getSelectedTableElements, getSelectedVectorLineElements, getSnapResizingRef, getSnapResizingRefOptions, getSnappingRef, getSnappingShape, getSourceAndTargetRectangle, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getSwimlaneCount, getSwimlanePointers, getTextKey, getTextManage, getTextManageByCell, getTextRectangle, getTextShapeProperty, getUMLPointers, getVectorByConnection, getVectorLinePoints, getVectorPenPointers, handleArrowLineCreating, hasIllegalElbowPoint, insertElement, isCellIncludeText, isClosedVectorLine, isDrawElementClosed, isDrawElementIncludeText, isDrawElementsIncludeText, isGeometryClosed, isGeometryIncludeText, isHitArrowLine, isHitArrowLineText, isHitDrawElement, isHitEdgeOfShape, isHitElementInside, isHitElementText, isHitPolyLine, isHitVectorLine, isInsideOfShape, isMultipleTextGeometry, isMultipleTextShape, isRectangleHitDrawElement, isRectangleHitElementText, isSelfLoop, isSingleSelectElementByTable, isSingleSelectSwimlane, isSingleSelectTable, isSingleTextGeometry, isSingleTextShape, isSwimlanePointers, isSwimlaneWithHeader, isTextExceedingBounds, isUpdatedHandleIndex, isUseDefaultOrthogonalRoute, memorizeLatestShape, memorizeLatestText, rerenderGeometryActive, setSelectedCells, setTextManage, traverseDrawShapes, updateCellIds, updateCellIdsByRowOrColumn, updateColumns, updateRowOrColumnIds, updateRows, vectorLineCreating, withArrowLineAutoComplete, withDraw };
8591
8955
  //# sourceMappingURL=plait-draw.mjs.map