@plait/draw 0.32.0 → 0.34.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 (46) hide show
  1. package/constants/geometry.d.ts +1 -0
  2. package/constants/index.d.ts +1 -0
  3. package/constants/theme.d.ts +26 -0
  4. package/esm2022/constants/geometry.mjs +2 -1
  5. package/esm2022/constants/index.mjs +2 -1
  6. package/esm2022/constants/theme.mjs +28 -0
  7. package/esm2022/generators/auto-complete.generator.mjs +44 -0
  8. package/esm2022/generators/geometry-shape.generator.mjs +4 -4
  9. package/esm2022/generators/line-active.generator.mjs +2 -2
  10. package/esm2022/generators/line.generator.mjs +2 -2
  11. package/esm2022/geometry.component.mjs +14 -8
  12. package/esm2022/image.component.mjs +2 -2
  13. package/esm2022/interfaces/element.mjs +7 -1
  14. package/esm2022/interfaces/index.mjs +3 -3
  15. package/esm2022/line.component.mjs +10 -9
  16. package/esm2022/plugins/with-auto-complete-reaction.mjs +35 -0
  17. package/esm2022/plugins/with-auto-complete.mjs +61 -0
  18. package/esm2022/plugins/with-draw.mjs +10 -6
  19. package/esm2022/plugins/with-geometry-create.mjs +3 -6
  20. package/esm2022/plugins/with-line-create.mjs +9 -24
  21. package/esm2022/plugins/with-line-resize.mjs +7 -16
  22. package/esm2022/transforms/common.mjs +33 -0
  23. package/esm2022/transforms/geometry.mjs +6 -3
  24. package/esm2022/transforms/index.mjs +9 -3
  25. package/esm2022/transforms/line.mjs +4 -2
  26. package/esm2022/utils/geometry.mjs +24 -11
  27. package/esm2022/utils/hit.mjs +2 -2
  28. package/esm2022/utils/line.mjs +38 -11
  29. package/esm2022/utils/style/stroke.mjs +10 -5
  30. package/fesm2022/plait-draw.mjs +354 -124
  31. package/fesm2022/plait-draw.mjs.map +1 -1
  32. package/generators/auto-complete.generator.d.ts +13 -0
  33. package/generators/geometry-shape.generator.d.ts +1 -1
  34. package/generators/line-active.generator.d.ts +1 -1
  35. package/generators/line.generator.d.ts +1 -1
  36. package/geometry.component.d.ts +2 -0
  37. package/interfaces/element.d.ts +5 -0
  38. package/package.json +1 -1
  39. package/plugins/with-auto-complete-reaction.d.ts +2 -0
  40. package/plugins/with-auto-complete.d.ts +7 -0
  41. package/transforms/common.d.ts +6 -0
  42. package/transforms/geometry.d.ts +2 -1
  43. package/transforms/index.d.ts +5 -0
  44. package/utils/geometry.d.ts +5 -1
  45. package/utils/line.d.ts +2 -0
  46. package/utils/style/stroke.d.ts +3 -2
@@ -1,5 +1,5 @@
1
- import { PlaitElement, ACTIVE_STROKE_WIDTH, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Point, BOARD_TO_HOST, transformPoint, toPoint, idCreator, createG, BoardTransforms, PlaitPointerType, preventTouchMove, createForeignObject, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, arrowPoints, createPath, drawLinearPath, distanceBetweenPointAndPoint, rotate, getElementById, distanceBetweenPointAndSegments, createMask, createRect, findElements, getSelectedElements, isPolylineHitRectangle, isSelectionMoving, PlaitPluginElementComponent, setClipboardData, getDataFromClipboard, depthFirstRecursion, getIsRecursionFunc, getHitElementByPoint } from '@plait/core';
2
- import { getRectangleByPoints, Generator, normalizeShapePoints, isDndMode, isDrawingMode, getExtendPoint, getFactorByPoints, getDirectionByVector, getOppositeDirection, getDirectionFactor, DEFAULT_ROUTE_MARGIN, reduceRouteMargin, getNextPoint, generateElbowLineRoute, getPoints, removeDuplicatePoints, getPointByVector, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90, TRANSPARENT, CommonPluginElement, ActiveGenerator, WithTextPluginKey, RESIZE_HANDLE_DIAMETER, PRIMARY_COLOR, isVirtualKey, isDelete, isSpaceHotkey, acceptImageTypes, getElementOfFocusedImage, buildImage, getRectangleResizeHandleRefs, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint, ImageGenerator } from '@plait/common';
1
+ import { PlaitElement, ACTIVE_STROKE_WIDTH, ThemeColorMode, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Point, BOARD_TO_HOST, transformPoint, toPoint, idCreator, createG, BoardTransforms, PlaitPointerType, preventTouchMove, createForeignObject, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, arrowPoints, createPath, drawLinearPath, distanceBetweenPointAndPoint, rotate, depthFirstRecursion, getIsRecursionFunc, getElementById, Direction, catmullRomFitting, distanceBetweenPointAndSegments, createMask, createRect, findElements, getSelectedElements, isPolylineHitRectangle, isSelectionMoving, PlaitPluginElementComponent, setClipboardData, getDataFromClipboard, getHitElementByPoint, temporaryDisableSelection } from '@plait/core';
2
+ import { getRectangleByPoints, Generator, PropertyTransforms, normalizeShapePoints, memorizeLatest, isDndMode, isDrawingMode, RESIZE_HANDLE_DIAMETER, getExtendPoint, getFactorByPoints, getRectangleResizeHandleRefs, getDirectionByVector, getOppositeDirection, getDirectionFactor, DEFAULT_ROUTE_MARGIN, reduceRouteMargin, getNextPoint, generateElbowLineRoute, getPoints, removeDuplicatePoints, getPointByVector, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90, TRANSPARENT, CommonPluginElement, ActiveGenerator, WithTextPluginKey, PRIMARY_COLOR, isVirtualKey, isDelete, isSpaceHotkey, acceptImageTypes, getElementOfFocusedImage, buildImage, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint, ImageGenerator } from '@plait/common';
3
3
  import { AlignEditor, Alignment, DEFAULT_FONT_SIZE, buildText, TextManage, getTextFromClipboard, getTextSize } from '@plait/text';
4
4
  import { isKeyHotkey } from 'is-hotkey';
5
5
  import { pointsOnBezierCurves } from 'points-on-curve';
@@ -122,6 +122,7 @@ const DefaultFlowchartPropertyMap = {
122
122
  [FlowchartSymbols.delay]: DefaultFlowchartProperty,
123
123
  [FlowchartSymbols.storedData]: DefaultFlowchartProperty
124
124
  };
125
+ const REACTION_MARGIN = -4;
125
126
 
126
127
  const getGeometryPointers = () => {
127
128
  return [...Object.keys(BasicShapes), ...Object.keys(FlowchartSymbols)];
@@ -138,6 +139,33 @@ const getLinePointers = () => {
138
139
 
139
140
  const DEFAULT_IMAGE_WIDTH = 1000;
140
141
 
142
+ const DrawThemeColors = {
143
+ [ThemeColorMode.default]: {
144
+ strokeColor: '#333333',
145
+ fill: '#FFFFFF'
146
+ },
147
+ [ThemeColorMode.colorful]: {
148
+ strokeColor: '#06ADBF',
149
+ fill: '#CDEFF2'
150
+ },
151
+ [ThemeColorMode.soft]: {
152
+ strokeColor: '#6D89C1',
153
+ fill: '#DADFEB'
154
+ },
155
+ [ThemeColorMode.retro]: {
156
+ strokeColor: '#E9C358',
157
+ fill: '#F6EDCF'
158
+ },
159
+ [ThemeColorMode.dark]: {
160
+ strokeColor: '#FFFFFF',
161
+ fill: '#434343'
162
+ },
163
+ [ThemeColorMode.starry]: {
164
+ strokeColor: '#42ABE5',
165
+ fill: '#163F5A'
166
+ }
167
+ };
168
+
141
169
  const getStrokeWidthByElement = (element) => {
142
170
  if (PlaitDrawElement.isText(element)) {
143
171
  return 0;
@@ -145,12 +173,16 @@ const getStrokeWidthByElement = (element) => {
145
173
  const strokeWidth = element.strokeWidth || DefaultGeometryStyle.strokeWidth;
146
174
  return strokeWidth;
147
175
  };
148
- const getStrokeColorByElement = (element) => {
149
- const strokeColor = element.strokeColor || DefaultGeometryStyle.strokeColor;
176
+ const getStrokeColorByElement = (board, element) => {
177
+ const defaultColor = getDrawDefaultStrokeColor(board.theme.themeColorMode);
178
+ const strokeColor = element.strokeColor || defaultColor;
150
179
  return strokeColor;
151
180
  };
152
- const getFillByElement = (element) => {
153
- const fill = element.fill || DefaultGeometryStyle.fill;
181
+ const getFillByElement = (board, element) => {
182
+ const defaultFill = PlaitDrawElement.isFlowchart(element)
183
+ ? getFlowchartDefaultFill(board.theme.themeColorMode)
184
+ : DefaultGeometryStyle.fill;
185
+ const fill = element.fill || defaultFill;
154
186
  return fill;
155
187
  };
156
188
  const getLineDashByElement = (element) => {
@@ -1172,15 +1204,15 @@ class GeometryShapeGenerator extends Generator {
1172
1204
  canDraw(element, data) {
1173
1205
  return true;
1174
1206
  }
1175
- baseDraw(element, data) {
1207
+ draw(element, data) {
1176
1208
  const rectangle = getRectangleByPoints(element.points);
1177
1209
  const shape = element.shape;
1178
1210
  if (shape === BasicShapes.text) {
1179
1211
  return;
1180
1212
  }
1181
1213
  const strokeWidth = getStrokeWidthByElement(element);
1182
- const strokeColor = getStrokeColorByElement(element);
1183
- const fill = getFillByElement(element);
1214
+ const strokeColor = getStrokeColorByElement(this.board, element);
1215
+ const fill = getFillByElement(this.board, element);
1184
1216
  const strokeLineDash = getLineDashByElement(element);
1185
1217
  return drawGeometry(this.board, RectangleClient.inflate(rectangle, -strokeWidth), shape, {
1186
1218
  stroke: strokeColor,
@@ -1191,9 +1223,39 @@ class GeometryShapeGenerator extends Generator {
1191
1223
  }
1192
1224
  }
1193
1225
 
1226
+ const setStrokeColor = (board, strokeColor) => {
1227
+ PropertyTransforms.setProperty(board, { strokeColor }, { getMemorizeKey });
1228
+ };
1229
+ const setStrokeWidth = (board, strokeWidth) => {
1230
+ PropertyTransforms.setProperty(board, { strokeWidth }, { getMemorizeKey });
1231
+ };
1232
+ const setFillColor = (board, fill) => {
1233
+ PropertyTransforms.setProperty(board, { fill }, { getMemorizeKey });
1234
+ };
1235
+ const setStrokeStyle = (board, strokeStyle) => {
1236
+ PropertyTransforms.setProperty(board, { strokeStyle }, { getMemorizeKey });
1237
+ };
1238
+ const getMemorizeKey = (element) => {
1239
+ let key = '';
1240
+ switch (true) {
1241
+ case PlaitDrawElement.isBaseShape(element): {
1242
+ key = MemorizeKey.basicShape;
1243
+ break;
1244
+ }
1245
+ case PlaitDrawElement.isFlowchart(element): {
1246
+ key = MemorizeKey.flowchart;
1247
+ break;
1248
+ }
1249
+ case PlaitDrawElement.isLine(element): {
1250
+ key = MemorizeKey.line;
1251
+ break;
1252
+ }
1253
+ }
1254
+ return key;
1255
+ };
1256
+
1194
1257
  const insertGeometry = (board, points, shape) => {
1195
1258
  let newElement = createGeometryElement(shape, points, '', {
1196
- strokeColor: DefaultBasicShapeProperty.strokeColor,
1197
1259
  strokeWidth: DefaultBasicShapeProperty.strokeWidth
1198
1260
  });
1199
1261
  Transforms.insertNode(board, newElement, [board.children.length]);
@@ -1216,6 +1278,10 @@ const resizeGeometry = (board, points, textHeight, path) => {
1216
1278
  }
1217
1279
  Transforms.setNode(board, newProperties, path);
1218
1280
  };
1281
+ const transformShape = (board, element, shape) => {
1282
+ const path = PlaitBoard.findPath(board, element);
1283
+ Transforms.setNode(board, { shape }, path);
1284
+ };
1219
1285
 
1220
1286
  const normalizePoints = (board, element, width, textHeight) => {
1221
1287
  let points = element.points;
@@ -1307,6 +1373,7 @@ const setLineMark = (board, element, handleKey, marker) => {
1307
1373
  const path = PlaitBoard.findPath(board, element);
1308
1374
  let handle = handleKey === LineHandleKey.source ? element.source : element.target;
1309
1375
  handle = { ...handle, marker };
1376
+ memorizeLatest(MemorizeKey.line, handleKey, marker);
1310
1377
  Transforms.setNode(board, { [handleKey]: handle }, path);
1311
1378
  };
1312
1379
 
@@ -1320,7 +1387,12 @@ const DrawTransforms = {
1320
1387
  setLineTexts,
1321
1388
  removeLineText,
1322
1389
  setLineMark,
1323
- insertImage
1390
+ insertImage,
1391
+ transformShape,
1392
+ setStrokeColor,
1393
+ setStrokeWidth,
1394
+ setFillColor,
1395
+ setStrokeStyle
1324
1396
  };
1325
1397
 
1326
1398
  const withGeometryCreateByDrag = (board) => {
@@ -1344,10 +1416,9 @@ const withGeometryCreateByDrag = (board) => {
1344
1416
  }
1345
1417
  else {
1346
1418
  const temporaryElement = createGeometryElement(pointer, points, '', {
1347
- strokeColor: DefaultBasicShapeProperty.strokeColor,
1348
1419
  strokeWidth: DefaultBasicShapeProperty.strokeWidth
1349
1420
  });
1350
- geometryGenerator.draw(temporaryElement, geometryShapeG);
1421
+ geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
1351
1422
  PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1352
1423
  }
1353
1424
  }
@@ -1420,10 +1491,9 @@ const withGeometryCreateByDrawing = (board) => {
1420
1491
  if (drawMode && pointer !== BasicShapes.text) {
1421
1492
  const points = normalizeShapePoints([start, movingPoint], isShift);
1422
1493
  temporaryElement = createGeometryElement(pointer, points, '', {
1423
- strokeColor: DefaultBasicShapeProperty.strokeColor,
1424
1494
  strokeWidth: DefaultBasicShapeProperty.strokeWidth
1425
1495
  });
1426
- geometryGenerator.draw(temporaryElement, geometryShapeG);
1496
+ geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
1427
1497
  PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1428
1498
  }
1429
1499
  pointerMove(event);
@@ -1438,7 +1508,6 @@ const withGeometryCreateByDrawing = (board) => {
1438
1508
  const points = getDefaultGeometryPoints(pointer, targetPoint);
1439
1509
  if (pointer !== BasicShapes.text) {
1440
1510
  temporaryElement = createGeometryElement(pointer, points, '', {
1441
- strokeColor: DefaultBasicShapeProperty.strokeColor,
1442
1511
  strokeWidth: DefaultBasicShapeProperty.strokeWidth
1443
1512
  });
1444
1513
  }
@@ -1502,10 +1571,6 @@ const createGeometryElement = (shape, points, text, options) => {
1502
1571
  textOptions = { autoSize: true };
1503
1572
  alignment = undefined;
1504
1573
  }
1505
- let flowchartOptions = {};
1506
- if (getFlowchartPointers().includes(shape)) {
1507
- flowchartOptions = { fill: '#ffffff' };
1508
- }
1509
1574
  return {
1510
1575
  id: idCreator(),
1511
1576
  type: 'geometry',
@@ -1516,8 +1581,7 @@ const createGeometryElement = (shape, points, text, options) => {
1516
1581
  text: buildText(text, alignment),
1517
1582
  points,
1518
1583
  ...textOptions,
1519
- ...options,
1520
- ...flowchartOptions
1584
+ ...options
1521
1585
  };
1522
1586
  };
1523
1587
  const getPointsByCenterPoint = (point, width, height) => {
@@ -1597,11 +1661,9 @@ const createDefaultFlowchart = (point) => {
1597
1661
  const processProperty = getDefaultFlowchartProperty(FlowchartSymbols.process);
1598
1662
  const terminalProperty = getDefaultFlowchartProperty(FlowchartSymbols.terminal);
1599
1663
  const options = {
1600
- strokeColor: DefaultBasicShapeProperty.strokeColor,
1601
1664
  strokeWidth: DefaultBasicShapeProperty.strokeWidth
1602
1665
  };
1603
1666
  const lineOptions = {
1604
- strokeColor: DefaultLineStyle.strokeColor,
1605
1667
  strokeWidth: DefaultLineStyle.strokeWidth
1606
1668
  };
1607
1669
  const startElement = createGeometryElement(FlowchartSymbols.terminal, getDefaultGeometryPoints(FlowchartSymbols.terminal, point), '开始', options);
@@ -1649,6 +1711,26 @@ const createDefaultFlowchart = (point) => {
1649
1711
  ], { marker: LineMarkerType.none, connection: [0.5, 1], boundId: processElement2.id }, { marker: LineMarkerType.arrow, connection: [1, 0.5], boundId: endElement.id }, [], lineOptions);
1650
1712
  return [startElement, processElement1, decisionElement, processElement2, endElement, line1, line2, line3, line4, line5];
1651
1713
  };
1714
+ const getAutoCompletePoints = (element) => {
1715
+ const AutoCompleteMargin = (12 + RESIZE_HANDLE_DIAMETER / 2) * 2;
1716
+ let rectangle = getRectangleByPoints(element.points);
1717
+ rectangle = RectangleClient.inflate(rectangle, AutoCompleteMargin);
1718
+ return RectangleClient.getEdgeCenterPoints(rectangle);
1719
+ };
1720
+ const getHitIndexOfAutoCompletePoint = (movingPoint, points) => {
1721
+ return points.findIndex(point => {
1722
+ const movingRectangle = RectangleClient.toRectangleClient([movingPoint]);
1723
+ let rectangle = RectangleClient.toRectangleClient([point]);
1724
+ rectangle = RectangleClient.inflate(rectangle, RESIZE_HANDLE_DIAMETER);
1725
+ return RectangleClient.isHit(movingRectangle, rectangle);
1726
+ });
1727
+ };
1728
+ const getDrawDefaultStrokeColor = (theme) => {
1729
+ return DrawThemeColors[theme].strokeColor;
1730
+ };
1731
+ const getFlowchartDefaultFill = (theme) => {
1732
+ return DrawThemeColors[theme].fill;
1733
+ };
1652
1734
 
1653
1735
  const MAX_LENGTH = 100;
1654
1736
  const drawLineArrow = (element, points, options) => {
@@ -1765,6 +1847,41 @@ const drawHollowTriangleArrow = (source, target, options) => {
1765
1847
  return drawLinearPath([pointLeft, pointRight, target], { ...options, fill: 'white' }, true);
1766
1848
  };
1767
1849
 
1850
+ class LineShapeGenerator extends Generator {
1851
+ canDraw(element, data) {
1852
+ return true;
1853
+ }
1854
+ draw(element, data) {
1855
+ let lineG;
1856
+ lineG = drawLine(this.board, element);
1857
+ return lineG;
1858
+ }
1859
+ }
1860
+
1861
+ const getHitGeometryResizeHandleRef = (board, element, point) => {
1862
+ const rectangle = getRectangleByPoints(element.points);
1863
+ const resizeHandleRefs = getRectangleResizeHandleRefs(rectangle, RESIZE_HANDLE_DIAMETER);
1864
+ const result = resizeHandleRefs.find(resizeHandleRef => {
1865
+ return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), resizeHandleRef.rectangle);
1866
+ });
1867
+ return result;
1868
+ };
1869
+ const getHitOutlineGeometry = (board, point, offset = 0) => {
1870
+ let geometry = null;
1871
+ depthFirstRecursion(board, node => {
1872
+ if (PlaitDrawElement.isGeometry(node) || PlaitDrawElement.isImage(node)) {
1873
+ let client = getRectangleByPoints(node.points);
1874
+ client = RectangleClient.getOutlineRectangle(client, offset);
1875
+ const shape = getShape(node);
1876
+ const isHit = getEngine(shape).isHit(client, point);
1877
+ if (isHit) {
1878
+ geometry = node;
1879
+ }
1880
+ }
1881
+ }, getIsRecursionFunc(board), true);
1882
+ return geometry;
1883
+ };
1884
+
1768
1885
  const createLineElement = (shape, points, source, target, texts, options) => {
1769
1886
  return {
1770
1887
  id: idCreator(),
@@ -1799,7 +1916,7 @@ const getLineHandleRefPair = (board, element) => {
1799
1916
  let targetPoint = targetBoundElement
1800
1917
  ? getConnectionPoint(targetBoundElement, element.target.connection)
1801
1918
  : element.points[element.points.length - 1];
1802
- let sourceDirection = getDirectionByVector([targetPoint[0] - sourcePoint[0], targetPoint[1] - sourcePoint[1]]);
1919
+ let sourceDirection = getDirectionByVector([targetPoint[0] - sourcePoint[0], targetPoint[1] - sourcePoint[1]]) || Direction.right;
1803
1920
  let targetDirection = getOppositeDirection(sourceDirection);
1804
1921
  const sourceFactor = getDirectionFactor(sourceDirection);
1805
1922
  const targetFactor = getDirectionFactor(targetDirection);
@@ -1911,12 +2028,9 @@ const getCurvePoints = (board, element) => {
1911
2028
  return pointsOnBezierCurves(curvePoints);
1912
2029
  }
1913
2030
  else {
1914
- //TODO 直接获取贝塞尔曲线上高密度点
1915
- const points = PlaitLine.getPoints(board, element);
1916
- const draw = PlaitBoard.getRoughSVG(board).generator.curve(points);
1917
- let bezierPoints = transformOpsToPoints(draw.sets[0].ops);
1918
- bezierPoints = removeDuplicatePoints(bezierPoints);
1919
- return pointsOnBezierCurves(bezierPoints);
2031
+ const allPoints = PlaitLine.getPoints(board, element);
2032
+ const points = catmullRomFitting(allPoints);
2033
+ return pointsOnBezierCurves(points);
1920
2034
  }
1921
2035
  };
1922
2036
  const transformOpsToPoints = (ops) => {
@@ -1958,7 +2072,7 @@ const isHitLineText = (board, element, point) => {
1958
2072
  };
1959
2073
  const drawLine = (board, element) => {
1960
2074
  const strokeWidth = getStrokeWidthByElement(element);
1961
- const strokeColor = getStrokeColorByElement(element);
2075
+ const strokeColor = getStrokeColorByElement(board, element);
1962
2076
  const strokeLineDash = getLineDashByElement(element);
1963
2077
  const options = { stroke: strokeColor, strokeWidth, strokeLineDash };
1964
2078
  const lineG = createG();
@@ -2092,6 +2206,33 @@ const getVectorByConnection = (boundElement, connection) => {
2092
2206
  }
2093
2207
  return vector;
2094
2208
  };
2209
+ const alignPoints = (basePoint, movingPoint) => {
2210
+ const offset = 3;
2211
+ const newPoint = [...movingPoint];
2212
+ if (Point.isVerticalAlign(newPoint, basePoint, offset)) {
2213
+ newPoint[0] = basePoint[0];
2214
+ }
2215
+ if (Point.isHorizontalAlign(newPoint, basePoint, offset)) {
2216
+ newPoint[1] = basePoint[1];
2217
+ }
2218
+ return newPoint;
2219
+ };
2220
+ const handleLineCreating = (board, lineShape, startPoint, movingPoint, sourceElement, lineShapeG) => {
2221
+ const hitElement = getHitOutlineGeometry(board, movingPoint, REACTION_MARGIN);
2222
+ const targetConnection = hitElement ? transformPointToConnection(board, movingPoint, hitElement) : undefined;
2223
+ const connection = sourceElement ? transformPointToConnection(board, startPoint, sourceElement) : undefined;
2224
+ const targetBoundId = hitElement ? hitElement.id : undefined;
2225
+ const lineGenerator = new LineShapeGenerator(board);
2226
+ const temporaryLineElement = createLineElement(lineShape, [startPoint, movingPoint], { marker: LineMarkerType.none, connection: connection, boundId: sourceElement?.id }, { marker: LineMarkerType.arrow, connection: targetConnection, boundId: targetBoundId }, [], {
2227
+ strokeWidth: DefaultLineStyle.strokeWidth
2228
+ });
2229
+ const linePoints = getLinePoints(board, temporaryLineElement);
2230
+ const otherPoint = linePoints[0];
2231
+ temporaryLineElement.points[1] = alignPoints(otherPoint, movingPoint);
2232
+ lineGenerator.processDrawing(temporaryLineElement, lineShapeG);
2233
+ PlaitBoard.getElementActiveHost(board).append(lineShapeG);
2234
+ return temporaryLineElement;
2235
+ };
2095
2236
 
2096
2237
  const getSelectedDrawElements = (board) => {
2097
2238
  const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isDrawElement(value));
@@ -2146,7 +2287,7 @@ const isRectangleHitDrawElement = (board, element, selection) => {
2146
2287
  };
2147
2288
  const isHitDrawElement = (board, element, point) => {
2148
2289
  if (PlaitDrawElement.isGeometry(element)) {
2149
- const fill = getFillByElement(element);
2290
+ const fill = getFillByElement(board, element);
2150
2291
  // when shape equals text, fill is not allowed
2151
2292
  if (fill !== DefaultGeometryStyle.fill && fill !== TRANSPARENT && !PlaitDrawElement.isText(element)) {
2152
2293
  return isRectangleHitDrawElement(board, element, { anchor: point, focus: point });
@@ -2247,6 +2388,12 @@ var StrokeStyle;
2247
2388
  StrokeStyle["solid"] = "solid";
2248
2389
  StrokeStyle["dashed"] = "dashed";
2249
2390
  })(StrokeStyle || (StrokeStyle = {}));
2391
+ var MemorizeKey;
2392
+ (function (MemorizeKey) {
2393
+ MemorizeKey["basicShape"] = "basicShape";
2394
+ MemorizeKey["flowchart"] = "flowchart";
2395
+ MemorizeKey["line"] = "line";
2396
+ })(MemorizeKey || (MemorizeKey = {}));
2250
2397
 
2251
2398
  const PlaitDrawElement = {
2252
2399
  isGeometry: (value) => {
@@ -2273,13 +2420,54 @@ const PlaitDrawElement = {
2273
2420
  return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value);
2274
2421
  },
2275
2422
  isBaseShape: (value) => {
2276
- return Object.keys(BasicShapes).includes(value.type);
2423
+ return Object.keys(BasicShapes).includes(value.shape);
2277
2424
  },
2278
2425
  isFlowchart: (value) => {
2279
- return Object.keys(FlowchartSymbols).includes(value.type);
2426
+ return Object.keys(FlowchartSymbols).includes(value.shape);
2280
2427
  }
2281
2428
  };
2282
2429
 
2430
+ class AutoCompleteGenerator extends Generator {
2431
+ constructor(board) {
2432
+ super(board);
2433
+ this.board = board;
2434
+ this.hoverElement = null;
2435
+ }
2436
+ canDraw(element, data) {
2437
+ const selectedElements = getSelectedElements(this.board);
2438
+ if (data.selected && selectedElements.length === 1 && !isSelectionMoving(this.board)) {
2439
+ return true;
2440
+ }
2441
+ else {
2442
+ return false;
2443
+ }
2444
+ }
2445
+ draw(element, data) {
2446
+ this.autoCompleteG = createG();
2447
+ const middlePoints = getAutoCompletePoints(element);
2448
+ middlePoints.forEach((point, index) => {
2449
+ const circle = drawCircle(PlaitBoard.getRoughSVG(this.board), point, RESIZE_HANDLE_DIAMETER, {
2450
+ stroke: 'none',
2451
+ fill: '#6698FF4d',
2452
+ fillStyle: 'solid'
2453
+ });
2454
+ circle.classList.add(`geometry-auto-complete-${index}`);
2455
+ this.autoCompleteG.appendChild(circle);
2456
+ });
2457
+ return this.autoCompleteG;
2458
+ }
2459
+ removeAutoCompleteG(index) {
2460
+ this.hoverElement = this.autoCompleteG.querySelector(`.geometry-auto-complete-${index}`);
2461
+ this.hoverElement.style.visibility = 'hidden';
2462
+ }
2463
+ recoverAutoCompleteG() {
2464
+ if (this.hoverElement) {
2465
+ this.hoverElement.style.visibility = 'visible';
2466
+ this.hoverElement = null;
2467
+ }
2468
+ }
2469
+ }
2470
+
2283
2471
  class GeometryComponent extends CommonPluginElement {
2284
2472
  get textManage() {
2285
2473
  return this.getTextManages()[0];
@@ -2321,33 +2509,38 @@ class GeometryComponent extends CommonPluginElement {
2321
2509
  return selectedElements.length === 1 && !isSelectionMoving(this.board);
2322
2510
  }
2323
2511
  });
2512
+ this.autoCompleteGenerator = new AutoCompleteGenerator(this.board);
2324
2513
  this.shapeGenerator = new GeometryShapeGenerator(this.board);
2325
2514
  this.initializeTextManage();
2326
2515
  }
2327
2516
  ngOnInit() {
2328
2517
  super.ngOnInit();
2329
2518
  this.initializeGenerator();
2330
- this.shapeGenerator.draw(this.element, this.g);
2331
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
2519
+ this.shapeGenerator.processDrawing(this.element, this.g);
2520
+ this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2521
+ this.autoCompleteGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2332
2522
  this.drawText();
2333
2523
  }
2334
2524
  onContextChanged(value, previous) {
2335
- if (value.element !== previous.element) {
2336
- this.shapeGenerator.draw(this.element, this.g);
2337
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
2525
+ const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
2526
+ if (value.element !== previous.element || isChangeTheme) {
2527
+ this.shapeGenerator.processDrawing(this.element, this.g);
2528
+ this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2529
+ this.autoCompleteGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2338
2530
  this.updateText();
2339
2531
  }
2340
2532
  else {
2341
2533
  const hasSameSelected = value.selected === previous.selected;
2342
2534
  const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
2343
2535
  if (!hasSameSelected || !hasSameHandleState) {
2344
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
2536
+ this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2537
+ this.autoCompleteGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2345
2538
  }
2346
2539
  }
2347
2540
  }
2348
2541
  editText() {
2349
2542
  this.textManage.edit();
2350
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
2543
+ this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2351
2544
  }
2352
2545
  drawText() {
2353
2546
  this.textManage.draw(this.element.text);
@@ -2408,17 +2601,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2408
2601
  }]
2409
2602
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
2410
2603
 
2411
- class LineShapeGenerator extends Generator {
2412
- canDraw(element, data) {
2413
- return true;
2414
- }
2415
- baseDraw(element, data) {
2416
- let lineG;
2417
- lineG = drawLine(this.board, element);
2418
- return lineG;
2419
- }
2420
- }
2421
-
2422
2604
  class LineActiveGenerator extends Generator {
2423
2605
  constructor() {
2424
2606
  super(...arguments);
@@ -2432,7 +2614,7 @@ class LineActiveGenerator extends Generator {
2432
2614
  return false;
2433
2615
  }
2434
2616
  }
2435
- baseDraw(element, data) {
2617
+ draw(element, data) {
2436
2618
  const activeG = createG();
2437
2619
  if (this.hasResizeHandle) {
2438
2620
  activeG.classList.add('active');
@@ -2515,8 +2697,8 @@ class LineComponent extends PlaitPluginElementComponent {
2515
2697
  }
2516
2698
  ngOnInit() {
2517
2699
  this.initializeGenerator();
2518
- this.shapeGenerator.draw(this.element, this.g);
2519
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2700
+ this.shapeGenerator.processDrawing(this.element, this.g);
2701
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2520
2702
  super.ngOnInit();
2521
2703
  this.boundedElements = this.getBoundedElements();
2522
2704
  this.drawText();
@@ -2541,21 +2723,22 @@ class LineComponent extends PlaitPluginElementComponent {
2541
2723
  const boundedElements = this.getBoundedElements();
2542
2724
  const isBoundedElementsChanged = boundedElements.source !== this.boundedElements.source || boundedElements.target !== this.boundedElements.target;
2543
2725
  this.boundedElements = boundedElements;
2544
- if (value.element !== previous.element) {
2545
- this.shapeGenerator.draw(this.element, this.g);
2546
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2726
+ const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
2727
+ if (value.element !== previous.element || isChangeTheme) {
2728
+ this.shapeGenerator.processDrawing(this.element, this.g);
2729
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2547
2730
  this.updateText(previous.element.texts, value.element.texts);
2548
2731
  this.updateTextRectangle();
2549
2732
  }
2550
2733
  if (isBoundedElementsChanged) {
2551
- this.shapeGenerator.draw(this.element, this.g);
2552
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2734
+ this.shapeGenerator.processDrawing(this.element, this.g);
2735
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2553
2736
  this.updateTextRectangle();
2554
2737
  return;
2555
2738
  }
2556
2739
  if (!isSelectionMoving(this.board)) {
2557
2740
  this.activeGenerator.hasResizeHandle = this.hasResizeHandle();
2558
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2741
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2559
2742
  }
2560
2743
  }
2561
2744
  hasResizeHandle() {
@@ -2804,35 +2987,10 @@ const getBoundedLineElements = (board, plaitShapes) => {
2804
2987
  return lines.filter(line => plaitShapes.find(shape => PlaitLine.isBoundElementOfSource(line, shape) || PlaitLine.isBoundElementOfTarget(line, shape)));
2805
2988
  };
2806
2989
 
2807
- const getHitGeometryResizeHandleRef = (board, element, point) => {
2808
- const rectangle = getRectangleByPoints(element.points);
2809
- const resizeHandleRefs = getRectangleResizeHandleRefs(rectangle, RESIZE_HANDLE_DIAMETER);
2810
- const result = resizeHandleRefs.find(resizeHandleRef => {
2811
- return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), resizeHandleRef.rectangle);
2812
- });
2813
- return result;
2814
- };
2815
- const getHitOutlineGeometry = (board, point, offset = 0) => {
2816
- let geometry = null;
2817
- depthFirstRecursion(board, node => {
2818
- if (PlaitDrawElement.isGeometry(node) || PlaitDrawElement.isImage(node)) {
2819
- let client = getRectangleByPoints(node.points);
2820
- client = RectangleClient.getOutlineRectangle(client, offset);
2821
- const shape = getShape(node);
2822
- const isHit = getEngine(shape).isHit(client, point);
2823
- if (isHit) {
2824
- geometry = node;
2825
- }
2826
- }
2827
- }, getIsRecursionFunc(board), true);
2828
- return geometry;
2829
- };
2830
-
2831
2990
  const withLineCreateByDraw = (board) => {
2832
2991
  const { pointerDown, pointerMove, pointerUp } = board;
2833
2992
  let start = null;
2834
- let sourceRef = {};
2835
- let targetRef = {};
2993
+ let sourceElement;
2836
2994
  let lineShapeG = null;
2837
2995
  let temporaryElement = null;
2838
2996
  board.pointerDown = (event) => {
@@ -2841,10 +2999,9 @@ const withLineCreateByDraw = (board) => {
2841
2999
  if (isLinePointer && isDrawingMode(board)) {
2842
3000
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
2843
3001
  start = point;
2844
- const hitElement = getHitOutlineGeometry(board, point, -4);
3002
+ const hitElement = getHitOutlineGeometry(board, point, REACTION_MARGIN);
2845
3003
  if (hitElement) {
2846
- sourceRef.connection = transformPointToConnection(board, point, hitElement);
2847
- sourceRef.boundId = hitElement.id;
3004
+ sourceElement = hitElement;
2848
3005
  }
2849
3006
  preventTouchMove(board, event, true);
2850
3007
  }
@@ -2853,19 +3010,10 @@ const withLineCreateByDraw = (board) => {
2853
3010
  board.pointerMove = (event) => {
2854
3011
  lineShapeG?.remove();
2855
3012
  lineShapeG = createG();
2856
- const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3013
+ let movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
2857
3014
  if (start) {
2858
- const hitElement = getHitOutlineGeometry(board, movingPoint, -4);
2859
- targetRef.connection = hitElement ? transformPointToConnection(board, movingPoint, hitElement) : undefined;
2860
- targetRef.boundId = hitElement ? hitElement.id : undefined;
2861
- const lineGenerator = new LineShapeGenerator(board);
2862
3015
  const lineShape = PlaitBoard.getPointer(board);
2863
- temporaryElement = createLineElement(lineShape, [start, movingPoint], { marker: LineMarkerType.none, connection: sourceRef.connection, boundId: sourceRef?.boundId }, { marker: LineMarkerType.arrow, connection: targetRef.connection, boundId: targetRef?.boundId }, [], {
2864
- strokeColor: DefaultLineStyle.strokeColor,
2865
- strokeWidth: DefaultLineStyle.strokeWidth
2866
- });
2867
- lineGenerator.draw(temporaryElement, lineShapeG);
2868
- PlaitBoard.getElementActiveHost(board).append(lineShapeG);
3016
+ temporaryElement = handleLineCreating(board, lineShape, start, movingPoint, sourceElement, lineShapeG);
2869
3017
  }
2870
3018
  pointerMove(event);
2871
3019
  };
@@ -2878,9 +3026,8 @@ const withLineCreateByDraw = (board) => {
2878
3026
  }
2879
3027
  lineShapeG?.remove();
2880
3028
  lineShapeG = null;
3029
+ sourceElement = null;
2881
3030
  start = null;
2882
- sourceRef = {};
2883
- targetRef = {};
2884
3031
  temporaryElement = null;
2885
3032
  preventTouchMove(board, event, false);
2886
3033
  pointerUp(event);
@@ -3066,7 +3213,7 @@ const withLineResize = (board) => {
3066
3213
  if (resizeRef.handle === LineResizeHandle.source || resizeRef.handle === LineResizeHandle.target) {
3067
3214
  const object = resizeRef.handle === LineResizeHandle.source ? source : target;
3068
3215
  points[pointIndex] = resizeState.endTransformPoint;
3069
- const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, -4);
3216
+ const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, REACTION_MARGIN);
3070
3217
  if (hitElement) {
3071
3218
  object.connection = transformPointToConnection(board, resizeState.endTransformPoint, hitElement);
3072
3219
  object.boundId = hitElement.id;
@@ -3076,7 +3223,9 @@ const withLineResize = (board) => {
3076
3223
  object.boundId = undefined;
3077
3224
  if (points.length === 2) {
3078
3225
  let movingPoint = points[pointIndex];
3079
- const otherPoint = points[Number(!pointIndex)];
3226
+ const drawPoints = getLinePoints(board, resizeRef.element);
3227
+ const index = pointIndex === 0 ? drawPoints.length - 1 : pointIndex;
3228
+ const otherPoint = drawPoints[index];
3080
3229
  points[pointIndex] = alignPoints(otherPoint, movingPoint);
3081
3230
  }
3082
3231
  }
@@ -3093,17 +3242,6 @@ const withLineResize = (board) => {
3093
3242
  withResize(board, options);
3094
3243
  return board;
3095
3244
  };
3096
- const alignPoints = (basePoint, movingPoint) => {
3097
- const offset = 3;
3098
- const newPoint = [...movingPoint];
3099
- if (Point.isVerticalAlign(newPoint, basePoint, offset)) {
3100
- newPoint[0] = basePoint[0];
3101
- }
3102
- if (Point.isHorizontalAlign(newPoint, basePoint, offset)) {
3103
- newPoint[1] = basePoint[1];
3104
- }
3105
- return newPoint;
3106
- };
3107
3245
 
3108
3246
  const withLineBoundReaction = (board) => {
3109
3247
  const { pointerMove, pointerUp } = board;
@@ -3227,7 +3365,7 @@ class ImageComponent extends CommonPluginElement {
3227
3365
  ngOnInit() {
3228
3366
  super.ngOnInit();
3229
3367
  this.initializeGenerator();
3230
- this.imageGenerator.draw(this.element, this.g, this.viewContainerRef);
3368
+ this.imageGenerator.processDrawing(this.element, this.g, this.viewContainerRef);
3231
3369
  }
3232
3370
  onContextChanged(value, previous) {
3233
3371
  if (value.element !== previous.element) {
@@ -3261,6 +3399,96 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3261
3399
  }]
3262
3400
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
3263
3401
 
3402
+ const withAutoCompleteReaction = (board) => {
3403
+ const { pointerMove } = board;
3404
+ let reactionG = null;
3405
+ board.pointerMove = (event) => {
3406
+ reactionG?.remove();
3407
+ if (isSelectionMoving(board)) {
3408
+ pointerMove(event);
3409
+ return;
3410
+ }
3411
+ const selectedElements = getSelectedDrawElements(board);
3412
+ const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3413
+ if (selectedElements.length === 1 && PlaitDrawElement.isGeometry(selectedElements[0])) {
3414
+ const points = getAutoCompletePoints(selectedElements[0]);
3415
+ const hitIndex = getHitIndexOfAutoCompletePoint(movingPoint, points);
3416
+ const hitPoint = points[hitIndex];
3417
+ const component = PlaitElement.getComponent(selectedElements[0]);
3418
+ component.autoCompleteGenerator.recoverAutoCompleteG();
3419
+ if (hitPoint) {
3420
+ component.autoCompleteGenerator.removeAutoCompleteG(hitIndex);
3421
+ reactionG = drawCircle(PlaitBoard.getRoughSVG(board), hitPoint, 10, {
3422
+ stroke: 'none',
3423
+ fill: '#6698FF80',
3424
+ fillStyle: 'solid'
3425
+ });
3426
+ PlaitBoard.getElementActiveHost(board).append(reactionG);
3427
+ }
3428
+ }
3429
+ pointerMove(event);
3430
+ };
3431
+ return board;
3432
+ };
3433
+
3434
+ const withAutoCompletePluginKey = 'plait-auto-complete-plugin-key';
3435
+ const withAutoComplete = (board) => {
3436
+ const { pointerDown, pointerMove, pointerUp } = board;
3437
+ const tolerance = 3;
3438
+ let startPoint = null;
3439
+ let lineShapeG = null;
3440
+ let sourceElement;
3441
+ let temporaryElement;
3442
+ board.pointerDown = (event) => {
3443
+ const selectedElements = getSelectedDrawElements(board);
3444
+ const clickPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3445
+ if (selectedElements.length === 1 && PlaitDrawElement.isGeometry(selectedElements[0])) {
3446
+ const points = getAutoCompletePoints(selectedElements[0]);
3447
+ const index = getHitIndexOfAutoCompletePoint(clickPoint, points);
3448
+ const hitPoint = points[index];
3449
+ if (hitPoint) {
3450
+ temporaryDisableSelection(board);
3451
+ startPoint = clickPoint;
3452
+ sourceElement = selectedElements[0];
3453
+ BoardTransforms.updatePointerType(board, LineShape.elbow);
3454
+ }
3455
+ }
3456
+ pointerDown(event);
3457
+ };
3458
+ board.pointerMove = (event) => {
3459
+ lineShapeG?.remove();
3460
+ lineShapeG = createG();
3461
+ let movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3462
+ if (startPoint && sourceElement) {
3463
+ const distance = distanceBetweenPointAndPoint(...movingPoint, ...startPoint);
3464
+ if (distance > tolerance) {
3465
+ temporaryElement = handleLineCreating(board, LineShape.elbow, startPoint, movingPoint, sourceElement, lineShapeG);
3466
+ }
3467
+ }
3468
+ pointerMove(event);
3469
+ };
3470
+ board.pointerUp = event => {
3471
+ if (temporaryElement) {
3472
+ Transforms.insertNode(board, temporaryElement, [board.children.length]);
3473
+ clearSelectedElement(board);
3474
+ addSelectedElement(board, temporaryElement);
3475
+ const afterComplete = board.getPluginOptions(withAutoCompletePluginKey)
3476
+ ?.afterComplete;
3477
+ afterComplete && afterComplete(temporaryElement);
3478
+ }
3479
+ if (startPoint) {
3480
+ BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
3481
+ startPoint = null;
3482
+ }
3483
+ lineShapeG?.remove();
3484
+ lineShapeG = null;
3485
+ sourceElement = null;
3486
+ temporaryElement = null;
3487
+ pointerUp(event);
3488
+ };
3489
+ return board;
3490
+ };
3491
+
3264
3492
  const withDraw = (board) => {
3265
3493
  const { drawElement, getRectangle, isRectangleHit, isHit, isMovable, isAlign } = board;
3266
3494
  board.drawElement = (context) => {
@@ -3314,11 +3542,13 @@ const withDraw = (board) => {
3314
3542
  const isSelected = (boundId) => {
3315
3543
  return !!selectedElements.find(value => value.id === boundId);
3316
3544
  };
3317
- if ((element.source.boundId && !isSelected(element.source.boundId)) ||
3318
- (element.target.boundId && !isSelected(element.target.boundId))) {
3319
- return false;
3545
+ if ((!element.source.boundId ||
3546
+ (element.source.boundId && isSelected(element.source.boundId) && selectedElements.includes(element))) &&
3547
+ (!element.target.boundId ||
3548
+ (element.target.boundId && isSelected(element.target.boundId) && selectedElements.includes(element)))) {
3549
+ return true;
3320
3550
  }
3321
- return true;
3551
+ return false;
3322
3552
  }
3323
3553
  return isMovable(element);
3324
3554
  };
@@ -3328,12 +3558,12 @@ const withDraw = (board) => {
3328
3558
  }
3329
3559
  return isAlign(element);
3330
3560
  };
3331
- return withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))));
3561
+ return withAutoCompleteReaction(withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))))));
3332
3562
  };
3333
3563
 
3334
3564
  /**
3335
3565
  * Generated bundle index. Do not edit.
3336
3566
  */
3337
3567
 
3338
- export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultBasicShapeProperty, DefaultConnectorProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultGeometryActiveStyle, DefaultGeometryStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultTextProperty, DrawTransforms, FlowchartSymbols, GeometryComponent, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, ShapeDefaultSpace, StrokeStyle, createDefaultFlowchart, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getBasicPointers, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getEdgeOnPolygonByPoint, getElbowPoints, getFillByElement, getFlowchartPointers, getGeometryPointers, getHitConnectorPoint, getHitLineTextIndex, getLineDashByElement, getLineHandleRefPair, getLinePointers, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getVectorByConnection, isHitDrawElement, isHitLineText, isHitPolyLine, isRectangleHitDrawElement, isTextExceedingBounds, transformOpsToPoints, transformPointToConnection, withDraw };
3568
+ 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, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getAutoCompletePoints, getBasicPointers, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getDrawDefaultStrokeColor, getEdgeOnPolygonByPoint, getElbowPoints, getFillByElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryPointers, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitLineTextIndex, getLineDashByElement, getLineHandleRefPair, getLinePointers, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getVectorByConnection, handleLineCreating, isHitDrawElement, isHitLineText, isHitPolyLine, isRectangleHitDrawElement, isTextExceedingBounds, transformOpsToPoints, transformPointToConnection, withDraw };
3339
3569
  //# sourceMappingURL=plait-draw.mjs.map