@plait/draw 0.35.0 → 0.37.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 (52) hide show
  1. package/constants/line.d.ts +4 -0
  2. package/esm2022/constants/line.mjs +5 -1
  3. package/esm2022/generators/line-active.generator.mjs +10 -7
  4. package/esm2022/generators/line-auto-complete.generator.mjs +45 -0
  5. package/esm2022/geometry.component.mjs +21 -11
  6. package/esm2022/image.component.mjs +14 -1
  7. package/esm2022/interfaces/element.mjs +2 -1
  8. package/esm2022/interfaces/index.mjs +2 -2
  9. package/esm2022/line.component.mjs +10 -15
  10. package/esm2022/plugins/with-draw-hotkey.mjs +5 -4
  11. package/esm2022/plugins/with-draw.mjs +4 -4
  12. package/esm2022/plugins/with-geometry-create.mjs +69 -53
  13. package/esm2022/plugins/with-line-auto-complete-reaction.mjs +36 -0
  14. package/esm2022/plugins/with-line-auto-complete.mjs +61 -0
  15. package/esm2022/plugins/with-line-bound-reaction.mjs +5 -1
  16. package/esm2022/plugins/with-line-create.mjs +2 -2
  17. package/esm2022/plugins/with-line-resize.mjs +2 -2
  18. package/esm2022/plugins/with-line-text.mjs +29 -27
  19. package/esm2022/transforms/geometry.mjs +3 -3
  20. package/esm2022/transforms/index.mjs +2 -7
  21. package/esm2022/utils/geometry.mjs +25 -12
  22. package/esm2022/utils/index.mjs +2 -1
  23. package/esm2022/utils/line-arrow.mjs +10 -6
  24. package/esm2022/utils/line.mjs +12 -5
  25. package/esm2022/utils/memorize.mjs +75 -0
  26. package/fesm2022/plait-draw.mjs +432 -325
  27. package/fesm2022/plait-draw.mjs.map +1 -1
  28. package/generators/line-active.generator.d.ts +0 -1
  29. package/generators/{auto-complete.generator.d.ts → line-auto-complete.generator.d.ts} +3 -3
  30. package/geometry.component.d.ts +2 -2
  31. package/image.component.d.ts +2 -0
  32. package/interfaces/element.d.ts +1 -0
  33. package/interfaces/index.d.ts +2 -2
  34. package/line.component.d.ts +0 -1
  35. package/package.json +1 -1
  36. package/plugins/with-geometry-create.d.ts +7 -2
  37. package/plugins/with-line-auto-complete-reaction.d.ts +2 -0
  38. package/plugins/with-line-auto-complete.d.ts +7 -0
  39. package/styles/styles.scss +1 -2
  40. package/transforms/index.d.ts +0 -4
  41. package/utils/geometry.d.ts +15 -4
  42. package/utils/index.d.ts +1 -0
  43. package/utils/line.d.ts +4 -4
  44. package/utils/memorize.d.ts +25 -0
  45. package/utils/position/geometry.d.ts +1 -1
  46. package/esm2022/generators/auto-complete.generator.mjs +0 -44
  47. package/esm2022/plugins/with-auto-complete-reaction.mjs +0 -35
  48. package/esm2022/plugins/with-auto-complete.mjs +0 -61
  49. package/esm2022/transforms/common.mjs +0 -33
  50. package/plugins/with-auto-complete-reaction.d.ts +0 -2
  51. package/plugins/with-auto-complete.d.ts +0 -7
  52. package/transforms/common.d.ts +0 -6
@@ -1,10 +1,10 @@
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
- import { AlignEditor, Alignment, DEFAULT_FONT_SIZE, buildText, TextManage, getTextFromClipboard, getTextSize } from '@plait/text';
1
+ import { PlaitElement, ACTIVE_STROKE_WIDTH, ThemeColorMode, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, createG, transformPoint, toPoint, preventTouchMove, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, idCreator, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, arrowPoints, createPath, distanceBetweenPointAndPoint, drawLinearPath, rotate, depthFirstRecursion, getIsRecursionFunc, getElementById, Direction, catmullRomFitting, distanceBetweenPointAndSegments, createMask, createRect, findElements, Point, getSelectedElements, isPolylineHitRectangle, PlaitNode, BOARD_TO_HOST, isSelectionMoving, RgbaToHEX, PlaitPluginElementComponent, setClipboardData, getDataFromClipboard, getHitElementByPoint, CursorClass, temporaryDisableSelection, PRESS_AND_MOVE_BUFFER } from '@plait/core';
2
+ import { getRectangleByPoints, Generator, isDndMode, isDrawingMode, normalizeShapePoints, RESIZE_HANDLE_DIAMETER, getExtendPoint, getFactorByPoints, getRectangleResizeHandleRefs, getMemorizedLatest, memorizeLatest, getDirectionByVector, getOppositeDirection, getDirectionFactor, DEFAULT_ROUTE_MARGIN, reduceRouteMargin, getNextPoint, generateElbowLineRoute, getPoints, removeDuplicatePoints, getPointByVector, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90, TRANSPARENT, PRIMARY_COLOR, CommonPluginElement, ActiveGenerator, WithTextPluginKey, isVirtualKey, isDelete, isSpaceHotkey, acceptImageTypes, getElementOfFocusedImage, buildImage, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint, ImageGenerator } from '@plait/common';
3
+ import { TextManage, Alignment, buildText, DEFAULT_FONT_SIZE, getTextSize, AlignEditor, getTextFromClipboard } from '@plait/text';
4
4
  import { isKeyHotkey } from 'is-hotkey';
5
- import { pointsOnBezierCurves } from 'points-on-curve';
6
5
  import * as i0 from '@angular/core';
7
- import { Component, ChangeDetectionStrategy } from '@angular/core';
6
+ import { NgZone, Component, ChangeDetectionStrategy } from '@angular/core';
7
+ import { pointsOnBezierCurves } from 'points-on-curve';
8
8
  import { Subject } from 'rxjs';
9
9
  import { Node } from 'slate';
10
10
 
@@ -1223,181 +1223,11 @@ class GeometryShapeGenerator extends Generator {
1223
1223
  }
1224
1224
  }
1225
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
-
1257
- const insertGeometry = (board, points, shape) => {
1258
- let newElement = createGeometryElement(shape, points, '', {
1259
- strokeWidth: DefaultBasicShapeProperty.strokeWidth
1260
- });
1261
- Transforms.insertNode(board, newElement, [board.children.length]);
1262
- clearSelectedElement(board);
1263
- addSelectedElement(board, newElement);
1264
- };
1265
- const insertText = (board, points, text = '文本') => {
1266
- let newElement = createGeometryElement(BasicShapes.text, points, text);
1267
- Transforms.insertNode(board, newElement, [board.children.length]);
1268
- clearSelectedElement(board);
1269
- addSelectedElement(board, newElement);
1270
- };
1271
- const resizeGeometry = (board, points, textHeight, path) => {
1272
- const normalizePoints = normalizeShapePoints(points);
1273
- const element = PlaitNode.get(board, path);
1274
- const newHeight = textHeight / board.viewport.zoom;
1275
- const newProperties = { points: normalizePoints, textHeight: newHeight };
1276
- if (PlaitDrawElement.isText(element) && element.autoSize) {
1277
- newProperties.autoSize = false;
1278
- }
1279
- Transforms.setNode(board, newProperties, path);
1280
- };
1281
- const transformShape = (board, element, shape) => {
1282
- const path = PlaitBoard.findPath(board, element);
1283
- Transforms.setNode(board, { shape }, path);
1284
- };
1285
-
1286
- const normalizePoints = (board, element, width, textHeight) => {
1287
- let points = element.points;
1288
- let autoSize = element.autoSize;
1289
- const defaultSpace = ShapeDefaultSpace.rectangleAndText;
1290
- if (autoSize) {
1291
- const editor = PlaitGeometry.getTextEditor(element);
1292
- if (AlignEditor.isActive(editor, Alignment.right)) {
1293
- points = [
1294
- [points[1][0] - (width + defaultSpace * 2), points[0][1]],
1295
- [points[1][0], points[0][1] + textHeight]
1296
- ];
1297
- }
1298
- else if (AlignEditor.isActive(editor, Alignment.center)) {
1299
- const oldWidth = Math.abs(points[0][0] - points[1][0]);
1300
- const offset = (width - oldWidth) / 2;
1301
- points = [
1302
- [points[0][0] - offset - defaultSpace, points[0][1]],
1303
- [points[1][0] + offset + defaultSpace, points[0][1] + textHeight]
1304
- ];
1305
- }
1306
- else {
1307
- points = [points[0], [points[0][0] + width + defaultSpace * 2, points[0][1] + textHeight]];
1308
- }
1309
- }
1310
- return { points };
1311
- };
1312
- const setText = (board, element, text, width, textHeight) => {
1313
- const newElement = {
1314
- text,
1315
- textHeight,
1316
- ...normalizePoints(board, element, width, textHeight)
1317
- };
1318
- const path = board.children.findIndex(child => child === element);
1319
- Transforms.setNode(board, newElement, [path]);
1320
- };
1321
- const setTextSize = (board, element, textWidth, textHeight) => {
1322
- if (element.autoSize) {
1323
- const newElement = {
1324
- textHeight,
1325
- ...normalizePoints(board, element, textWidth, textHeight)
1326
- };
1327
- const isPointsEqual = Point.isEquals(element.points[0], newElement.points[0]) && Point.isEquals(element.points[1], newElement.points[1]);
1328
- const isTextHeightEqual = Math.round(textHeight) === Math.round(element.textHeight);
1329
- if (!isPointsEqual || !isTextHeightEqual) {
1330
- const path = board.children.findIndex(child => child === element);
1331
- Transforms.setNode(board, newElement, [path]);
1332
- }
1333
- }
1334
- };
1335
-
1336
- const insertImage = (board, imageItem, startPoint) => {
1337
- const { width, height, url } = imageItem;
1338
- const host = BOARD_TO_HOST.get(board);
1339
- const viewportWidth = PlaitBoard.getComponent(board).nativeElement.clientWidth;
1340
- const viewportHeight = PlaitBoard.getComponent(board).nativeElement.clientHeight;
1341
- const point = transformPoint(board, toPoint(viewportWidth / 2, viewportHeight / 2, host));
1342
- const points = startPoint
1343
- ? [startPoint, [startPoint[0] + width, startPoint[1] + height]]
1344
- : [
1345
- [point[0] - width / 2, point[1] - height / 2],
1346
- [point[0] + width / 2, point[1] + height / 2]
1347
- ];
1348
- const imageElement = {
1349
- id: idCreator(),
1350
- type: 'image',
1351
- points,
1352
- url
1353
- };
1354
- Transforms.insertNode(board, imageElement, [board.children.length]);
1355
- Transforms.addSelectionWithTemporaryElements(board, [imageElement]);
1356
- };
1357
-
1358
- const resizeLine = (board, options, path) => {
1359
- Transforms.setNode(board, options, path);
1360
- };
1361
- const setLineTexts = (board, element, texts) => {
1362
- const path = PlaitBoard.findPath(board, element);
1363
- Transforms.setNode(board, { texts }, path);
1364
- };
1365
- const removeLineText = (board, element, index) => {
1366
- const path = PlaitBoard.findPath(board, element);
1367
- const texts = element.texts?.length ? [...element.texts] : [];
1368
- const newTexts = [...texts];
1369
- newTexts.splice(index, 1);
1370
- Transforms.setNode(board, { texts: newTexts }, path);
1371
- };
1372
- const setLineMark = (board, element, handleKey, marker) => {
1373
- const path = PlaitBoard.findPath(board, element);
1374
- let handle = handleKey === LineHandleKey.source ? element.source : element.target;
1375
- handle = { ...handle, marker };
1376
- memorizeLatest(MemorizeKey.line, handleKey, marker);
1377
- Transforms.setNode(board, { [handleKey]: handle }, path);
1378
- };
1379
-
1380
- const DrawTransforms = {
1381
- setText,
1382
- insertGeometry,
1383
- resizeGeometry,
1384
- insertText,
1385
- setTextSize,
1386
- resizeLine,
1387
- setLineTexts,
1388
- removeLineText,
1389
- setLineMark,
1390
- insertImage,
1391
- transformShape,
1392
- setStrokeColor,
1393
- setStrokeWidth,
1394
- setFillColor,
1395
- setStrokeStyle
1396
- };
1397
-
1398
1226
  const withGeometryCreateByDrag = (board) => {
1399
1227
  const { pointerMove, pointerUp } = board;
1400
1228
  let geometryShapeG = null;
1229
+ let temporaryElement = null;
1230
+ let fakeCreateTextRef = null;
1401
1231
  board.pointerMove = (event) => {
1402
1232
  geometryShapeG?.remove();
1403
1233
  geometryShapeG = createG();
@@ -1408,16 +1238,39 @@ const withGeometryCreateByDrag = (board) => {
1408
1238
  const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1409
1239
  const pointer = PlaitBoard.getPointer(board);
1410
1240
  if (dragMode) {
1411
- const points = getDefaultGeometryPoints(pointer, movingPoint);
1241
+ const memorizedLatest = getMemorizedLatestByPointer(pointer);
1412
1242
  if (pointer === BasicShapes.text) {
1413
- const textG = getTemporaryTextG(movingPoint);
1414
- geometryShapeG.appendChild(textG);
1415
- PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1243
+ const points = getDefaultGeometryPoints(board, pointer, movingPoint, memorizedLatest.textProperties['font-size']);
1244
+ temporaryElement = createGeometryElement(board, BasicShapes.text, points, DefaultTextProperty.text, memorizedLatest.geometryProperties, memorizedLatest.textProperties);
1245
+ if (!fakeCreateTextRef) {
1246
+ const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, {
1247
+ getRectangle: () => {
1248
+ return getTextRectangle(temporaryElement);
1249
+ }
1250
+ });
1251
+ PlaitBoard.getComponent(board)
1252
+ .viewContainerRef.injector.get(NgZone)
1253
+ .run(() => {
1254
+ textManage.draw(temporaryElement.text);
1255
+ });
1256
+ fakeCreateTextRef = {
1257
+ g: createG(),
1258
+ textManage
1259
+ };
1260
+ PlaitBoard.getHost(board).append(fakeCreateTextRef.g);
1261
+ fakeCreateTextRef.g.append(textManage.g);
1262
+ }
1263
+ else {
1264
+ fakeCreateTextRef.textManage.updateRectangle();
1265
+ fakeCreateTextRef.g.append(fakeCreateTextRef.textManage.g);
1266
+ }
1416
1267
  }
1417
1268
  else {
1418
- const temporaryElement = createGeometryElement(pointer, points, '', {
1419
- strokeWidth: DefaultBasicShapeProperty.strokeWidth
1420
- });
1269
+ const points = getDefaultGeometryPoints(board, pointer, movingPoint);
1270
+ temporaryElement = createGeometryElement(board, pointer, points, '', {
1271
+ strokeWidth: DefaultBasicShapeProperty.strokeWidth,
1272
+ ...memorizedLatest.geometryProperties
1273
+ }, memorizedLatest.textProperties);
1421
1274
  geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
1422
1275
  PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1423
1276
  }
@@ -1425,20 +1278,14 @@ const withGeometryCreateByDrag = (board) => {
1425
1278
  pointerMove(event);
1426
1279
  };
1427
1280
  board.pointerUp = (event) => {
1428
- const pointer = PlaitBoard.getPointer(board);
1429
1281
  const geometryPointers = getGeometryPointers();
1430
1282
  const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
1431
1283
  const dragMode = isGeometryPointer && isDndMode(board);
1432
- if (dragMode) {
1433
- const targetPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1434
- const points = getDefaultGeometryPoints(pointer, targetPoint);
1435
- if (pointer === BasicShapes.text) {
1436
- DrawTransforms.insertText(board, points);
1437
- }
1438
- else {
1439
- DrawTransforms.insertGeometry(board, points, pointer);
1440
- }
1441
- BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1284
+ if (dragMode && temporaryElement) {
1285
+ insertElement(board, temporaryElement);
1286
+ fakeCreateTextRef?.textManage.destroy();
1287
+ fakeCreateTextRef?.g.remove();
1288
+ fakeCreateTextRef = null;
1442
1289
  }
1443
1290
  geometryShapeG?.remove();
1444
1291
  geometryShapeG = null;
@@ -1464,14 +1311,15 @@ const withGeometryCreateByDrawing = (board) => {
1464
1311
  board.pointerDown = (event) => {
1465
1312
  const geometryPointers = getGeometryPointers();
1466
1313
  const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
1467
- if (isGeometryPointer && isDrawingMode(board)) {
1314
+ if (!PlaitBoard.isReadonly(board) && isGeometryPointer && isDrawingMode(board)) {
1468
1315
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1469
1316
  start = point;
1470
1317
  const pointer = PlaitBoard.getPointer(board);
1471
1318
  preventTouchMove(board, event, true);
1472
1319
  if (pointer === BasicShapes.text) {
1473
- const points = getDefaultGeometryPoints(pointer, point);
1474
- const textElement = createGeometryElement(BasicShapes.text, points, DefaultTextProperty.text);
1320
+ const memorizedLatest = getMemorizedLatestByPointer(pointer);
1321
+ const points = getDefaultGeometryPoints(board, pointer, point, memorizedLatest.textProperties['font-size']);
1322
+ const textElement = createGeometryElement(board, BasicShapes.text, points, DefaultTextProperty.text, memorizedLatest.geometryProperties, memorizedLatest.textProperties);
1475
1323
  Transforms.insertNode(board, textElement, [board.children.length]);
1476
1324
  clearSelectedElement(board);
1477
1325
  addSelectedElement(board, textElement);
@@ -1490,9 +1338,11 @@ const withGeometryCreateByDrawing = (board) => {
1490
1338
  const pointer = PlaitBoard.getPointer(board);
1491
1339
  if (drawMode && pointer !== BasicShapes.text) {
1492
1340
  const points = normalizeShapePoints([start, movingPoint], isShift);
1493
- temporaryElement = createGeometryElement(pointer, points, '', {
1494
- strokeWidth: DefaultBasicShapeProperty.strokeWidth
1495
- });
1341
+ const memorizedLatest = getMemorizedLatestByPointer(pointer);
1342
+ temporaryElement = createGeometryElement(board, pointer, points, '', {
1343
+ strokeWidth: DefaultBasicShapeProperty.strokeWidth,
1344
+ ...memorizedLatest.geometryProperties
1345
+ }, memorizedLatest.textProperties);
1496
1346
  geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
1497
1347
  PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1498
1348
  }
@@ -1505,19 +1355,18 @@ const withGeometryCreateByDrawing = (board) => {
1505
1355
  const { width, height } = RectangleClient.toRectangleClient([start, targetPoint]);
1506
1356
  if (Math.hypot(width, height) === 0) {
1507
1357
  const pointer = PlaitBoard.getPointer(board);
1508
- const points = getDefaultGeometryPoints(pointer, targetPoint);
1358
+ const points = getDefaultGeometryPoints(board, pointer, targetPoint);
1509
1359
  if (pointer !== BasicShapes.text) {
1510
- temporaryElement = createGeometryElement(pointer, points, '', {
1511
- strokeWidth: DefaultBasicShapeProperty.strokeWidth
1512
- });
1360
+ const memorizedLatest = getMemorizedLatestByPointer(pointer);
1361
+ temporaryElement = createGeometryElement(board, pointer, points, '', {
1362
+ strokeWidth: DefaultBasicShapeProperty.strokeWidth,
1363
+ ...memorizedLatest.geometryProperties
1364
+ }, memorizedLatest.textProperties);
1513
1365
  }
1514
1366
  }
1515
1367
  }
1516
1368
  if (temporaryElement) {
1517
- Transforms.insertNode(board, temporaryElement, [board.children.length]);
1518
- clearSelectedElement(board);
1519
- addSelectedElement(board, temporaryElement);
1520
- BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1369
+ insertElement(board, temporaryElement);
1521
1370
  }
1522
1371
  geometryShapeG?.remove();
1523
1372
  geometryShapeG = null;
@@ -1528,15 +1377,15 @@ const withGeometryCreateByDrawing = (board) => {
1528
1377
  };
1529
1378
  return board;
1530
1379
  };
1531
- const getDefaultGeometryPoints = (pointer, targetPoint) => {
1532
- const defaultProperty = getGeometryDefaultProperty(pointer);
1380
+ const getDefaultGeometryPoints = (board, pointer, targetPoint, fontSize) => {
1381
+ const defaultProperty = getGeometryDefaultProperty(board, pointer, fontSize);
1533
1382
  return getPointsByCenterPoint(targetPoint, defaultProperty.width, defaultProperty.height);
1534
1383
  };
1535
- const getGeometryDefaultProperty = (pointer) => {
1384
+ const getGeometryDefaultProperty = (board, pointer, fontSize) => {
1536
1385
  const isText = pointer === BasicShapes.text;
1537
1386
  const isFlowChart = getFlowchartPointers().includes(pointer);
1538
1387
  if (isText) {
1539
- return DefaultTextProperty;
1388
+ return getDefaultTextShapeProperty(board, fontSize);
1540
1389
  }
1541
1390
  else if (isFlowChart) {
1542
1391
  return getDefaultFlowchartProperty(pointer);
@@ -1545,17 +1394,12 @@ const getGeometryDefaultProperty = (pointer) => {
1545
1394
  return DefaultBasicShapeProperty;
1546
1395
  }
1547
1396
  };
1548
- const getTemporaryTextG = (movingPoint) => {
1549
- const textG = createG();
1550
- const width = DefaultTextProperty.width - ShapeDefaultSpace.rectangleAndText * 2;
1551
- const foreignObject = createForeignObject(movingPoint[0] - width / 2, movingPoint[1] - DefaultTextProperty.height / 2, width, DefaultTextProperty.height);
1552
- const richtext = document.createElement('div');
1553
- richtext.textContent = DefaultTextProperty.text;
1554
- richtext.style.fontSize = `${DEFAULT_FONT_SIZE}px`;
1555
- richtext.style.cursor = 'default';
1556
- foreignObject.appendChild(richtext);
1557
- textG.appendChild(foreignObject);
1558
- return textG;
1397
+ const insertElement = (board, element) => {
1398
+ memorizeLatestShape(board, element.shape);
1399
+ Transforms.insertNode(board, element, [board.children.length]);
1400
+ clearSelectedElement(board);
1401
+ addSelectedElement(board, element);
1402
+ BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1559
1403
  };
1560
1404
 
1561
1405
  const DefaultLineStyle = {
@@ -1563,22 +1407,30 @@ const DefaultLineStyle = {
1563
1407
  strokeColor: '#000'
1564
1408
  };
1565
1409
  const LINE_TEXT_SPACE = 4;
1410
+ const LINE_AUTO_COMPLETE_DIAMETER = 6;
1411
+ const LINE_AUTO_COMPLETE_OPACITY = 0.6;
1412
+ const LINE_AUTO_COMPLETE_HOVERED_OPACITY = 0.8;
1413
+ const LINE_AUTO_COMPLETE_HOVERED_DIAMETER = 10;
1566
1414
 
1567
- const createGeometryElement = (shape, points, text, options) => {
1415
+ const createGeometryElement = (board, shape, points, text, options = {}, textProperties = {}) => {
1568
1416
  let textOptions = {};
1569
1417
  let alignment = Alignment.center;
1570
1418
  if (shape === BasicShapes.text) {
1571
1419
  textOptions = { autoSize: true };
1572
1420
  alignment = undefined;
1573
1421
  }
1422
+ textProperties = { ...textProperties };
1423
+ textProperties?.align && (alignment = textProperties?.align);
1424
+ delete textProperties?.align;
1425
+ const textHeight = getDefaultTextShapeProperty(board, textProperties['font-size']).height;
1574
1426
  return {
1575
1427
  id: idCreator(),
1576
1428
  type: 'geometry',
1577
1429
  shape,
1578
1430
  angle: 0,
1579
1431
  opacity: 1,
1580
- textHeight: DefaultTextProperty.height,
1581
- text: buildText(text, alignment),
1432
+ textHeight,
1433
+ text: buildText(text, alignment, textProperties),
1582
1434
  points,
1583
1435
  ...textOptions,
1584
1436
  ...options
@@ -1656,7 +1508,7 @@ const getEdgeOnPolygonByPoint = (corners, point) => {
1656
1508
  const getDefaultFlowchartProperty = (symbol) => {
1657
1509
  return DefaultFlowchartPropertyMap[symbol];
1658
1510
  };
1659
- const createDefaultFlowchart = (point) => {
1511
+ const createDefaultFlowchart = (board, point) => {
1660
1512
  const decisionProperty = getDefaultFlowchartProperty(FlowchartSymbols.decision);
1661
1513
  const processProperty = getDefaultFlowchartProperty(FlowchartSymbols.process);
1662
1514
  const terminalProperty = getDefaultFlowchartProperty(FlowchartSymbols.terminal);
@@ -1666,15 +1518,15 @@ const createDefaultFlowchart = (point) => {
1666
1518
  const lineOptions = {
1667
1519
  strokeWidth: DefaultLineStyle.strokeWidth
1668
1520
  };
1669
- const startElement = createGeometryElement(FlowchartSymbols.terminal, getDefaultGeometryPoints(FlowchartSymbols.terminal, point), '开始', options);
1521
+ const startElement = createGeometryElement(board, FlowchartSymbols.terminal, getDefaultGeometryPoints(board, FlowchartSymbols.terminal, point), '开始', options);
1670
1522
  const processPoint1 = [point[0], point[1] + terminalProperty.height / 2 + 55 + processProperty.height / 2];
1671
- const processElement1 = createGeometryElement(FlowchartSymbols.process, getDefaultGeometryPoints(FlowchartSymbols.process, processPoint1), '过程', options);
1523
+ const processElement1 = createGeometryElement(board, FlowchartSymbols.process, getDefaultGeometryPoints(board, FlowchartSymbols.process, processPoint1), '过程', options);
1672
1524
  const decisionPoint = [processPoint1[0], processPoint1[1] + processProperty.height / 2 + 55 + decisionProperty.height / 2];
1673
- const decisionElement = createGeometryElement(FlowchartSymbols.decision, getDefaultGeometryPoints(FlowchartSymbols.decision, decisionPoint), '过程', options);
1525
+ const decisionElement = createGeometryElement(board, FlowchartSymbols.decision, getDefaultGeometryPoints(board, FlowchartSymbols.decision, decisionPoint), '过程', options);
1674
1526
  const processPoint2 = [decisionPoint[0] + decisionProperty.width / 2 + 75 + processProperty.width / 2, decisionPoint[1]];
1675
- const processElement2 = createGeometryElement(FlowchartSymbols.process, getDefaultGeometryPoints(FlowchartSymbols.process, processPoint2), '过程', options);
1527
+ const processElement2 = createGeometryElement(board, FlowchartSymbols.process, getDefaultGeometryPoints(board, FlowchartSymbols.process, processPoint2), '过程', options);
1676
1528
  const endPoint = [decisionPoint[0], decisionPoint[1] + decisionProperty.height / 2 + 95 + terminalProperty.height / 2];
1677
- const endElement = createGeometryElement(FlowchartSymbols.terminal, getDefaultGeometryPoints(FlowchartSymbols.terminal, endPoint), '结束', options);
1529
+ const endElement = createGeometryElement(board, FlowchartSymbols.terminal, getDefaultGeometryPoints(board, FlowchartSymbols.terminal, endPoint), '结束', options);
1678
1530
  const line1 = createLineElement(LineShape.elbow, [
1679
1531
  [0, 0],
1680
1532
  [0, 0]
@@ -1731,8 +1583,17 @@ const getDrawDefaultStrokeColor = (theme) => {
1731
1583
  const getFlowchartDefaultFill = (theme) => {
1732
1584
  return DrawThemeColors[theme].fill;
1733
1585
  };
1586
+ const getDefaultTextShapeProperty = (board, fontSize) => {
1587
+ fontSize = fontSize ? Number(fontSize) : DEFAULT_FONT_SIZE;
1588
+ const textSize = getTextSize(board, '文本', 10, { fontSize });
1589
+ return {
1590
+ width: textSize.width + ShapeDefaultSpace.rectangleAndText * 2,
1591
+ height: textSize.height,
1592
+ text: '文本'
1593
+ };
1594
+ };
1734
1595
 
1735
- const MAX_LENGTH = 100;
1596
+ const ARROW_LENGTH = 20;
1736
1597
  const drawLineArrow = (element, points, options) => {
1737
1598
  const arrowG = createG();
1738
1599
  if (PlaitLine.isSourceMark(element, LineMarkerType.none) && PlaitLine.isTargetMark(element, LineMarkerType.none)) {
@@ -1740,13 +1601,16 @@ const drawLineArrow = (element, points, options) => {
1740
1601
  }
1741
1602
  const strokeWidth = getStrokeWidthByElement(element);
1742
1603
  const offset = (strokeWidth * strokeWidth) / 3;
1604
+ if (points.length === 1) {
1605
+ points = [points[0], [points[0][0] + 0.1, points[0][1]]];
1606
+ }
1743
1607
  if (!PlaitLine.isSourceMark(element, LineMarkerType.none)) {
1744
- const source = getExtendPoint(points[0], points[1], 24 + offset);
1608
+ const source = getExtendPoint(points[0], points[1], ARROW_LENGTH + offset);
1745
1609
  const sourceArrow = getArrow(element, { marker: element.source.marker, source, target: points[0], isSource: true }, options);
1746
1610
  sourceArrow && arrowG.appendChild(sourceArrow);
1747
1611
  }
1748
1612
  if (!PlaitLine.isTargetMark(element, LineMarkerType.none)) {
1749
- const source = getExtendPoint(points[points.length - 1], points[points.length - 2], 24 + offset);
1613
+ const source = getExtendPoint(points[points.length - 1], points[points.length - 2], ARROW_LENGTH + offset);
1750
1614
  const arrow = getArrow(element, { marker: element.target.marker, source, target: points[points.length - 1], isSource: false }, options);
1751
1615
  arrow && arrowG.appendChild(arrow);
1752
1616
  }
@@ -1808,9 +1672,10 @@ const drawArrow = (element, source, target, options) => {
1808
1672
  const directionFactor = getFactorByPoints(source, target);
1809
1673
  const strokeWidth = getStrokeWidthByElement(element);
1810
1674
  const endPoint = [target[0] + (strokeWidth * directionFactor.x) / 2, target[1] + (strokeWidth * directionFactor.y) / 2];
1675
+ const distance = distanceBetweenPointAndPoint(...source, ...endPoint);
1811
1676
  const middlePoint = [
1812
- endPoint[0] - (8 + strokeWidth / 2) * directionFactor.x,
1813
- endPoint[1] - (8 + strokeWidth / 2) * directionFactor.y
1677
+ endPoint[0] - (((distance * 3) / 5 + strokeWidth) / 2) * directionFactor.x,
1678
+ endPoint[1] - (((distance * 3) / 5 + strokeWidth) / 2) * directionFactor.y
1814
1679
  ];
1815
1680
  const { pointLeft, pointRight } = arrowPoints(source, endPoint, 30);
1816
1681
  const arrowG = drawLinearPath([pointLeft, endPoint, pointRight, middlePoint], { ...options, fill: options.stroke }, true);
@@ -1882,6 +1747,79 @@ const getHitOutlineGeometry = (board, point, offset = 0) => {
1882
1747
  return geometry;
1883
1748
  };
1884
1749
 
1750
+ const SHAPE_MAX_LENGTH = 6;
1751
+ const memorizedShape = new WeakMap();
1752
+ const getMemorizeKey = (element) => {
1753
+ let key = '';
1754
+ switch (true) {
1755
+ case PlaitDrawElement.isText(element): {
1756
+ key = MemorizeKey.text;
1757
+ break;
1758
+ }
1759
+ case PlaitDrawElement.isBasicShape(element): {
1760
+ key = MemorizeKey.basicShape;
1761
+ break;
1762
+ }
1763
+ case PlaitDrawElement.isFlowchart(element): {
1764
+ key = MemorizeKey.flowchart;
1765
+ break;
1766
+ }
1767
+ case PlaitDrawElement.isLine(element): {
1768
+ key = MemorizeKey.line;
1769
+ break;
1770
+ }
1771
+ }
1772
+ return key;
1773
+ };
1774
+ const getLineMemorizedLatest = () => {
1775
+ const properties = getMemorizedLatest(MemorizeKey.line);
1776
+ delete properties?.text;
1777
+ return { ...properties } || {};
1778
+ };
1779
+ const getMemorizedLatestByPointer = (pointer) => {
1780
+ let memorizeKey = '';
1781
+ if (PlaitDrawElement.isBasicShape({ shape: pointer })) {
1782
+ memorizeKey = pointer === BasicShapes.text ? MemorizeKey.text : MemorizeKey.basicShape;
1783
+ }
1784
+ else {
1785
+ memorizeKey = MemorizeKey.flowchart;
1786
+ }
1787
+ const properties = { ...getMemorizedLatest(memorizeKey) } || {};
1788
+ const textProperties = properties.text || {};
1789
+ delete properties.text;
1790
+ return { textProperties, geometryProperties: properties };
1791
+ };
1792
+ const memorizeLatestText = (element, operations) => {
1793
+ const memorizeKey = getMemorizeKey(element);
1794
+ let textMemory = getMemorizedLatest(memorizeKey)?.text || {};
1795
+ const setNodeOperation = operations.find(operation => operation.type === 'set_node');
1796
+ if (setNodeOperation) {
1797
+ const newProperties = setNodeOperation.newProperties;
1798
+ textMemory = { ...textMemory, ...newProperties };
1799
+ memorizeLatest(memorizeKey, 'text', textMemory);
1800
+ }
1801
+ };
1802
+ const memorizeLatestShape = (board, shape) => {
1803
+ const shapes = memorizedShape.has(board) ? memorizedShape.get(board) : [];
1804
+ const shapeIndex = shapes.indexOf(shape);
1805
+ if (shape === BasicShapes.text || shapeIndex === 0) {
1806
+ return;
1807
+ }
1808
+ if (shapeIndex !== -1) {
1809
+ shapes.splice(shapeIndex, 1);
1810
+ }
1811
+ else {
1812
+ if (shapes.length === SHAPE_MAX_LENGTH) {
1813
+ shapes.pop();
1814
+ }
1815
+ }
1816
+ shapes.unshift(shape);
1817
+ memorizedShape.set(board, shapes);
1818
+ };
1819
+ const getMemorizedLatestShape = (board) => {
1820
+ return memorizedShape.get(board);
1821
+ };
1822
+
1885
1823
  const createLineElement = (shape, points, source, target, texts, options) => {
1886
1824
  return {
1887
1825
  id: idCreator(),
@@ -2079,7 +2017,6 @@ const drawLine = (board, element) => {
2079
2017
  let points = getLinePoints(board, element);
2080
2018
  let line;
2081
2019
  if (element.shape === LineShape.curve) {
2082
- //TODO element.points 应为曲线拐点
2083
2020
  line = PlaitBoard.getRoughSVG(board).curve(points, options);
2084
2021
  }
2085
2022
  else {
@@ -2142,7 +2079,7 @@ const transformPointToConnection = (board, point, hitElement) => {
2142
2079
  const getHitConnectorPoint = (movingPoint, hitElement, rectangle) => {
2143
2080
  const shape = getShape(hitElement);
2144
2081
  const connector = getEngine(shape).getConnectorPoints(rectangle);
2145
- const points = getPointsByCenterPoint(movingPoint, 5, 5);
2082
+ const points = getPointsByCenterPoint(movingPoint, 10, 10);
2146
2083
  const pointRectangle = getRectangleByPoints(points);
2147
2084
  return connector.find(point => {
2148
2085
  return RectangleClient.isHit(pointRectangle, RectangleClient.toRectangleClient([point, point]));
@@ -2223,8 +2160,15 @@ const handleLineCreating = (board, lineShape, startPoint, movingPoint, sourceEle
2223
2160
  const connection = sourceElement ? transformPointToConnection(board, startPoint, sourceElement) : undefined;
2224
2161
  const targetBoundId = hitElement ? hitElement.id : undefined;
2225
2162
  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
2163
+ const memorizedLatest = getLineMemorizedLatest();
2164
+ let sourceMarker, targetMarker;
2165
+ sourceMarker = memorizedLatest.source;
2166
+ targetMarker = memorizedLatest.target;
2167
+ sourceMarker && delete memorizedLatest.source;
2168
+ targetMarker && delete memorizedLatest.target;
2169
+ const temporaryLineElement = createLineElement(lineShape, [startPoint, movingPoint], { marker: sourceMarker || LineMarkerType.none, connection: connection, boundId: sourceElement?.id }, { marker: targetMarker || LineMarkerType.arrow, connection: targetConnection, boundId: targetBoundId }, [], {
2170
+ strokeWidth: DefaultLineStyle.strokeWidth,
2171
+ ...memorizedLatest
2228
2172
  });
2229
2173
  const linePoints = getLinePoints(board, temporaryLineElement);
2230
2174
  const otherPoint = linePoints[0];
@@ -2392,6 +2336,7 @@ var MemorizeKey;
2392
2336
  (function (MemorizeKey) {
2393
2337
  MemorizeKey["basicShape"] = "basicShape";
2394
2338
  MemorizeKey["flowchart"] = "flowchart";
2339
+ MemorizeKey["text"] = "text";
2395
2340
  MemorizeKey["line"] = "line";
2396
2341
  })(MemorizeKey || (MemorizeKey = {}));
2397
2342
 
@@ -2419,7 +2364,7 @@ const PlaitDrawElement = {
2419
2364
  isShape: (value) => {
2420
2365
  return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value);
2421
2366
  },
2422
- isBaseShape: (value) => {
2367
+ isBasicShape: (value) => {
2423
2368
  return Object.keys(BasicShapes).includes(value.shape);
2424
2369
  },
2425
2370
  isFlowchart: (value) => {
@@ -2427,7 +2372,144 @@ const PlaitDrawElement = {
2427
2372
  }
2428
2373
  };
2429
2374
 
2430
- class AutoCompleteGenerator extends Generator {
2375
+ const insertGeometry = (board, points, shape) => {
2376
+ let newElement = createGeometryElement(board, shape, points, '', {
2377
+ strokeWidth: DefaultBasicShapeProperty.strokeWidth
2378
+ });
2379
+ Transforms.insertNode(board, newElement, [board.children.length]);
2380
+ clearSelectedElement(board);
2381
+ addSelectedElement(board, newElement);
2382
+ };
2383
+ const insertText = (board, points, text = '文本') => {
2384
+ let newElement = createGeometryElement(board, BasicShapes.text, points, text);
2385
+ Transforms.insertNode(board, newElement, [board.children.length]);
2386
+ clearSelectedElement(board);
2387
+ addSelectedElement(board, newElement);
2388
+ };
2389
+ const resizeGeometry = (board, points, textHeight, path) => {
2390
+ const normalizePoints = normalizeShapePoints(points);
2391
+ const element = PlaitNode.get(board, path);
2392
+ const newHeight = textHeight / board.viewport.zoom;
2393
+ const newProperties = { points: normalizePoints, textHeight: newHeight };
2394
+ if (PlaitDrawElement.isText(element) && element.autoSize) {
2395
+ newProperties.autoSize = false;
2396
+ }
2397
+ Transforms.setNode(board, newProperties, path);
2398
+ };
2399
+ const transformShape = (board, element, shape) => {
2400
+ const path = PlaitBoard.findPath(board, element);
2401
+ Transforms.setNode(board, { shape }, path);
2402
+ };
2403
+
2404
+ const normalizePoints = (board, element, width, textHeight) => {
2405
+ let points = element.points;
2406
+ let autoSize = element.autoSize;
2407
+ const defaultSpace = ShapeDefaultSpace.rectangleAndText;
2408
+ if (autoSize) {
2409
+ const editor = PlaitGeometry.getTextEditor(element);
2410
+ if (AlignEditor.isActive(editor, Alignment.right)) {
2411
+ points = [
2412
+ [points[1][0] - (width + defaultSpace * 2), points[0][1]],
2413
+ [points[1][0], points[0][1] + textHeight]
2414
+ ];
2415
+ }
2416
+ else if (AlignEditor.isActive(editor, Alignment.center)) {
2417
+ const oldWidth = Math.abs(points[0][0] - points[1][0]);
2418
+ const offset = (width - oldWidth) / 2;
2419
+ points = [
2420
+ [points[0][0] - offset - defaultSpace, points[0][1]],
2421
+ [points[1][0] + offset + defaultSpace, points[0][1] + textHeight]
2422
+ ];
2423
+ }
2424
+ else {
2425
+ points = [points[0], [points[0][0] + width + defaultSpace * 2, points[0][1] + textHeight]];
2426
+ }
2427
+ }
2428
+ return { points };
2429
+ };
2430
+ const setText = (board, element, text, width, textHeight) => {
2431
+ const newElement = {
2432
+ text,
2433
+ textHeight,
2434
+ ...normalizePoints(board, element, width, textHeight)
2435
+ };
2436
+ const path = board.children.findIndex(child => child === element);
2437
+ Transforms.setNode(board, newElement, [path]);
2438
+ };
2439
+ const setTextSize = (board, element, textWidth, textHeight) => {
2440
+ if (element.autoSize) {
2441
+ const newElement = {
2442
+ textHeight,
2443
+ ...normalizePoints(board, element, textWidth, textHeight)
2444
+ };
2445
+ const isPointsEqual = Point.isEquals(element.points[0], newElement.points[0]) && Point.isEquals(element.points[1], newElement.points[1]);
2446
+ const isTextHeightEqual = Math.round(textHeight) === Math.round(element.textHeight);
2447
+ if (!isPointsEqual || !isTextHeightEqual) {
2448
+ const path = board.children.findIndex(child => child === element);
2449
+ Transforms.setNode(board, newElement, [path]);
2450
+ }
2451
+ }
2452
+ };
2453
+
2454
+ const insertImage = (board, imageItem, startPoint) => {
2455
+ const { width, height, url } = imageItem;
2456
+ const host = BOARD_TO_HOST.get(board);
2457
+ const viewportWidth = PlaitBoard.getComponent(board).nativeElement.clientWidth;
2458
+ const viewportHeight = PlaitBoard.getComponent(board).nativeElement.clientHeight;
2459
+ const point = transformPoint(board, toPoint(viewportWidth / 2, viewportHeight / 2, host));
2460
+ const points = startPoint
2461
+ ? [startPoint, [startPoint[0] + width, startPoint[1] + height]]
2462
+ : [
2463
+ [point[0] - width / 2, point[1] - height / 2],
2464
+ [point[0] + width / 2, point[1] + height / 2]
2465
+ ];
2466
+ const imageElement = {
2467
+ id: idCreator(),
2468
+ type: 'image',
2469
+ points,
2470
+ url
2471
+ };
2472
+ Transforms.insertNode(board, imageElement, [board.children.length]);
2473
+ Transforms.addSelectionWithTemporaryElements(board, [imageElement]);
2474
+ };
2475
+
2476
+ const resizeLine = (board, options, path) => {
2477
+ Transforms.setNode(board, options, path);
2478
+ };
2479
+ const setLineTexts = (board, element, texts) => {
2480
+ const path = PlaitBoard.findPath(board, element);
2481
+ Transforms.setNode(board, { texts }, path);
2482
+ };
2483
+ const removeLineText = (board, element, index) => {
2484
+ const path = PlaitBoard.findPath(board, element);
2485
+ const texts = element.texts?.length ? [...element.texts] : [];
2486
+ const newTexts = [...texts];
2487
+ newTexts.splice(index, 1);
2488
+ Transforms.setNode(board, { texts: newTexts }, path);
2489
+ };
2490
+ const setLineMark = (board, element, handleKey, marker) => {
2491
+ const path = PlaitBoard.findPath(board, element);
2492
+ let handle = handleKey === LineHandleKey.source ? element.source : element.target;
2493
+ handle = { ...handle, marker };
2494
+ memorizeLatest(MemorizeKey.line, handleKey, marker);
2495
+ Transforms.setNode(board, { [handleKey]: handle }, path);
2496
+ };
2497
+
2498
+ const DrawTransforms = {
2499
+ setText,
2500
+ insertGeometry,
2501
+ resizeGeometry,
2502
+ insertText,
2503
+ setTextSize,
2504
+ resizeLine,
2505
+ setLineTexts,
2506
+ removeLineText,
2507
+ setLineMark,
2508
+ insertImage,
2509
+ transformShape
2510
+ };
2511
+
2512
+ class LineAutoCompleteGenerator extends Generator {
2431
2513
  constructor(board) {
2432
2514
  super(board);
2433
2515
  this.board = board;
@@ -2446,18 +2528,18 @@ class AutoCompleteGenerator extends Generator {
2446
2528
  this.autoCompleteG = createG();
2447
2529
  const middlePoints = getAutoCompletePoints(element);
2448
2530
  middlePoints.forEach((point, index) => {
2449
- const circle = drawCircle(PlaitBoard.getRoughSVG(this.board), point, RESIZE_HANDLE_DIAMETER, {
2531
+ const circle = drawCircle(PlaitBoard.getRoughSVG(this.board), point, LINE_AUTO_COMPLETE_DIAMETER, {
2450
2532
  stroke: 'none',
2451
- fill: '#6698FF4d',
2533
+ fill: RgbaToHEX(PRIMARY_COLOR, LINE_AUTO_COMPLETE_OPACITY),
2452
2534
  fillStyle: 'solid'
2453
2535
  });
2454
- circle.classList.add(`geometry-auto-complete-${index}`);
2536
+ circle.classList.add(`line-auto-complete-${index}`);
2455
2537
  this.autoCompleteG.appendChild(circle);
2456
2538
  });
2457
2539
  return this.autoCompleteG;
2458
2540
  }
2459
2541
  removeAutoCompleteG(index) {
2460
- this.hoverElement = this.autoCompleteG.querySelector(`.geometry-auto-complete-${index}`);
2542
+ this.hoverElement = this.autoCompleteG.querySelector(`.line-auto-complete-${index}`);
2461
2543
  this.hoverElement.style.visibility = 'hidden';
2462
2544
  }
2463
2545
  recoverAutoCompleteG() {
@@ -2509,7 +2591,7 @@ class GeometryComponent extends CommonPluginElement {
2509
2591
  return selectedElements.length === 1 && !isSelectionMoving(this.board);
2510
2592
  }
2511
2593
  });
2512
- this.autoCompleteGenerator = new AutoCompleteGenerator(this.board);
2594
+ this.lineAutoCompleteGenerator = new LineAutoCompleteGenerator(this.board);
2513
2595
  this.shapeGenerator = new GeometryShapeGenerator(this.board);
2514
2596
  this.initializeTextManage();
2515
2597
  }
@@ -2517,30 +2599,36 @@ class GeometryComponent extends CommonPluginElement {
2517
2599
  super.ngOnInit();
2518
2600
  this.initializeGenerator();
2519
2601
  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 });
2602
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2603
+ this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
2604
+ selected: this.selected
2605
+ });
2522
2606
  this.drawText();
2523
2607
  }
2524
2608
  onContextChanged(value, previous) {
2525
2609
  const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
2526
2610
  if (value.element !== previous.element || isChangeTheme) {
2527
2611
  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 });
2612
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2613
+ this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
2614
+ selected: this.selected
2615
+ });
2530
2616
  this.updateText();
2531
2617
  }
2532
2618
  else {
2533
2619
  const hasSameSelected = value.selected === previous.selected;
2534
2620
  const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
2535
2621
  if (!hasSameSelected || !hasSameHandleState) {
2536
- this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2537
- this.autoCompleteGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2622
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2623
+ this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
2624
+ selected: this.selected
2625
+ });
2538
2626
  }
2539
2627
  }
2540
2628
  }
2541
2629
  editText() {
2542
2630
  this.textManage.edit();
2543
- this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2631
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2544
2632
  }
2545
2633
  drawText() {
2546
2634
  this.textManage.draw(this.element.text);
@@ -2551,7 +2639,7 @@ class GeometryComponent extends CommonPluginElement {
2551
2639
  this.textManage.updateRectangle();
2552
2640
  }
2553
2641
  initializeTextManage() {
2554
- const plugins = this.board.getPluginOptions(WithTextPluginKey).textPlugins;
2642
+ const plugins = (this.board.getPluginOptions(WithTextPluginKey) || {}).textPlugins;
2555
2643
  const manage = new TextManage(this.board, this.viewContainerRef, {
2556
2644
  getRectangle: () => {
2557
2645
  const getRectangle = getEngine(this.element.shape).getTextRectangle;
@@ -2569,6 +2657,7 @@ class GeometryComponent extends CommonPluginElement {
2569
2657
  else {
2570
2658
  DrawTransforms.setTextSize(this.board, this.element, width, height);
2571
2659
  }
2660
+ textManageRef.operations && memorizeLatestText(this.element, textManageRef.operations);
2572
2661
  },
2573
2662
  getMaxWidth: () => {
2574
2663
  let width = getTextRectangle(this.element).width;
@@ -2587,6 +2676,8 @@ class GeometryComponent extends CommonPluginElement {
2587
2676
  this.textManage.destroy();
2588
2677
  this.destroy$.next();
2589
2678
  this.destroy$.complete();
2679
+ this.activeGenerator.destroy();
2680
+ this.lineAutoCompleteGenerator.destroy();
2590
2681
  }
2591
2682
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GeometryComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2592
2683
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: GeometryComponent, isStandalone: true, selector: "plait-draw-geometry", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
@@ -2602,10 +2693,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2602
2693
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
2603
2694
 
2604
2695
  class LineActiveGenerator extends Generator {
2605
- constructor() {
2606
- super(...arguments);
2607
- this.hasResizeHandle = false;
2608
- }
2609
2696
  canDraw(element, data) {
2610
2697
  if (data.selected) {
2611
2698
  return true;
@@ -2616,7 +2703,9 @@ class LineActiveGenerator extends Generator {
2616
2703
  }
2617
2704
  draw(element, data) {
2618
2705
  const activeG = createG();
2619
- if (this.hasResizeHandle) {
2706
+ const selectedElements = getSelectedElements(this.board);
2707
+ const isSingleSelection = selectedElements.length === 1;
2708
+ if (isSingleSelection) {
2620
2709
  activeG.classList.add('active');
2621
2710
  activeG.classList.add('line-handle');
2622
2711
  const points = PlaitLine.getPoints(this.board, element);
@@ -2642,10 +2731,15 @@ class LineActiveGenerator extends Generator {
2642
2731
  else {
2643
2732
  const points = getLinePoints(this.board, element);
2644
2733
  const activeRectangle = getRectangleByPoints(points);
2734
+ let opacity = '0.5';
2735
+ if (activeRectangle.height === 0 || activeRectangle.width === 0) {
2736
+ opacity = '0.8';
2737
+ }
2645
2738
  const strokeG = drawRectangle(this.board, activeRectangle, {
2646
2739
  stroke: PRIMARY_COLOR,
2647
2740
  strokeWidth: DefaultGeometryActiveStyle.selectionStrokeWidth
2648
2741
  });
2742
+ strokeG.style.opacity = opacity;
2649
2743
  activeG.appendChild(strokeG);
2650
2744
  }
2651
2745
  return activeG;
@@ -2730,23 +2824,18 @@ class LineComponent extends PlaitPluginElementComponent {
2730
2824
  this.updateText(previous.element.texts, value.element.texts);
2731
2825
  this.updateTextRectangle();
2732
2826
  }
2827
+ else {
2828
+ const hasSameSelected = value.selected === previous.selected;
2829
+ if (!hasSameSelected || (value.selected && isSelectionMoving(this.board))) {
2830
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2831
+ }
2832
+ }
2733
2833
  if (isBoundedElementsChanged) {
2734
2834
  this.shapeGenerator.processDrawing(this.element, this.g);
2735
2835
  this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2736
2836
  this.updateTextRectangle();
2737
2837
  return;
2738
2838
  }
2739
- if (!isSelectionMoving(this.board)) {
2740
- this.activeGenerator.hasResizeHandle = this.hasResizeHandle();
2741
- this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2742
- }
2743
- }
2744
- hasResizeHandle() {
2745
- const selectedElements = getSelectedElements(this.board);
2746
- if (PlaitBoard.hasBeenTextEditing(this.board) && PlaitDrawElement.isText(this.element)) {
2747
- return false;
2748
- }
2749
- return selectedElements.length === 1 && !isSelectionMoving(this.board);
2750
2839
  }
2751
2840
  initializeTextManages() {
2752
2841
  if (this.element.texts?.length) {
@@ -2785,6 +2874,7 @@ class LineComponent extends PlaitPluginElementComponent {
2785
2874
  height
2786
2875
  });
2787
2876
  DrawTransforms.setLineTexts(this.board, this.element, texts);
2877
+ textManageRef.operations && memorizeLatestText(this.element, textManageRef.operations);
2788
2878
  },
2789
2879
  getMaxWidth: () => GeometryThreshold.defaultTextMaxWidth
2790
2880
  });
@@ -2838,7 +2928,8 @@ const withDrawHotkey = (board) => {
2838
2928
  const selectedElements = getSelectedElements(board);
2839
2929
  const isSingleSelection = selectedElements.length === 1;
2840
2930
  const targetElement = selectedElements[0];
2841
- if (!isVirtualKey(event) &&
2931
+ if (!PlaitBoard.isReadonly(board) &&
2932
+ !isVirtualKey(event) &&
2842
2933
  !isDelete(event) &&
2843
2934
  !isSpaceHotkey(event) &&
2844
2935
  isSingleSelection &&
@@ -2852,7 +2943,7 @@ const withDrawHotkey = (board) => {
2852
2943
  board.dblclick = (event) => {
2853
2944
  event.preventDefault();
2854
2945
  const geometries = getSelectedGeometryElements(board);
2855
- if (geometries.length === 1) {
2946
+ if (!PlaitBoard.isReadonly(board) && geometries.length === 1) {
2856
2947
  const component = PlaitElement.getComponent(geometries[0]);
2857
2948
  component.editText();
2858
2949
  }
@@ -2996,7 +3087,7 @@ const withLineCreateByDraw = (board) => {
2996
3087
  board.pointerDown = (event) => {
2997
3088
  const linePointers = getLinePointers();
2998
3089
  const isLinePointer = PlaitBoard.isInPointer(board, linePointers);
2999
- if (isLinePointer && isDrawingMode(board)) {
3090
+ if (!PlaitBoard.isReadonly(board) && isLinePointer && isDrawingMode(board)) {
3000
3091
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3001
3092
  start = point;
3002
3093
  const hitElement = getHitOutlineGeometry(board, point, REACTION_MARGIN);
@@ -3224,7 +3315,7 @@ const withLineResize = (board) => {
3224
3315
  if (points.length === 2) {
3225
3316
  let movingPoint = points[pointIndex];
3226
3317
  const drawPoints = getLinePoints(board, resizeRef.element);
3227
- const index = pointIndex === 0 ? drawPoints.length - 1 : pointIndex;
3318
+ const index = pointIndex === 0 ? drawPoints.length - 1 : 0;
3228
3319
  const otherPoint = drawPoints[index];
3229
3320
  points[pointIndex] = alignPoints(otherPoint, movingPoint);
3230
3321
  }
@@ -3248,6 +3339,10 @@ const withLineBoundReaction = (board) => {
3248
3339
  let boundShapeG = null;
3249
3340
  board.pointerMove = (event) => {
3250
3341
  boundShapeG?.remove();
3342
+ if (PlaitBoard.isReadonly(board)) {
3343
+ pointerMove(event);
3344
+ return;
3345
+ }
3251
3346
  const linePointers = Object.keys(LineShape);
3252
3347
  const isLinePointer = PlaitBoard.isInPointer(board, linePointers);
3253
3348
  const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
@@ -3288,32 +3383,34 @@ const withLineBoundReaction = (board) => {
3288
3383
  const withLineText = (board) => {
3289
3384
  const { dblclick } = board;
3290
3385
  board.dblclick = (event) => {
3291
- const clickPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3292
- const hitTarget = getHitElementByPoint(board, clickPoint, (element) => {
3293
- return PlaitDrawElement.isLine(element);
3294
- });
3295
- if (hitTarget) {
3296
- const points = getLinePoints(board, hitTarget);
3297
- const point = getNearestPointBetweenPointAndSegments(clickPoint, points);
3298
- const texts = hitTarget.texts?.length ? [...hitTarget.texts] : [];
3299
- const textIndex = getHitLineTextIndex(board, hitTarget, clickPoint);
3300
- const isHitText = isHitLineText(board, hitTarget, clickPoint);
3301
- if (isHitText) {
3302
- editHandle(board, hitTarget, textIndex);
3303
- }
3304
- else {
3305
- const ratio = getRatioByPoint(points, point);
3306
- texts.push({
3307
- text: buildText('文本'),
3308
- position: ratio,
3309
- width: 28,
3310
- height: 20
3311
- });
3312
- DrawTransforms.setLineTexts(board, hitTarget, texts);
3313
- setTimeout(() => {
3314
- const hitComponent = PlaitElement.getComponent(hitTarget);
3315
- editHandle(board, hitTarget, hitComponent.textManages.length - 1, true);
3316
- });
3386
+ if (!PlaitBoard.isReadonly(board)) {
3387
+ const clickPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3388
+ const hitTarget = getHitElementByPoint(board, clickPoint, (element) => {
3389
+ return PlaitDrawElement.isLine(element);
3390
+ });
3391
+ if (hitTarget) {
3392
+ const points = getLinePoints(board, hitTarget);
3393
+ const point = getNearestPointBetweenPointAndSegments(clickPoint, points);
3394
+ const texts = hitTarget.texts?.length ? [...hitTarget.texts] : [];
3395
+ const textIndex = getHitLineTextIndex(board, hitTarget, clickPoint);
3396
+ const isHitText = isHitLineText(board, hitTarget, clickPoint);
3397
+ if (isHitText) {
3398
+ editHandle(board, hitTarget, textIndex);
3399
+ }
3400
+ else {
3401
+ const ratio = getRatioByPoint(points, point);
3402
+ texts.push({
3403
+ text: buildText('文本'),
3404
+ position: ratio,
3405
+ width: 28,
3406
+ height: 20
3407
+ });
3408
+ DrawTransforms.setLineTexts(board, hitTarget, texts);
3409
+ setTimeout(() => {
3410
+ const hitComponent = PlaitElement.getComponent(hitTarget);
3411
+ editHandle(board, hitTarget, hitComponent.textManages.length - 1, true);
3412
+ });
3413
+ }
3317
3414
  }
3318
3415
  }
3319
3416
  dblclick(event);
@@ -3361,22 +3458,32 @@ class ImageComponent extends CommonPluginElement {
3361
3458
  };
3362
3459
  }
3363
3460
  });
3461
+ this.lineAutoCompleteGenerator = new LineAutoCompleteGenerator(this.board);
3364
3462
  }
3365
3463
  ngOnInit() {
3366
3464
  super.ngOnInit();
3367
3465
  this.initializeGenerator();
3368
3466
  this.imageGenerator.processDrawing(this.element, this.g, this.viewContainerRef);
3467
+ this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
3468
+ selected: this.selected
3469
+ });
3369
3470
  }
3370
3471
  onContextChanged(value, previous) {
3371
3472
  if (value.element !== previous.element) {
3372
3473
  this.imageGenerator.updateImage(this.g, previous.element, value.element);
3373
3474
  this.imageGenerator.componentRef.instance.isFocus = this.selected;
3475
+ this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
3476
+ selected: this.selected
3477
+ });
3374
3478
  }
3375
3479
  else {
3376
3480
  const hasSameSelected = value.selected === previous.selected;
3377
3481
  const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
3378
3482
  if (!hasSameSelected || !hasSameHandleState) {
3379
3483
  this.imageGenerator.componentRef.instance.isFocus = this.selected;
3484
+ this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
3485
+ selected: this.selected
3486
+ });
3380
3487
  }
3381
3488
  }
3382
3489
  }
@@ -3385,6 +3492,7 @@ class ImageComponent extends CommonPluginElement {
3385
3492
  this.destroy$.next();
3386
3493
  this.destroy$.complete();
3387
3494
  this.imageGenerator.destroy();
3495
+ this.lineAutoCompleteGenerator.destroy();
3388
3496
  }
3389
3497
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ImageComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3390
3498
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ImageComponent, isStandalone: true, selector: "plait-draw-geometry", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
@@ -3399,31 +3507,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3399
3507
  }]
3400
3508
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
3401
3509
 
3402
- const withAutoCompleteReaction = (board) => {
3510
+ const withLineAutoCompleteReaction = (board) => {
3403
3511
  const { pointerMove } = board;
3404
3512
  let reactionG = null;
3405
3513
  board.pointerMove = (event) => {
3406
3514
  reactionG?.remove();
3407
- if (isSelectionMoving(board)) {
3408
- pointerMove(event);
3409
- return;
3410
- }
3515
+ PlaitBoard.getBoardContainer(board).classList.remove(CursorClass.crosshair);
3411
3516
  const selectedElements = getSelectedDrawElements(board);
3517
+ const targetElement = selectedElements.length === 1 && selectedElements[0];
3412
3518
  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]);
3519
+ if (!PlaitBoard.isReadonly(board) && !isSelectionMoving(board) && targetElement && PlaitDrawElement.isShape(targetElement)) {
3520
+ const points = getAutoCompletePoints(targetElement);
3415
3521
  const hitIndex = getHitIndexOfAutoCompletePoint(movingPoint, points);
3416
3522
  const hitPoint = points[hitIndex];
3417
- const component = PlaitElement.getComponent(selectedElements[0]);
3418
- component.autoCompleteGenerator.recoverAutoCompleteG();
3523
+ const component = PlaitElement.getComponent(targetElement);
3524
+ component.lineAutoCompleteGenerator.recoverAutoCompleteG();
3419
3525
  if (hitPoint) {
3420
- component.autoCompleteGenerator.removeAutoCompleteG(hitIndex);
3421
- reactionG = drawCircle(PlaitBoard.getRoughSVG(board), hitPoint, 10, {
3526
+ component.lineAutoCompleteGenerator.removeAutoCompleteG(hitIndex);
3527
+ reactionG = drawCircle(PlaitBoard.getRoughSVG(board), hitPoint, LINE_AUTO_COMPLETE_HOVERED_DIAMETER, {
3422
3528
  stroke: 'none',
3423
- fill: '#6698FF80',
3529
+ fill: RgbaToHEX(PRIMARY_COLOR, LINE_AUTO_COMPLETE_HOVERED_OPACITY),
3424
3530
  fillStyle: 'solid'
3425
3531
  });
3426
3532
  PlaitBoard.getElementActiveHost(board).append(reactionG);
3533
+ PlaitBoard.getBoardContainer(board).classList.add(CursorClass.crosshair);
3427
3534
  }
3428
3535
  }
3429
3536
  pointerMove(event);
@@ -3431,25 +3538,25 @@ const withAutoCompleteReaction = (board) => {
3431
3538
  return board;
3432
3539
  };
3433
3540
 
3434
- const withAutoCompletePluginKey = 'plait-auto-complete-plugin-key';
3435
- const withAutoComplete = (board) => {
3541
+ const withLineAutoCompletePluginKey = 'plait-line-auto-complete-plugin-key';
3542
+ const withLineAutoComplete = (board) => {
3436
3543
  const { pointerDown, pointerMove, pointerUp } = board;
3437
- const tolerance = 3;
3438
3544
  let startPoint = null;
3439
3545
  let lineShapeG = null;
3440
3546
  let sourceElement;
3441
3547
  let temporaryElement;
3442
3548
  board.pointerDown = (event) => {
3443
3549
  const selectedElements = getSelectedDrawElements(board);
3550
+ const targetElement = selectedElements.length === 1 && selectedElements[0];
3444
3551
  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]);
3552
+ if (!PlaitBoard.isReadonly(board) && targetElement && PlaitDrawElement.isShape(targetElement)) {
3553
+ const points = getAutoCompletePoints(targetElement);
3447
3554
  const index = getHitIndexOfAutoCompletePoint(clickPoint, points);
3448
3555
  const hitPoint = points[index];
3449
3556
  if (hitPoint) {
3450
3557
  temporaryDisableSelection(board);
3451
3558
  startPoint = clickPoint;
3452
- sourceElement = selectedElements[0];
3559
+ sourceElement = targetElement;
3453
3560
  BoardTransforms.updatePointerType(board, LineShape.elbow);
3454
3561
  }
3455
3562
  }
@@ -3461,7 +3568,7 @@ const withAutoComplete = (board) => {
3461
3568
  let movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3462
3569
  if (startPoint && sourceElement) {
3463
3570
  const distance = distanceBetweenPointAndPoint(...movingPoint, ...startPoint);
3464
- if (distance > tolerance) {
3571
+ if (distance > PRESS_AND_MOVE_BUFFER) {
3465
3572
  temporaryElement = handleLineCreating(board, LineShape.elbow, startPoint, movingPoint, sourceElement, lineShapeG);
3466
3573
  }
3467
3574
  }
@@ -3472,7 +3579,7 @@ const withAutoComplete = (board) => {
3472
3579
  Transforms.insertNode(board, temporaryElement, [board.children.length]);
3473
3580
  clearSelectedElement(board);
3474
3581
  addSelectedElement(board, temporaryElement);
3475
- const afterComplete = board.getPluginOptions(withAutoCompletePluginKey)
3582
+ const afterComplete = board.getPluginOptions(withLineAutoCompletePluginKey)
3476
3583
  ?.afterComplete;
3477
3584
  afterComplete && afterComplete(temporaryElement);
3478
3585
  }
@@ -3558,12 +3665,12 @@ const withDraw = (board) => {
3558
3665
  }
3559
3666
  return isAlign(element);
3560
3667
  };
3561
- return withAutoCompleteReaction(withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))))));
3668
+ return withLineAutoCompleteReaction(withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withLineAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))))));
3562
3669
  };
3563
3670
 
3564
3671
  /**
3565
3672
  * Generated bundle index. Do not edit.
3566
3673
  */
3567
3674
 
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 };
3675
+ 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, 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, isHitDrawElement, isHitLineText, isHitPolyLine, isRectangleHitDrawElement, isTextExceedingBounds, memorizeLatestShape, memorizeLatestText, transformOpsToPoints, transformPointToConnection, withDraw };
3569
3676
  //# sourceMappingURL=plait-draw.mjs.map