@plait/draw 0.39.0 → 0.41.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.
@@ -1,5 +1,5 @@
1
- import { PlaitElement, ACTIVE_STROKE_WIDTH, ThemeColorMode, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, idCreator, createG, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, arrowPoints, createPath, distanceBetweenPointAndPoint, drawLinearPath, rotate, depthFirstRecursion, getIsRecursionFunc, getElementById, Direction, catmullRomFitting, distanceBetweenPointAndSegments, createMask, createRect, findElements, Point, getSelectedElements, isPolylineHitRectangle, PlaitNode, BOARD_TO_HOST, transformPoint, toPoint, isSelectionMoving, RgbaToHEX, PlaitPluginElementComponent, preventTouchMove, setClipboardData, getDataFromClipboard, getHitElementByPoint, CursorClass, temporaryDisableSelection, PRESS_AND_MOVE_BUFFER } from '@plait/core';
2
- import { getRectangleByPoints, getMemorizedLatest, memorizeLatest, RESIZE_HANDLE_DIAMETER, getExtendPoint, getFactorByPoints, Generator, getRectangleResizeHandleRefs, getDirectionByVector, getOppositeDirection, getDirectionFactor, DEFAULT_ROUTE_MARGIN, reduceRouteMargin, getNextPoint, generateElbowLineRoute, getPoints, removeDuplicatePoints, getPointByVector, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90, TRANSPARENT, normalizeShapePoints, PRIMARY_COLOR, CommonPluginElement, ActiveGenerator, WithTextPluginKey, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, acceptImageTypes, getElementOfFocusedImage, buildImage, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint, ImageGenerator } from '@plait/common';
1
+ import { PlaitElement, ACTIVE_STROKE_WIDTH, ThemeColorMode, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, idCreator, createG, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, arrowPoints, createPath, distanceBetweenPointAndPoint, drawLinearPath, rotate, depthFirstRecursion, getIsRecursionFunc, getElementById, Direction, catmullRomFitting, distanceBetweenPointAndSegments, createMask, createRect, findElements, Point, getSelectedElements, isPolylineHitRectangle, Path, PlaitNode, BOARD_TO_HOST, transformPoint, toPoint, isSelectionMoving, RgbaToHEX, PlaitPluginElementComponent, preventTouchMove, setClipboardData, getDataFromClipboard, getHitElementByPoint, CursorClass, temporaryDisableSelection, PRESS_AND_MOVE_BUFFER } from '@plait/core';
2
+ import { getRectangleByPoints, getMemorizedLatest, memorizeLatest, RESIZE_HANDLE_DIAMETER, getExtendPoint, getFactorByPoints, Generator, getRectangleResizeHandleRefs, getDirectionByVector, getOppositeDirection, getDirectionFactor, getPointByVector, reduceRouteMargin, getNextPoint, generateElbowLineRoute, getPoints, removeDuplicatePoints, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90, TRANSPARENT, normalizeShapePoints, PRIMARY_COLOR, CommonPluginElement, ActiveGenerator, WithTextPluginKey, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, acceptImageTypes, getElementOfFocusedImage, buildImage, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint, ImageGenerator } from '@plait/common';
3
3
  import { Alignment, buildText, DEFAULT_FONT_SIZE, getTextSize, AlignEditor, TextManage, getTextFromClipboard } from '@plait/text';
4
4
  import { pointsOnBezierCurves } from 'points-on-curve';
5
5
  import * as i0 from '@angular/core';
@@ -1090,7 +1090,7 @@ const StoredDataEngine = {
1090
1090
  draw(board, rectangle, options) {
1091
1091
  const rs = PlaitBoard.getRoughSVG(board);
1092
1092
  const shape = rs.path(`M${rectangle.x + rectangle.width / 10} ${rectangle.y} L${rectangle.x + rectangle.width} ${rectangle.y} A ${rectangle.width /
1093
- 10} ${rectangle.height / 2}, 1, 0, 0,${rectangle.x + rectangle.width} ${rectangle.y + rectangle.height} L${rectangle.x +
1093
+ 10} ${rectangle.height / 2}, 0, 0, 0,${rectangle.x + rectangle.width} ${rectangle.y + rectangle.height} L${rectangle.x +
1094
1094
  rectangle.width / 10} ${rectangle.y + rectangle.height}A ${rectangle.width / 10} ${rectangle.height /
1095
1095
  2}, 0, 0, 1,${rectangle.x + rectangle.width / 10} ${rectangle.y}`, { ...options, fillStyle: 'solid' });
1096
1096
  setStrokeLinecap(shape, 'round');
@@ -1679,7 +1679,11 @@ const getLinePoints = (board, element) => {
1679
1679
  return getCurvePoints(board, element);
1680
1680
  }
1681
1681
  default: {
1682
- return PlaitLine.getPoints(board, element);
1682
+ const points = PlaitLine.getPoints(board, element);
1683
+ const handleRefPair = getLineHandleRefPair(board, element);
1684
+ points[0] = handleRefPair.source.point;
1685
+ points[points.length - 1] = handleRefPair.target.point;
1686
+ return points;
1683
1687
  }
1684
1688
  }
1685
1689
  };
@@ -1731,43 +1735,52 @@ const getLineHandleRefPair = (board, element) => {
1731
1735
  }
1732
1736
  return { source: sourceHandleRef, target: targetHandleRef };
1733
1737
  };
1738
+ const createFakeElement = (startPoint, vector) => {
1739
+ const point = getPointByVector(startPoint, vector, -25);
1740
+ const points = getPointsByCenterPoint(point, 50, 50);
1741
+ return createGeometryElement(BasicShapes.rectangle, points, '');
1742
+ };
1734
1743
  const getElbowPoints = (board, element) => {
1735
1744
  if (element.points.length === 2) {
1736
1745
  const handleRefPair = getLineHandleRefPair(board, element);
1737
- const offset = element.source.boundId || element.target.boundId ? DEFAULT_ROUTE_MARGIN : 0;
1738
- const sourceElement = element.source.boundId && getElementById(board, element.source.boundId);
1739
- const targetElement = element.target.boundId && getElementById(board, element.target.boundId);
1740
- const isBound = sourceElement && targetElement;
1746
+ let sourceElement = element.source.boundId ? getElementById(board, element.source.boundId) : undefined;
1747
+ let targetElement = element.target.boundId ? getElementById(board, element.target.boundId) : undefined;
1741
1748
  let points = [];
1742
- if (isBound) {
1743
- const targetRectangle = RectangleClient.inflate(getRectangleByPoints(targetElement.points), getStrokeWidthByElement(targetElement) * 2);
1744
- const sourceRectangle = RectangleClient.inflate(getRectangleByPoints(sourceElement.points), getStrokeWidthByElement(sourceElement) * 2);
1745
- const sourcePoint = handleRefPair.source.point;
1746
- const targetPoint = handleRefPair.target.point;
1747
- const { sourceOffset, targetOffset } = reduceRouteMargin(sourceRectangle, targetRectangle);
1748
- const sourceOuterRectangle = RectangleClient.expand(sourceRectangle, sourceOffset[3], sourceOffset[0], sourceOffset[1], sourceOffset[2]);
1749
- const targetOuterRectangle = RectangleClient.expand(targetRectangle, targetOffset[3], targetOffset[0], targetOffset[1], targetOffset[2]);
1750
- const nextSourcePoint = getNextPoint(sourcePoint, sourceOuterRectangle, handleRefPair.source.direction);
1751
- const nextTargetPoint = getNextPoint(targetPoint, targetOuterRectangle, handleRefPair.target.direction);
1752
- const isIntersect = RectangleClient.isPointInRectangle(targetRectangle, sourcePoint) ||
1753
- RectangleClient.isPointInRectangle(targetOuterRectangle, nextSourcePoint) ||
1754
- RectangleClient.isPointInRectangle(sourceOuterRectangle, nextTargetPoint) ||
1755
- RectangleClient.isPointInRectangle(sourceRectangle, targetPoint);
1756
- if (!isIntersect) {
1757
- points = generateElbowLineRoute({
1758
- sourcePoint,
1759
- nextSourcePoint,
1760
- sourceRectangle,
1761
- sourceOuterRectangle,
1762
- targetPoint,
1763
- nextTargetPoint,
1764
- targetRectangle,
1765
- targetOuterRectangle
1766
- });
1767
- }
1749
+ if (!sourceElement) {
1750
+ const source = handleRefPair.source;
1751
+ sourceElement = createFakeElement(source.point, source.vector);
1752
+ }
1753
+ if (!targetElement) {
1754
+ const target = handleRefPair.target;
1755
+ targetElement = createFakeElement(target.point, target.vector);
1756
+ }
1757
+ const targetRectangle = RectangleClient.inflate(getRectangleByPoints(targetElement.points), getStrokeWidthByElement(targetElement) * 2);
1758
+ const sourceRectangle = RectangleClient.inflate(getRectangleByPoints(sourceElement.points), getStrokeWidthByElement(sourceElement) * 2);
1759
+ const sourcePoint = handleRefPair.source.point;
1760
+ const targetPoint = handleRefPair.target.point;
1761
+ const { sourceOffset, targetOffset } = reduceRouteMargin(sourceRectangle, targetRectangle);
1762
+ const sourceOuterRectangle = RectangleClient.expand(sourceRectangle, sourceOffset[3], sourceOffset[0], sourceOffset[1], sourceOffset[2]);
1763
+ const targetOuterRectangle = RectangleClient.expand(targetRectangle, targetOffset[3], targetOffset[0], targetOffset[1], targetOffset[2]);
1764
+ const nextSourcePoint = getNextPoint(sourcePoint, sourceOuterRectangle, handleRefPair.source.direction);
1765
+ const nextTargetPoint = getNextPoint(targetPoint, targetOuterRectangle, handleRefPair.target.direction);
1766
+ const isIntersect = RectangleClient.isPointInRectangle(targetRectangle, sourcePoint) ||
1767
+ RectangleClient.isPointInRectangle(targetOuterRectangle, nextSourcePoint) ||
1768
+ RectangleClient.isPointInRectangle(sourceOuterRectangle, nextTargetPoint) ||
1769
+ RectangleClient.isPointInRectangle(sourceRectangle, targetPoint);
1770
+ if (!isIntersect) {
1771
+ points = generateElbowLineRoute({
1772
+ sourcePoint,
1773
+ nextSourcePoint,
1774
+ sourceRectangle,
1775
+ sourceOuterRectangle,
1776
+ targetPoint,
1777
+ nextTargetPoint,
1778
+ targetRectangle,
1779
+ targetOuterRectangle
1780
+ });
1768
1781
  }
1769
- if (!points.length) {
1770
- points = getPoints(handleRefPair.source.point, handleRefPair.source.direction, handleRefPair.target.point, handleRefPair.target.direction, offset);
1782
+ else {
1783
+ points = getPoints(handleRefPair.source.point, handleRefPair.source.direction, handleRefPair.target.point, handleRefPair.target.direction, 0);
1771
1784
  }
1772
1785
  points = removeDuplicatePoints(points);
1773
1786
  return points;
@@ -1830,7 +1843,7 @@ const getHitLineTextIndex = (board, element, point) => {
1830
1843
  const texts = element.texts;
1831
1844
  if (!texts.length)
1832
1845
  return -1;
1833
- const points = getElbowPoints(board, element);
1846
+ const points = getLinePoints(board, element);
1834
1847
  return texts.findIndex(text => {
1835
1848
  const center = getPointOnPolyline(points, text.position);
1836
1849
  const rectangle = {
@@ -1905,10 +1918,10 @@ const getConnectionPoint = (geometry, connection, direction, delta) => {
1905
1918
  return RectangleClient.getConnectionPoint(rectangle, connection);
1906
1919
  }
1907
1920
  };
1908
- const transformPointToConnection = (board, point, hitElement) => {
1921
+ const transformPointToConnection = (board, point, hitElement, tolerance = ACTIVE_STROKE_WIDTH) => {
1909
1922
  let rectangle = getRectangleByPoints(hitElement.points);
1910
- rectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
1911
- let nearestPoint = getNearestPoint(hitElement, point, ACTIVE_STROKE_WIDTH);
1923
+ rectangle = RectangleClient.inflate(rectangle, tolerance);
1924
+ let nearestPoint = getNearestPoint(hitElement, point, tolerance);
1912
1925
  const hitConnector = getHitConnectorPoint(nearestPoint, hitElement, rectangle);
1913
1926
  nearestPoint = hitConnector ? hitConnector : nearestPoint;
1914
1927
  return [(nearestPoint[0] - rectangle.x) / rectangle.width, (nearestPoint[1] - rectangle.y) / rectangle.height];
@@ -2232,9 +2245,108 @@ class GeometryShapeGenerator extends Generator {
2232
2245
  }
2233
2246
  }
2234
2247
 
2248
+ const resizeLine = (board, options, path) => {
2249
+ Transforms.setNode(board, options, path);
2250
+ };
2251
+ const setLineTexts = (board, element, texts) => {
2252
+ const path = PlaitBoard.findPath(board, element);
2253
+ Transforms.setNode(board, { texts }, path);
2254
+ };
2255
+ const removeLineText = (board, element, index) => {
2256
+ const path = PlaitBoard.findPath(board, element);
2257
+ const texts = element.texts?.length ? [...element.texts] : [];
2258
+ const newTexts = [...texts];
2259
+ newTexts.splice(index, 1);
2260
+ Transforms.setNode(board, { texts: newTexts }, path);
2261
+ };
2262
+ const setLineMark = (board, element, handleKey, marker) => {
2263
+ const path = PlaitBoard.findPath(board, element);
2264
+ let handle = handleKey === LineHandleKey.source ? element.source : element.target;
2265
+ handle = { ...handle, marker };
2266
+ memorizeLatest(MemorizeKey.line, handleKey, marker);
2267
+ Transforms.setNode(board, { [handleKey]: handle }, path);
2268
+ };
2269
+ const collectLineUpdatedRefsByGeometry = (board, geometry, refs) => {
2270
+ const lines = findElements(board, {
2271
+ match: (element) => {
2272
+ if (PlaitDrawElement.isLine(element)) {
2273
+ return element.source.boundId === geometry.id || element.target.boundId === geometry.id;
2274
+ }
2275
+ return false;
2276
+ },
2277
+ recursion: element => true
2278
+ });
2279
+ if (lines.length) {
2280
+ lines.forEach(line => {
2281
+ const isSourceBound = line.source.boundId === geometry.id;
2282
+ const handle = isSourceBound ? 'source' : 'target';
2283
+ const object = { ...line[handle] };
2284
+ const linePoints = getLinePoints(board, line);
2285
+ const point = isSourceBound ? linePoints[0] : linePoints[linePoints.length - 1];
2286
+ object.connection = transformPointToConnection(board, point, geometry);
2287
+ const path = PlaitBoard.findPath(board, line);
2288
+ const index = refs.findIndex(obj => Path.equals(obj.path, path));
2289
+ if (index === -1) {
2290
+ refs.push({
2291
+ property: {
2292
+ [handle]: object
2293
+ },
2294
+ path
2295
+ });
2296
+ }
2297
+ else {
2298
+ refs[index].property = { ...refs[index].property, [handle]: object };
2299
+ }
2300
+ });
2301
+ }
2302
+ };
2303
+ const connectLineToGeometry = (board, lineElement, handle, geometryElement) => {
2304
+ const linePoints = PlaitLine.getPoints(board, lineElement);
2305
+ const point = handle === LineHandleKey.source ? linePoints[0] : linePoints[linePoints.length - 1];
2306
+ const connection = transformPointToConnection(board, point, geometryElement, Math.max(geometryElement.width, geometryElement.height));
2307
+ if (connection) {
2308
+ let source = lineElement.source;
2309
+ let target = lineElement.target;
2310
+ if (handle === LineHandleKey.source) {
2311
+ source = {
2312
+ ...source,
2313
+ boundId: geometryElement.id,
2314
+ connection
2315
+ };
2316
+ }
2317
+ else {
2318
+ target = {
2319
+ ...target,
2320
+ boundId: geometryElement.id,
2321
+ connection
2322
+ };
2323
+ }
2324
+ const path = PlaitBoard.findPath(board, lineElement);
2325
+ resizeLine(board, { source, target }, path);
2326
+ }
2327
+ };
2328
+
2235
2329
  const insertGeometry = (board, points, shape) => {
2236
2330
  const newElement = createDefaultGeometry(board, points, shape);
2237
2331
  insertElement(board, newElement);
2332
+ return newElement;
2333
+ };
2334
+ const insertGeometryByVector = (board, point, shape, vector) => {
2335
+ const shapeProperty = DefaultFlowchartPropertyMap[shape] || DefaultBasicShapeProperty;
2336
+ const direction = getDirectionByVector(vector);
2337
+ if (direction) {
2338
+ let offset = 0;
2339
+ if ([Direction.left, Direction.right].includes(direction)) {
2340
+ offset = -shapeProperty.width / 2;
2341
+ }
2342
+ else {
2343
+ offset = -shapeProperty.height / 2;
2344
+ }
2345
+ const vectorPoint = getPointByVector(point, vector, offset);
2346
+ const points = getPointsByCenterPoint(vectorPoint, shapeProperty.width, shapeProperty.height);
2347
+ return insertGeometry(board, points, shape);
2348
+ }
2349
+ return null;
2238
2350
  };
2239
2351
  const insertText = (board, points, text = '文本') => {
2240
2352
  const newElement = createDefaultText(board, points);
@@ -2250,9 +2362,21 @@ const resizeGeometry = (board, points, textHeight, path) => {
2250
2362
  }
2251
2363
  Transforms.setNode(board, newProperties, path);
2252
2364
  };
2253
- const transformShape = (board, element, shape) => {
2254
- const path = PlaitBoard.findPath(board, element);
2255
- Transforms.setNode(board, { shape }, path);
2365
+ const switchGeometryShape = (board, shape) => {
2366
+ const selectedElements = getSelectedElements(board);
2367
+ const refs = [];
2368
+ selectedElements.forEach(item => {
2369
+ if (PlaitDrawElement.isGeometry(item) && !PlaitDrawElement.isText(item)) {
2370
+ const path = PlaitBoard.findPath(board, item);
2371
+ Transforms.setNode(board, { shape }, path);
2372
+ collectLineUpdatedRefsByGeometry(board, { ...item, shape }, refs);
2373
+ }
2374
+ });
2375
+ if (refs.length) {
2376
+ refs.forEach(ref => {
2377
+ DrawTransforms.resizeLine(board, ref.property, ref.path);
2378
+ });
2379
+ }
2256
2380
  };
2257
2381
 
2258
2382
  const normalizePoints = (board, element, width, textHeight) => {
@@ -2327,28 +2451,6 @@ const insertImage = (board, imageItem, startPoint) => {
2327
2451
  Transforms.addSelectionWithTemporaryElements(board, [imageElement]);
2328
2452
  };
2329
2453
 
2330
- const resizeLine = (board, options, path) => {
2331
- Transforms.setNode(board, options, path);
2332
- };
2333
- const setLineTexts = (board, element, texts) => {
2334
- const path = PlaitBoard.findPath(board, element);
2335
- Transforms.setNode(board, { texts }, path);
2336
- };
2337
- const removeLineText = (board, element, index) => {
2338
- const path = PlaitBoard.findPath(board, element);
2339
- const texts = element.texts?.length ? [...element.texts] : [];
2340
- const newTexts = [...texts];
2341
- newTexts.splice(index, 1);
2342
- Transforms.setNode(board, { texts: newTexts }, path);
2343
- };
2344
- const setLineMark = (board, element, handleKey, marker) => {
2345
- const path = PlaitBoard.findPath(board, element);
2346
- let handle = handleKey === LineHandleKey.source ? element.source : element.target;
2347
- handle = { ...handle, marker };
2348
- memorizeLatest(MemorizeKey.line, handleKey, marker);
2349
- Transforms.setNode(board, { [handleKey]: handle }, path);
2350
- };
2351
-
2352
2454
  const DrawTransforms = {
2353
2455
  setText,
2354
2456
  insertGeometry,
@@ -2360,7 +2462,9 @@ const DrawTransforms = {
2360
2462
  removeLineText,
2361
2463
  setLineMark,
2362
2464
  insertImage,
2363
- transformShape
2465
+ switchGeometryShape,
2466
+ connectLineToGeometry,
2467
+ insertGeometryByVector
2364
2468
  };
2365
2469
 
2366
2470
  class LineAutoCompleteGenerator extends Generator {
@@ -2602,9 +2706,13 @@ class LineActiveGenerator extends Generator {
2602
2706
  function getMiddlePoints(board, element) {
2603
2707
  const result = [];
2604
2708
  const shape = element.shape;
2709
+ const hideBuffer = 10;
2605
2710
  if (shape === LineShape.straight) {
2606
2711
  const points = PlaitLine.getPoints(board, element);
2607
2712
  for (let i = 0; i < points.length - 1; i++) {
2713
+ const distance = distanceBetweenPointAndPoint(...points[i], ...points[i + 1]);
2714
+ if (distance < hideBuffer)
2715
+ continue;
2608
2716
  result.push([(points[i][0] + points[i + 1][0]) / 2, (points[i][1] + points[i + 1][1]) / 2]);
2609
2717
  }
2610
2718
  }
@@ -2622,6 +2730,9 @@ function getMiddlePoints(board, element) {
2622
2730
  const startIndex = pointsOnBezier.findIndex(point => point[0] === points[i][0] && point[1] === points[i][1]);
2623
2731
  const endIndex = pointsOnBezier.findIndex(point => point[0] === points[i + 1][0] && point[1] === points[i + 1][1]);
2624
2732
  const middleIndex = Math.round((startIndex + endIndex) / 2);
2733
+ const distance = distanceBetweenPointAndPoint(...points[i], ...points[i + 1]);
2734
+ if (distance < hideBuffer)
2735
+ continue;
2625
2736
  result.push(pointsOnBezier[middleIndex]);
2626
2737
  }
2627
2738
  }
@@ -3287,7 +3398,7 @@ const withLineResize = (board) => {
3287
3398
  element: value,
3288
3399
  handle: handleRef.handle
3289
3400
  };
3290
- pointIndex = handleRef.index;
3401
+ pointIndex = handleRef.handle === LineResizeHandle.addHandle ? handleRef.index + 1 : handleRef.index;
3291
3402
  }
3292
3403
  });
3293
3404
  return result;
@@ -3298,10 +3409,10 @@ const withLineResize = (board) => {
3298
3409
  let points = [...resizeRef.element.points];
3299
3410
  let source = { ...resizeRef.element.source };
3300
3411
  let target = { ...resizeRef.element.target };
3412
+ const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, REACTION_MARGIN);
3301
3413
  if (resizeRef.handle === LineResizeHandle.source || resizeRef.handle === LineResizeHandle.target) {
3302
3414
  const object = resizeRef.handle === LineResizeHandle.source ? source : target;
3303
3415
  points[pointIndex] = resizeState.endTransformPoint;
3304
- const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, REACTION_MARGIN);
3305
3416
  if (hitElement) {
3306
3417
  object.connection = transformPointToConnection(board, resizeState.endTransformPoint, hitElement);
3307
3418
  object.boundId = hitElement.id;
@@ -3309,21 +3420,25 @@ const withLineResize = (board) => {
3309
3420
  else {
3310
3421
  object.connection = undefined;
3311
3422
  object.boundId = undefined;
3312
- if (points.length === 2) {
3313
- let movingPoint = points[pointIndex];
3314
- const drawPoints = getLinePoints(board, resizeRef.element);
3315
- const index = pointIndex === 0 ? drawPoints.length - 1 : 0;
3316
- const otherPoint = drawPoints[index];
3317
- points[pointIndex] = alignPoints(otherPoint, movingPoint);
3318
- }
3319
3423
  }
3320
3424
  }
3321
3425
  else if (resizeRef.handle === LineResizeHandle.addHandle) {
3322
- points.splice(pointIndex + 1, 0, resizeState.endTransformPoint);
3426
+ points.splice(pointIndex, 0, resizeState.endTransformPoint);
3323
3427
  }
3324
3428
  else {
3325
3429
  points[pointIndex] = resizeState.endTransformPoint;
3326
3430
  }
3431
+ if (!hitElement) {
3432
+ const drawPoints = getLinePoints(board, resizeRef.element);
3433
+ const newPoints = [...points];
3434
+ newPoints[0] = drawPoints[0];
3435
+ newPoints[newPoints.length - 1] = drawPoints[drawPoints.length - 1];
3436
+ newPoints.forEach((point, index) => {
3437
+ if (index === pointIndex)
3438
+ return;
3439
+ points[pointIndex] = alignPoints(point, points[pointIndex]);
3440
+ });
3441
+ }
3327
3442
  DrawTransforms.resizeLine(board, { points, source, target }, resizeRef.path);
3328
3443
  }
3329
3444
  };
@@ -3535,7 +3650,7 @@ const withLineAutoCompleteReaction = (board) => {
3535
3650
  return board;
3536
3651
  };
3537
3652
 
3538
- const withLineAutoCompletePluginKey = 'plait-line-auto-complete-plugin-key';
3653
+ const WithLineAutoCompletePluginKey = 'plait-line-auto-complete-plugin-key';
3539
3654
  const withLineAutoComplete = (board) => {
3540
3655
  const { pointerDown, pointerMove, pointerUp } = board;
3541
3656
  let startPoint = null;
@@ -3576,7 +3691,7 @@ const withLineAutoComplete = (board) => {
3576
3691
  Transforms.insertNode(board, temporaryElement, [board.children.length]);
3577
3692
  clearSelectedElement(board);
3578
3693
  addSelectedElement(board, temporaryElement);
3579
- const afterComplete = board.getPluginOptions(withLineAutoCompletePluginKey)
3694
+ const afterComplete = board.getPluginOptions(WithLineAutoCompletePluginKey)
3580
3695
  ?.afterComplete;
3581
3696
  afterComplete && afterComplete(temporaryElement);
3582
3697
  }
@@ -3593,6 +3708,53 @@ const withLineAutoComplete = (board) => {
3593
3708
  return board;
3594
3709
  };
3595
3710
 
3711
+ const withLineTextMove = (board) => {
3712
+ let textIndex = 0;
3713
+ const movableBuffer = 100;
3714
+ const options = {
3715
+ key: 'line-text',
3716
+ canResize: () => {
3717
+ return true;
3718
+ },
3719
+ detect: (point) => {
3720
+ let result = null;
3721
+ const line = getHitElementByPoint(board, point, (element) => {
3722
+ return PlaitDrawElement.isLine(element);
3723
+ });
3724
+ if (line) {
3725
+ const index = getHitLineTextIndex(board, line, point);
3726
+ const hitComponent = PlaitElement.getComponent(line);
3727
+ const textManage = hitComponent.textManages[index];
3728
+ if (index !== -1 && !textManage.isEditing) {
3729
+ textIndex = index;
3730
+ return { element: line, handle: ResizeHandle.e };
3731
+ }
3732
+ }
3733
+ return result;
3734
+ },
3735
+ onResize: (resizeRef, resizeState) => {
3736
+ const element = resizeRef.element;
3737
+ if (element) {
3738
+ const movingPoint = resizeState.endTransformPoint;
3739
+ const points = getLinePoints(board, element);
3740
+ const distance = distanceBetweenPointAndSegments(points, movingPoint);
3741
+ if (distance <= movableBuffer) {
3742
+ const point = getNearestPointBetweenPointAndSegments(movingPoint, points, false);
3743
+ const position = getRatioByPoint(points, point);
3744
+ const texts = [...element.texts];
3745
+ texts[textIndex] = {
3746
+ ...texts[textIndex],
3747
+ position
3748
+ };
3749
+ DrawTransforms.setLineTexts(board, element, texts);
3750
+ }
3751
+ }
3752
+ }
3753
+ };
3754
+ withResize(board, options);
3755
+ return board;
3756
+ };
3757
+
3596
3758
  const withDraw = (board) => {
3597
3759
  const { drawElement, getRectangle, isRectangleHit, isHit, isMovable, isAlign } = board;
3598
3760
  board.drawElement = (context) => {
@@ -3662,12 +3824,12 @@ const withDraw = (board) => {
3662
3824
  }
3663
3825
  return isAlign(element);
3664
3826
  };
3665
- return withLineAutoCompleteReaction(withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withLineAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))))));
3827
+ return withLineTextMove(withLineAutoCompleteReaction(withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withLineAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board))))))))))));
3666
3828
  };
3667
3829
 
3668
3830
  /**
3669
3831
  * Generated bundle index. Do not edit.
3670
3832
  */
3671
3833
 
3672
- export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultBasicShapeProperty, DefaultConnectorProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultGeometryActiveStyle, DefaultGeometryStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultTextProperty, DrawThemeColors, DrawTransforms, FlowchartSymbols, GeometryComponent, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, MemorizeKey, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, REACTION_MARGIN, ShapeDefaultSpace, StrokeStyle, alignPoints, createDefaultFlowchart, createDefaultGeometry, createDefaultText, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getAutoCompletePoints, getBasicPointers, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultTextPoints, getDefaultTextShapeProperty, getDrawDefaultStrokeColor, getEdgeOnPolygonByPoint, getElbowPoints, getFillByElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryPointers, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitLineTextIndex, getLineDashByElement, getLineHandleRefPair, getLineMemorizedLatest, getLinePointers, getLinePoints, getLineTextRectangle, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getVectorByConnection, handleLineCreating, insertElement, isHitDrawElement, isHitLineText, isHitPolyLine, isRectangleHitDrawElement, isTextExceedingBounds, memorizeLatestShape, memorizeLatestText, transformOpsToPoints, transformPointToConnection, withDraw };
3834
+ export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultBasicShapeProperty, DefaultConnectorProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultGeometryActiveStyle, DefaultGeometryStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultTextProperty, DrawThemeColors, DrawTransforms, FlowchartSymbols, GeometryComponent, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, MemorizeKey, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, REACTION_MARGIN, ShapeDefaultSpace, StrokeStyle, WithLineAutoCompletePluginKey, alignPoints, createDefaultFlowchart, createDefaultGeometry, createDefaultText, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getAutoCompletePoints, getBasicPointers, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultTextPoints, getDefaultTextShapeProperty, getDrawDefaultStrokeColor, getEdgeOnPolygonByPoint, getElbowPoints, getFillByElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryPointers, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitLineTextIndex, getLineDashByElement, getLineHandleRefPair, getLineMemorizedLatest, getLinePointers, getLinePoints, getLineTextRectangle, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getVectorByConnection, handleLineCreating, insertElement, isHitDrawElement, isHitLineText, isHitPolyLine, isRectangleHitDrawElement, isTextExceedingBounds, memorizeLatestShape, memorizeLatestText, transformOpsToPoints, transformPointToConnection, withDraw, withLineAutoComplete };
3673
3835
  //# sourceMappingURL=plait-draw.mjs.map