@plait/draw 0.63.0 → 0.64.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.
Files changed (60) 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 +12 -1
  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 +500 -145
  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 +2 -1
  46. package/transforms/vector-line.d.ts +3 -0
  47. package/utils/arrow-line/arrow-line-basic.d.ts +0 -1
  48. package/utils/clipboard.d.ts +1 -1
  49. package/utils/geometry.d.ts +17 -17
  50. package/utils/hit.d.ts +3 -2
  51. package/utils/index.d.ts +2 -0
  52. package/utils/line.d.ts +3 -0
  53. package/utils/position/arrow-line.d.ts +0 -13
  54. package/utils/position/line.d.ts +15 -0
  55. package/utils/selected.d.ts +2 -1
  56. package/utils/shape.d.ts +1 -1
  57. package/utils/vector-line.d.ts +7 -0
  58. package/vector-line.component.d.ts +14 -0
  59. package/esm2022/generators/arrow-line-active.generator.mjs +0 -81
  60. 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, 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, 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, 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,10 @@ 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
+ return isHitPolyLine(points, point);
1054
+ };
1005
1055
  const isRectangleHitElementText = (element, rectangle) => {
1006
1056
  const engine = getEngine(element.shape);
1007
1057
  if (isMultipleTextGeometry(element)) {
@@ -1115,6 +1165,9 @@ const isHitDrawElement = (board, element, point) => {
1115
1165
  if (PlaitDrawElement.isArrowLine(element)) {
1116
1166
  return isHitArrowLine(board, element, point);
1117
1167
  }
1168
+ if (PlaitDrawElement.isVectorLine(element)) {
1169
+ return isHitVectorLine(board, element, point);
1170
+ }
1118
1171
  return null;
1119
1172
  };
1120
1173
  const isHitEdgeOfShape = (board, element, point, hitDistanceBuffer) => {
@@ -1149,6 +1202,9 @@ const isHitElementInside = (board, element, point) => {
1149
1202
  if (PlaitDrawElement.isArrowLine(element)) {
1150
1203
  return isHitArrowLine(board, element, point);
1151
1204
  }
1205
+ if (PlaitDrawElement.isVectorLine(element)) {
1206
+ return isHitVectorLine(board, element, point);
1207
+ }
1152
1208
  return null;
1153
1209
  };
1154
1210
 
@@ -1206,6 +1262,9 @@ const isDrawElementClosed = (element) => {
1206
1262
  if (PlaitDrawElement.isText(element) || PlaitDrawElement.isArrowLine(element) || PlaitDrawElement.isImage(element)) {
1207
1263
  return false;
1208
1264
  }
1265
+ if (PlaitDrawElement.isVectorLine(element)) {
1266
+ return isClosedVectorLine(element);
1267
+ }
1209
1268
  if (PlaitDrawElement.isGeometry(element)) {
1210
1269
  return isGeometryClosed(element);
1211
1270
  }
@@ -1333,29 +1392,6 @@ const getStrokeStyleByElement = (element) => {
1333
1392
  return element.strokeStyle || StrokeStyle.solid;
1334
1393
  };
1335
1394
 
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
1395
  const debugKey$3 = 'debug:plait:line-mirror';
1360
1396
  const debugGenerator$3 = createDebugGenerator(debugKey$3);
1361
1397
  const alignPoints = (basePoint, movingPoint) => {
@@ -1780,6 +1816,17 @@ const drawHollowTriangleArrow = (source, target, options) => {
1780
1816
  return drawLinearPath([pointLeft, pointRight, target], { ...options, fill: 'white' }, true);
1781
1817
  };
1782
1818
 
1819
+ class ArrowLineShapeGenerator extends Generator {
1820
+ canDraw(element) {
1821
+ return true;
1822
+ }
1823
+ draw(element) {
1824
+ let lineG;
1825
+ lineG = drawArrowLine(this.board, element);
1826
+ return lineG;
1827
+ }
1828
+ }
1829
+
1783
1830
  const createArrowLineElement = (shape, points, source, target, texts, options) => {
1784
1831
  return {
1785
1832
  id: idCreator(),
@@ -1845,59 +1892,6 @@ const getCurvePoints = (board, element) => {
1845
1892
  return pointsOnBezierCurves(points);
1846
1893
  }
1847
1894
  };
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
1895
  const drawArrowLine = (board, element) => {
1902
1896
  const strokeWidth = getStrokeWidthByElement(element);
1903
1897
  const strokeColor = getStrokeColorByElement(board, element);
@@ -2455,6 +2449,10 @@ const getSelectedArrowLineElements = (board) => {
2455
2449
  const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isArrowLine(value));
2456
2450
  return selectedElements;
2457
2451
  };
2452
+ const getSelectedVectorLineElements = (board) => {
2453
+ const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isVectorLine(value));
2454
+ return selectedElements;
2455
+ };
2458
2456
  const getSelectedImageElements = (board) => {
2459
2457
  const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isImage(value));
2460
2458
  return selectedElements;
@@ -3004,6 +3002,17 @@ const setTableFill = (board, element, fill, path) => {
3004
3002
  Transforms.setNode(board, { cells: newCells }, path);
3005
3003
  };
3006
3004
 
3005
+ const setVectorLineShape = (board, newProperties) => {
3006
+ const elements = getSelectedVectorLineElements(board);
3007
+ elements.map(element => {
3008
+ if (element.shape === newProperties.shape) {
3009
+ return;
3010
+ }
3011
+ const path = PlaitBoard.findPath(board, element);
3012
+ Transforms.setNode(board, { ...newProperties }, path);
3013
+ });
3014
+ };
3015
+
3007
3016
  const insertDrawByVector = (board, point, shape, vector) => {
3008
3017
  const swimlanePointers = getSwimlanePointers();
3009
3018
  const isSwimlanePointer = swimlanePointers.includes(shape);
@@ -3047,6 +3056,7 @@ const DrawTransforms = {
3047
3056
  removeArrowLineText,
3048
3057
  setArrowLineMark,
3049
3058
  setArrowLineShape,
3059
+ setVectorLineShape,
3050
3060
  insertImage,
3051
3061
  connectArrowLineToDraw,
3052
3062
  switchGeometryShape,
@@ -3520,6 +3530,66 @@ function drawIsometricSnapLines(board, activePoints, snapRectangles, resizeSnapO
3520
3530
  return drawSolidLines(board, isometricLines);
3521
3531
  }
3522
3532
 
3533
+ function getMiddlePoints(board, element) {
3534
+ const result = [];
3535
+ const shape = element.shape;
3536
+ const hideBuffer = 10;
3537
+ if (shape === ArrowLineShape.straight) {
3538
+ const points = PlaitDrawElement.isArrowLine(element)
3539
+ ? PlaitArrowLine.getPoints(board, element)
3540
+ : element.points;
3541
+ for (let i = 0; i < points.length - 1; i++) {
3542
+ const distance = distanceBetweenPointAndPoint(...points[i], ...points[i + 1]);
3543
+ if (distance < hideBuffer)
3544
+ continue;
3545
+ result.push([(points[i][0] + points[i + 1][0]) / 2, (points[i][1] + points[i + 1][1]) / 2]);
3546
+ }
3547
+ }
3548
+ if (shape === ArrowLineShape.curve) {
3549
+ const points = PlaitDrawElement.isArrowLine(element)
3550
+ ? PlaitArrowLine.getPoints(board, element)
3551
+ : element.points;
3552
+ const pointsOnBezier = PlaitDrawElement.isArrowLine(element)
3553
+ ? getCurvePoints(board, element)
3554
+ : getVectorLinePoints(board, element);
3555
+ if (points.length === 2) {
3556
+ const start = 0;
3557
+ const endIndex = pointsOnBezier.length - 1;
3558
+ const middleIndex = Math.round((start + endIndex) / 2);
3559
+ result.push(pointsOnBezier[middleIndex]);
3560
+ }
3561
+ else {
3562
+ for (let i = 0; i < points.length - 1; i++) {
3563
+ const startIndex = pointsOnBezier.findIndex(point => point[0] === points[i][0] && point[1] === points[i][1]);
3564
+ const endIndex = pointsOnBezier.findIndex(point => point[0] === points[i + 1][0] && point[1] === points[i + 1][1]);
3565
+ const middleIndex = Math.round((startIndex + endIndex) / 2);
3566
+ const distance = distanceBetweenPointAndPoint(...points[i], ...points[i + 1]);
3567
+ if (distance < hideBuffer)
3568
+ continue;
3569
+ result.push(pointsOnBezier[middleIndex]);
3570
+ }
3571
+ }
3572
+ }
3573
+ if (shape === ArrowLineShape.elbow) {
3574
+ const renderPoints = getElbowPoints(board, element);
3575
+ const options = getElbowLineRouteOptions(board, element);
3576
+ if (!isUseDefaultOrthogonalRoute(element, options)) {
3577
+ const [nextSourcePoint, nextTargetPoint] = getNextSourceAndTargetPoints(board, element);
3578
+ for (let i = 0; i < renderPoints.length - 1; i++) {
3579
+ if ((i == 0 && Point.isEquals(renderPoints[i + 1], nextSourcePoint)) ||
3580
+ (i === renderPoints.length - 2 && Point.isEquals(renderPoints[renderPoints.length - 2], nextTargetPoint))) {
3581
+ continue;
3582
+ }
3583
+ const [currentX, currentY] = renderPoints[i];
3584
+ const [nextX, nextY] = renderPoints[i + 1];
3585
+ const middlePoint = [(currentX + nextX) / 2, (currentY + nextY) / 2];
3586
+ result.push(middlePoint);
3587
+ }
3588
+ }
3589
+ }
3590
+ return result;
3591
+ }
3592
+
3523
3593
  const getCenterPointsOnPolygon = (points) => {
3524
3594
  const centerPoints = [];
3525
3595
  for (let i = 0; i < points.length; i++) {
@@ -6378,6 +6448,10 @@ var MemorizeKey;
6378
6448
  MemorizeKey["UML"] = "UML";
6379
6449
  })(MemorizeKey || (MemorizeKey = {}));
6380
6450
 
6451
+ var VectorPenPointerType;
6452
+ (function (VectorPenPointerType) {
6453
+ VectorPenPointerType["vectorPen"] = "vectorPen";
6454
+ })(VectorPenPointerType || (VectorPenPointerType = {}));
6381
6455
  var VectorLineShape;
6382
6456
  (function (VectorLineShape) {
6383
6457
  VectorLineShape["straight"] = "straight";
@@ -6388,12 +6462,15 @@ const PlaitDrawElement = {
6388
6462
  isGeometry: (value) => {
6389
6463
  return value.type === 'geometry';
6390
6464
  },
6391
- // isLine: (value: any): value is PlaitArrowLine => {
6392
- // return value.type === 'arrow-line' || value.type === 'line' || value.type === 'vector-line';
6393
- // },
6394
6465
  isArrowLine: (value) => {
6395
6466
  return value.type === 'arrow-line' || value.type === 'line';
6396
6467
  },
6468
+ isVectorLine: (value) => {
6469
+ return value.type === 'vector-line';
6470
+ },
6471
+ isLine: (value) => {
6472
+ return PlaitDrawElement.isArrowLine(value) || PlaitDrawElement.isVectorLine(value);
6473
+ },
6397
6474
  isText: (value) => {
6398
6475
  return value.type === 'geometry' && value.shape === BasicShapes.text;
6399
6476
  },
@@ -6405,7 +6482,7 @@ const PlaitDrawElement = {
6405
6482
  },
6406
6483
  isDrawElement: (value) => {
6407
6484
  if (PlaitDrawElement.isGeometry(value) ||
6408
- PlaitDrawElement.isArrowLine(value) ||
6485
+ PlaitDrawElement.isLine(value) ||
6409
6486
  PlaitDrawElement.isImage(value) ||
6410
6487
  PlaitDrawElement.isTable(value) ||
6411
6488
  PlaitDrawElement.isSwimlane(value)) {
@@ -6656,7 +6733,54 @@ class GeometryComponent extends CommonElementFlavour {
6656
6733
  }
6657
6734
  }
6658
6735
 
6659
- class ArrowLineActiveGenerator extends Generator {
6736
+ var LineResizeHandle;
6737
+ (function (LineResizeHandle) {
6738
+ LineResizeHandle["source"] = "source";
6739
+ LineResizeHandle["target"] = "target";
6740
+ LineResizeHandle["addHandle"] = "addHandle";
6741
+ })(LineResizeHandle || (LineResizeHandle = {}));
6742
+ const getHitLineResizeHandleRef = (board, element, point) => {
6743
+ let dataPoints = PlaitDrawElement.isArrowLine(element) ? PlaitArrowLine.getPoints(board, element) : element.points;
6744
+ const index = getHitPointIndex(dataPoints, point);
6745
+ if (index !== -1) {
6746
+ const handleIndex = index;
6747
+ if (index === 0) {
6748
+ return { handle: LineResizeHandle.source, handleIndex };
6749
+ }
6750
+ if (index === dataPoints.length - 1) {
6751
+ return { handle: LineResizeHandle.target, handleIndex };
6752
+ }
6753
+ // elbow line, data points only verify source connection point and target connection point
6754
+ if (element.shape !== ArrowLineShape.elbow) {
6755
+ return { handleIndex };
6756
+ }
6757
+ }
6758
+ const middlePoints = getMiddlePoints(board, element);
6759
+ const indexOfMiddlePoints = getHitPointIndex(middlePoints, point);
6760
+ if (indexOfMiddlePoints !== -1) {
6761
+ return {
6762
+ handle: LineResizeHandle.addHandle,
6763
+ handleIndex: indexOfMiddlePoints
6764
+ };
6765
+ }
6766
+ return undefined;
6767
+ };
6768
+ function getHitPointIndex(points, movingPoint) {
6769
+ const rectangles = points.map(point => {
6770
+ return {
6771
+ x: point[0] - RESIZE_HANDLE_DIAMETER / 2,
6772
+ y: point[1] - RESIZE_HANDLE_DIAMETER / 2,
6773
+ width: RESIZE_HANDLE_DIAMETER,
6774
+ height: RESIZE_HANDLE_DIAMETER
6775
+ };
6776
+ });
6777
+ const rectangle = rectangles.find(rectangle => {
6778
+ return RectangleClient.isHit(RectangleClient.getRectangleByPoints([movingPoint, movingPoint]), rectangle);
6779
+ });
6780
+ return rectangle ? rectangles.indexOf(rectangle) : -1;
6781
+ }
6782
+
6783
+ class LineActiveGenerator extends Generator {
6660
6784
  constructor() {
6661
6785
  super(...arguments);
6662
6786
  this.onlySelectedCurrentLine = false;
@@ -6676,7 +6800,7 @@ class ArrowLineActiveGenerator extends Generator {
6676
6800
  if (this.onlySelectedCurrentLine) {
6677
6801
  activeG.classList.add('active');
6678
6802
  activeG.classList.add('line-handle');
6679
- const points = PlaitArrowLine.getPoints(this.board, element);
6803
+ const points = PlaitDrawElement.isArrowLine(element) ? PlaitArrowLine.getPoints(this.board, element) : element.points;
6680
6804
  let updatePoints = [...points];
6681
6805
  let elbowNextRenderPoints = [];
6682
6806
  if (element.shape === ArrowLineShape.elbow) {
@@ -6738,7 +6862,7 @@ class ArrowLineComponent extends CommonElementFlavour {
6738
6862
  }
6739
6863
  initializeGenerator() {
6740
6864
  this.shapeGenerator = new ArrowLineShapeGenerator(this.board);
6741
- this.activeGenerator = new ArrowLineActiveGenerator(this.board);
6865
+ this.activeGenerator = new LineActiveGenerator(this.board);
6742
6866
  this.initializeTextManagesByElement();
6743
6867
  }
6744
6868
  initialize() {
@@ -6878,6 +7002,51 @@ class ArrowLineComponent extends CommonElementFlavour {
6878
7002
  }
6879
7003
  }
6880
7004
 
7005
+ class VectorLineComponent extends CommonElementFlavour {
7006
+ constructor() {
7007
+ super();
7008
+ }
7009
+ initializeGenerator() {
7010
+ this.shapeGenerator = new VectorLineShapeGenerator(this.board);
7011
+ this.activeGenerator = new LineActiveGenerator(this.board);
7012
+ }
7013
+ initialize() {
7014
+ this.initializeGenerator();
7015
+ this.shapeGenerator.processDrawing(this.element, this.getElementG());
7016
+ const linePoints = getVectorLinePoints(this.board, this.element);
7017
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
7018
+ selected: this.selected,
7019
+ linePoints
7020
+ });
7021
+ super.initialize();
7022
+ }
7023
+ onContextChanged(value, previous) {
7024
+ this.initializeWeakMap();
7025
+ const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
7026
+ const linePoints = getVectorLinePoints(this.board, this.element);
7027
+ if (value.element !== previous.element || isChangeTheme) {
7028
+ this.shapeGenerator.processDrawing(this.element, this.getElementG());
7029
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
7030
+ selected: this.selected,
7031
+ linePoints
7032
+ });
7033
+ }
7034
+ else {
7035
+ const needUpdate = value.selected !== previous.selected || this.activeGenerator.needUpdate();
7036
+ if (needUpdate) {
7037
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
7038
+ selected: this.selected,
7039
+ linePoints
7040
+ });
7041
+ }
7042
+ }
7043
+ }
7044
+ destroy() {
7045
+ super.destroy();
7046
+ this.activeGenerator.destroy();
7047
+ }
7048
+ }
7049
+
6881
7050
  const withDrawHotkey = (board) => {
6882
7051
  const { keyDown, dblClick } = board;
6883
7052
  board.keyDown = (event) => {
@@ -7197,7 +7366,8 @@ const withDrawFragment = (baseBoard) => {
7197
7366
  const drawElements = getSelectedDrawElements(board);
7198
7367
  if (drawElements.length) {
7199
7368
  const geometryElements = drawElements.filter(value => PlaitDrawElement.isGeometry(value));
7200
- const lineElements = drawElements.filter(value => PlaitDrawElement.isArrowLine(value));
7369
+ const arrowLineElements = drawElements.filter(value => PlaitDrawElement.isArrowLine(value));
7370
+ const vectorLineElements = drawElements.filter(value => PlaitDrawElement.isVectorLine(value));
7201
7371
  const imageElements = drawElements.filter(value => PlaitDrawElement.isImage(value));
7202
7372
  const tableElements = drawElements.filter(value => PlaitDrawElement.isTable(value));
7203
7373
  const swimlaneElements = drawElements.filter(value => PlaitDrawElement.isSwimlane(value));
@@ -7206,14 +7376,15 @@ const withDrawFragment = (baseBoard) => {
7206
7376
  ...getBoundedArrowLineElements(board, imageElements),
7207
7377
  ...getBoundedArrowLineElements(board, tableElements),
7208
7378
  ...getBoundedArrowLineElements(board, swimlaneElements)
7209
- ].filter(line => !lineElements.includes(line));
7379
+ ].filter(line => !arrowLineElements.includes(line));
7210
7380
  data.push(...[
7211
7381
  ...geometryElements,
7212
- ...lineElements,
7382
+ ...arrowLineElements,
7383
+ ...vectorLineElements,
7213
7384
  ...imageElements,
7214
7385
  ...tableElements,
7215
7386
  ...swimlaneElements,
7216
- ...boundLineElements.filter(line => !lineElements.includes(line))
7387
+ ...boundLineElements.filter(line => !arrowLineElements.includes(line))
7217
7388
  ]);
7218
7389
  }
7219
7390
  return getDeletedFragment(data);
@@ -7407,7 +7578,7 @@ const withArrowLineResize = (board) => {
7407
7578
  if (selectedLineElements.length > 0) {
7408
7579
  let result = null;
7409
7580
  selectedLineElements.forEach(value => {
7410
- const handleRef = getHitArrowLineResizeHandleRef(board, value, point);
7581
+ const handleRef = getHitLineResizeHandleRef(board, value, point);
7411
7582
  if (handleRef) {
7412
7583
  result = {
7413
7584
  element: value,
@@ -7422,8 +7593,8 @@ const withArrowLineResize = (board) => {
7422
7593
  },
7423
7594
  beforeResize: (resizeRef) => {
7424
7595
  if (resizeRef.element.shape === ArrowLineShape.elbow &&
7425
- resizeRef.handle !== ArrowLineResizeHandle.source &&
7426
- resizeRef.handle !== ArrowLineResizeHandle.target) {
7596
+ resizeRef.handle !== LineResizeHandle.source &&
7597
+ resizeRef.handle !== LineResizeHandle.target) {
7427
7598
  const params = getElbowLineRouteOptions(board, resizeRef.element);
7428
7599
  if (isUseDefaultOrthogonalRoute(resizeRef.element, params)) {
7429
7600
  return;
@@ -7445,8 +7616,8 @@ const withArrowLineResize = (board) => {
7445
7616
  let target = { ...resizeRef.element.target };
7446
7617
  let handleIndex = resizeRef.handleIndex;
7447
7618
  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;
7619
+ if (resizeRef.handle === LineResizeHandle.source || resizeRef.handle === LineResizeHandle.target) {
7620
+ const object = resizeRef.handle === LineResizeHandle.source ? source : target;
7450
7621
  points[handleIndex] = resizeState.endPoint;
7451
7622
  if (hitElement) {
7452
7623
  object.connection = getHitConnection(board, resizeState.endPoint, hitElement);
@@ -7477,7 +7648,7 @@ const withArrowLineResize = (board) => {
7477
7648
  }
7478
7649
  }
7479
7650
  else {
7480
- if (resizeRef.handle === ArrowLineResizeHandle.addHandle) {
7651
+ if (resizeRef.handle === LineResizeHandle.addHandle) {
7481
7652
  points.splice(handleIndex + 1, 0, resizeState.endPoint);
7482
7653
  }
7483
7654
  else {
@@ -7486,7 +7657,7 @@ const withArrowLineResize = (board) => {
7486
7657
  }
7487
7658
  }
7488
7659
  if (!hitElement) {
7489
- handleIndex = resizeRef.handle === ArrowLineResizeHandle.addHandle ? handleIndex + 1 : handleIndex;
7660
+ handleIndex = resizeRef.handle === LineResizeHandle.addHandle ? handleIndex + 1 : handleIndex;
7490
7661
  const drawPoints = getArrowLinePoints(board, resizeRef.element);
7491
7662
  const newPoints = [...points];
7492
7663
  newPoints[0] = drawPoints[0];
@@ -7552,7 +7723,7 @@ const withArrowLineBoundReaction = (board) => {
7552
7723
  const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
7553
7724
  const isLineResizing = isResizingByCondition(board, resizeRef => {
7554
7725
  const { element, handle } = resizeRef;
7555
- const isSourceOrTarget = handle === ArrowLineResizeHandle.target || handle === ArrowLineResizeHandle.source;
7726
+ const isSourceOrTarget = handle === LineResizeHandle.target || handle === LineResizeHandle.source;
7556
7727
  return PlaitDrawElement.isArrowLine(element) && isSourceOrTarget;
7557
7728
  });
7558
7729
  if (isLinePointer || isLineResizing) {
@@ -8475,6 +8646,179 @@ const withSwimlane = (board) => {
8475
8646
  return withSwimlaneCreateByDrawing(withSwimlaneCreateByDrag(board));
8476
8647
  };
8477
8648
 
8649
+ const withVectorPenCreateByDraw = (board) => {
8650
+ const { pointerDown, pointerMove, dblClick, globalKeyDown } = board;
8651
+ let lineShapeG = null;
8652
+ let temporaryElement = null;
8653
+ let vectorPenRef;
8654
+ const vectorLineComplete = () => {
8655
+ if (vectorPenRef) {
8656
+ clearSelectedElement(board);
8657
+ if (vectorPenRef?.element) {
8658
+ addSelectedElement(board, vectorPenRef?.element);
8659
+ }
8660
+ }
8661
+ PlaitBoard.getBoardContainer(board).classList.remove(`vector-line-closed`);
8662
+ lineShapeG?.remove();
8663
+ lineShapeG = null;
8664
+ vectorPenRef = null;
8665
+ temporaryElement = null;
8666
+ };
8667
+ board.pointerDown = (event) => {
8668
+ const penPointers = getVectorPenPointers();
8669
+ const isVectorPenPointer = PlaitBoard.isInPointer(board, penPointers);
8670
+ if (isVectorPenPointer && !vectorPenRef) {
8671
+ vectorPenRef = { shape: VectorLineShape.straight };
8672
+ }
8673
+ if (!PlaitBoard.isReadonly(board) && vectorPenRef && isDrawingMode(board)) {
8674
+ let point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
8675
+ if (!temporaryElement) {
8676
+ vectorPenRef = {
8677
+ ...vectorPenRef,
8678
+ start: point
8679
+ };
8680
+ }
8681
+ else {
8682
+ if (!vectorPenRef.element) {
8683
+ vectorPenRef.element = temporaryElement;
8684
+ Transforms.insertNode(board, vectorPenRef.element, [board.children.length]);
8685
+ }
8686
+ else {
8687
+ let points = vectorPenRef.element.points;
8688
+ const isClosed = distanceBetweenPointAndPoint(...point, ...vectorPenRef.start) <= LINE_HIT_GEOMETRY_BUFFER;
8689
+ if (isClosed) {
8690
+ point = vectorPenRef.start;
8691
+ }
8692
+ if (vectorPenRef.path) {
8693
+ const lastPoint = points[points.length - 1];
8694
+ const distance = distanceBetweenPointAndPoint(...point, ...lastPoint);
8695
+ if (distance > 2) {
8696
+ Transforms.setNode(board, { points: [...points, point] }, vectorPenRef.path);
8697
+ }
8698
+ }
8699
+ vectorPenRef.element = getElementById(board, vectorPenRef.element.id);
8700
+ if (isClosed) {
8701
+ vectorLineComplete();
8702
+ }
8703
+ }
8704
+ preventTouchMove(board, event, true);
8705
+ }
8706
+ }
8707
+ pointerDown(event);
8708
+ };
8709
+ board.pointerMove = (event) => {
8710
+ lineShapeG?.remove();
8711
+ lineShapeG = createG();
8712
+ let movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
8713
+ const pointer = PlaitBoard.getPointer(board);
8714
+ if (pointer !== VectorPenPointerType.vectorPen) {
8715
+ vectorLineComplete();
8716
+ }
8717
+ if (vectorPenRef && vectorPenRef.start) {
8718
+ let drawPoints = [vectorPenRef.start];
8719
+ if (vectorPenRef.element) {
8720
+ drawPoints = [vectorPenRef.start, ...vectorPenRef.element.points];
8721
+ const path = PlaitBoard.findPath(board, vectorPenRef.element);
8722
+ vectorPenRef.path = path;
8723
+ }
8724
+ const distance = distanceBetweenPointAndPoint(...movingPoint, ...vectorPenRef.start);
8725
+ if (distance <= LINE_HIT_GEOMETRY_BUFFER) {
8726
+ movingPoint = vectorPenRef.start;
8727
+ PlaitBoard.getBoardContainer(board).classList.add(`vector-line-closed`);
8728
+ }
8729
+ else {
8730
+ PlaitBoard.getBoardContainer(board).classList.remove(`vector-line-closed`);
8731
+ }
8732
+ temporaryElement = vectorLineCreating(board, vectorPenRef.shape, drawPoints, movingPoint, lineShapeG);
8733
+ }
8734
+ pointerMove(event);
8735
+ };
8736
+ board.dblClick = (event) => {
8737
+ if (!PlaitBoard.isReadonly(board)) {
8738
+ if (vectorPenRef) {
8739
+ if (vectorPenRef.path) {
8740
+ Transforms.setNode(board, { points: vectorPenRef?.element?.points }, vectorPenRef.path);
8741
+ }
8742
+ vectorLineComplete();
8743
+ BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
8744
+ }
8745
+ }
8746
+ dblClick(event);
8747
+ };
8748
+ board.globalKeyDown = (event) => {
8749
+ if (!PlaitBoard.isReadonly(board)) {
8750
+ const isEsc = isKeyHotkey('esc', event);
8751
+ const isV = isKeyHotkey('v', event);
8752
+ if ((isEsc || isV) && vectorPenRef) {
8753
+ if (vectorPenRef.path) {
8754
+ Transforms.setNode(board, { points: vectorPenRef.element?.points }, vectorPenRef.path);
8755
+ }
8756
+ vectorLineComplete();
8757
+ if (isV) {
8758
+ BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
8759
+ }
8760
+ }
8761
+ }
8762
+ globalKeyDown(event);
8763
+ };
8764
+ return board;
8765
+ };
8766
+
8767
+ const withVectorLineResize = (board) => {
8768
+ const options = {
8769
+ key: 'draw-vector-line',
8770
+ canResize: () => {
8771
+ return true;
8772
+ },
8773
+ hitTest: (point) => {
8774
+ const selectedVectorLineElements = getSelectedVectorLineElements(board);
8775
+ if (selectedVectorLineElements.length > 0) {
8776
+ let result = null;
8777
+ selectedVectorLineElements.forEach(value => {
8778
+ const handleRef = getHitLineResizeHandleRef(board, value, point);
8779
+ if (handleRef) {
8780
+ result = {
8781
+ element: value,
8782
+ handle: handleRef.handle,
8783
+ handleIndex: handleRef.handleIndex
8784
+ };
8785
+ }
8786
+ });
8787
+ return result;
8788
+ }
8789
+ return null;
8790
+ },
8791
+ onResize: (resizeRef, resizeState) => {
8792
+ let points = [...resizeRef.element.points];
8793
+ let handleIndex = resizeRef.handleIndex;
8794
+ if (resizeRef.handle === LineResizeHandle.source || resizeRef.handle === LineResizeHandle.target) {
8795
+ points[handleIndex] = resizeState.endPoint;
8796
+ if (isClosedVectorLine(resizeRef.element)) {
8797
+ points[points.length - 1] = resizeState.endPoint;
8798
+ }
8799
+ else {
8800
+ const targetPoint = resizeRef.handle === LineResizeHandle.source ? points[points.length - 1] : points[0];
8801
+ const distance = distanceBetweenPointAndPoint(...resizeState.endPoint, ...targetPoint);
8802
+ if (distance <= LINE_HIT_GEOMETRY_BUFFER) {
8803
+ points[handleIndex] = targetPoint;
8804
+ }
8805
+ }
8806
+ }
8807
+ else {
8808
+ if (resizeRef.handle === LineResizeHandle.addHandle) {
8809
+ points.splice(handleIndex + 1, 0, resizeState.endPoint);
8810
+ }
8811
+ else {
8812
+ points[handleIndex] = resizeState.endPoint;
8813
+ }
8814
+ }
8815
+ Transforms.setNode(board, { points }, resizeRef.path);
8816
+ }
8817
+ };
8818
+ withResize(board, options);
8819
+ return board;
8820
+ };
8821
+
8478
8822
  const withDraw = (board) => {
8479
8823
  const { drawElement, getRectangle, isRectangleHit, isHit, isInsidePoint, isMovable, isAlign, getRelatedFragment, getHitElement } = board;
8480
8824
  board.drawElement = (context) => {
@@ -8487,6 +8831,9 @@ const withDraw = (board) => {
8487
8831
  else if (PlaitDrawElement.isArrowLine(context.element)) {
8488
8832
  return ArrowLineComponent;
8489
8833
  }
8834
+ else if (PlaitDrawElement.isVectorLine(context.element)) {
8835
+ return VectorLineComponent;
8836
+ }
8490
8837
  else if (PlaitDrawElement.isImage(context.element)) {
8491
8838
  return ImageComponent;
8492
8839
  }
@@ -8505,6 +8852,11 @@ const withDraw = (board) => {
8505
8852
  const linePointsRectangle = RectangleClient.getRectangleByPoints(points);
8506
8853
  return RectangleClient.getBoundingRectangle([linePointsRectangle, ...lineTextRectangles]);
8507
8854
  }
8855
+ if (PlaitDrawElement.isVectorLine(element)) {
8856
+ const points = getVectorLinePoints(board, element);
8857
+ const linePointsRectangle = RectangleClient.getRectangleByPoints(points);
8858
+ return RectangleClient.getBoundingRectangle([linePointsRectangle]);
8859
+ }
8508
8860
  if (PlaitDrawElement.isImage(element)) {
8509
8861
  return RectangleClient.getRectangleByPoints(element.points);
8510
8862
  }
@@ -8545,6 +8897,9 @@ const withDraw = (board) => {
8545
8897
  if (PlaitDrawElement.isImage(element)) {
8546
8898
  return true;
8547
8899
  }
8900
+ if (PlaitDrawElement.isVectorLine(element)) {
8901
+ return true;
8902
+ }
8548
8903
  if (PlaitDrawElement.isArrowLine(element)) {
8549
8904
  const selectedElements = getSelectedElements(board);
8550
8905
  const isSelected = (boundId) => {
@@ -8580,12 +8935,12 @@ const withDraw = (board) => {
8580
8935
  });
8581
8936
  return getRelatedFragment([...elements, ...activeLines], originData);
8582
8937
  };
8583
- return withSwimlane(withTable(withDrawResize(withArrowLineAutoCompleteReaction(withArrowLineBoundReaction(withArrowLineResize(withArrowLineTextMove(withArrowLineText(withGeometryResize(withDrawRotate(withArrowLineCreateByDraw(withArrowLineAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board))))))))))))))));
8938
+ return withSwimlane(withTable(withDrawResize(withVectorPenCreateByDraw(withArrowLineAutoCompleteReaction(withArrowLineBoundReaction(withVectorLineResize(withArrowLineResize(withArrowLineTextMove(withArrowLineText(withGeometryResize(withDrawRotate(withArrowLineCreateByDraw(withArrowLineAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board))))))))))))))))));
8584
8939
  };
8585
8940
 
8586
8941
  /**
8587
8942
  * Generated bundle index. Do not edit.
8588
8943
  */
8589
8944
 
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 };
8945
+ 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
8946
  //# sourceMappingURL=plait-draw.mjs.map