@plait/draw 0.1.0-next.6 → 0.1.0-next.8

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 (41) hide show
  1. package/esm2022/constants/geometry.mjs +4 -3
  2. package/esm2022/generators/geometry-shape.generator.mjs +23 -0
  3. package/esm2022/generators/line-active.generator.mjs +36 -0
  4. package/esm2022/generators/line.generator.mjs +22 -0
  5. package/esm2022/geometry.component.mjs +13 -11
  6. package/esm2022/interfaces/geometry.mjs +5 -2
  7. package/esm2022/interfaces/line.mjs +9 -1
  8. package/esm2022/line.component.mjs +3 -3
  9. package/esm2022/plugins/with-draw-fragment.mjs +5 -10
  10. package/esm2022/plugins/with-draw-hotkey.mjs +7 -3
  11. package/esm2022/plugins/with-draw.mjs +3 -3
  12. package/esm2022/plugins/with-geometry-create.mjs +5 -6
  13. package/esm2022/plugins/with-geometry-resize.mjs +5 -5
  14. package/esm2022/plugins/with-line-bound-reaction.mjs +5 -7
  15. package/esm2022/plugins/with-line-create.mjs +4 -4
  16. package/esm2022/plugins/with-line-text.mjs +3 -3
  17. package/esm2022/public-api.mjs +2 -1
  18. package/esm2022/transforms/index.mjs +4 -3
  19. package/esm2022/transforms/line.mjs +8 -1
  20. package/esm2022/utils/geometry.mjs +8 -8
  21. package/esm2022/utils/line-arrow.mjs +89 -0
  22. package/esm2022/utils/line.mjs +51 -46
  23. package/fesm2022/plait-draw.mjs +196 -109
  24. package/fesm2022/plait-draw.mjs.map +1 -1
  25. package/geometry.component.d.ts +5 -5
  26. package/interfaces/geometry.d.ts +1 -0
  27. package/interfaces/line.d.ts +8 -1
  28. package/line.component.d.ts +2 -2
  29. package/package.json +1 -1
  30. package/public-api.d.ts +1 -0
  31. package/transforms/index.d.ts +1 -0
  32. package/transforms/line.d.ts +2 -1
  33. package/utils/geometry.d.ts +1 -1
  34. package/utils/line-arrow.d.ts +4 -0
  35. package/utils/line.d.ts +3 -3
  36. package/esm2022/generator/geometry-shape.generator.mjs +0 -22
  37. package/esm2022/generator/line-active.generator.mjs +0 -36
  38. package/esm2022/generator/line.generator.mjs +0 -43
  39. /package/{generator → generators}/geometry-shape.generator.d.ts +0 -0
  40. /package/{generator → generators}/line-active.generator.d.ts +0 -0
  41. /package/{generator → generators}/line.generator.d.ts +0 -0
@@ -1,8 +1,8 @@
1
- import { PlaitElement, RectangleClient, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, idCreator, createG, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegments, setPathStrokeLinecap, arrowPoints, drawLinearPath, getElementById, findElements, getSelectedElements, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Point, PlaitPluginElementComponent, isSelectionMoving, createMask, createRect, transformPoint, toPoint, BoardTransforms, PlaitPointerType, preventTouchMove, createForeignObject, setClipboardData, getDataFromClipboard, depthFirstRecursion, getIsRecursionFunc, getHitElements, isPolylineHitRectangle } from '@plait/core';
1
+ import { PlaitElement, ACTIVE_STROKE_WIDTH, RectangleClient, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, idCreator, createG, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, arrowPoints, createPath, drawLinearPath, distanceBetweenPointAndSegments, createMask, createRect, getElementById, findElements, getSelectedElements, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Point, isSelectionMoving, PlaitPluginElementComponent, transformPoint, toPoint, BoardTransforms, PlaitPointerType, preventTouchMove, createForeignObject, setClipboardData, getDataFromClipboard, depthFirstRecursion, getIsRecursionFunc, getHitElements, isPolylineHitRectangle } from '@plait/core';
2
2
  import * as i0 from '@angular/core';
3
3
  import { Component, ChangeDetectionStrategy } from '@angular/core';
4
4
  import { Subject } from 'rxjs';
5
- import { getRectangleByPoints, Direction, getDirectionByPoint, getPoints, getPointOnPolyline, getDirectionBetweenPointAndPoint, getDirectionFactor, Generator, normalizeShapePoints, ActiveGenerator, RESIZE_HANDLE_DIAMETER, isVirtualKey, isSpaceHotkey, isDndMode, isDrawingMode, CommonTransforms, getRectangleResizeHandleRefs, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint } from '@plait/common';
5
+ import { getRectangleByPoints, getFactorByPoints, Direction, getDirectionByPoint, getPoints, getPointOnPolyline, getDirectionFactor, Generator, normalizeShapePoints, CommonPluginElement, ActiveGenerator, WithTextPluginKey, RESIZE_HANDLE_DIAMETER, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, getRectangleResizeHandleRefs, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint } from '@plait/common';
6
6
  import { Alignment, buildText, AlignEditor, TextManage, DEFAULT_FONT_SIZE, getTextFromClipboard, getTextSize } from '@plait/text';
7
7
  import { isKeyHotkey } from 'is-hotkey';
8
8
  import { Node } from 'slate';
@@ -18,9 +18,12 @@ var GeometryShape;
18
18
  })(GeometryShape || (GeometryShape = {}));
19
19
  const PlaitGeometry = {
20
20
  getTextEditor(element) {
21
+ return PlaitGeometry.getTextManage(element).componentRef.instance.editor;
22
+ },
23
+ getTextManage(element) {
21
24
  const component = PlaitElement.getComponent(element);
22
25
  if (component) {
23
- return component.textManage.componentRef.instance.editor;
26
+ return component.textManage;
24
27
  }
25
28
  throw new Error('can not get correctly component in get text editor');
26
29
  }
@@ -30,6 +33,9 @@ var LineMarkerType;
30
33
  (function (LineMarkerType) {
31
34
  LineMarkerType["arrow"] = "arrow";
32
35
  LineMarkerType["none"] = "none";
36
+ LineMarkerType["openTriangle"] = "open-triangle";
37
+ LineMarkerType["solidTriangle"] = "solid-triangle";
38
+ LineMarkerType["sharpArrow"] = "sharp-arrow";
33
39
  })(LineMarkerType || (LineMarkerType = {}));
34
40
  var LineShape;
35
41
  (function (LineShape) {
@@ -37,6 +43,11 @@ var LineShape;
37
43
  LineShape["curve"] = "curve";
38
44
  LineShape["elbow"] = "elbow";
39
45
  })(LineShape || (LineShape = {}));
46
+ var LineHandleKey;
47
+ (function (LineHandleKey) {
48
+ LineHandleKey["source"] = "source";
49
+ LineHandleKey["target"] = "target";
50
+ })(LineHandleKey || (LineHandleKey = {}));
40
51
  const PlaitLine = {
41
52
  getTextEditors(element) {
42
53
  const component = PlaitElement.getComponent(element);
@@ -101,8 +112,8 @@ const DefaultGeometryStyle = {
101
112
  fill: 'none'
102
113
  };
103
114
  const DefaultGeometryActiveStyle = {
104
- strokeWidth: 2,
105
- selectionStrokeWidth: 1
115
+ strokeWidth: ACTIVE_STROKE_WIDTH,
116
+ selectionStrokeWidth: ACTIVE_STROKE_WIDTH
106
117
  };
107
118
  const DefaultGeometryProperty = {
108
119
  width: 100,
@@ -365,20 +376,20 @@ const getPointsByCenterPoint = (point, width, height) => {
365
376
  };
366
377
  const getTextRectangle = (element) => {
367
378
  const elementRectangle = getRectangleByPoints(element.points);
379
+ const strokeWidth = getStrokeWidthByElement(element);
368
380
  const height = element.textHeight;
369
- const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2;
381
+ const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
370
382
  return {
371
383
  height,
372
384
  width: width > 0 ? width : 0,
373
- x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText,
385
+ x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
374
386
  y: elementRectangle.y + (elementRectangle.height - height) / 2
375
387
  };
376
388
  };
377
389
  const drawBoundMask = (board, element) => {
378
390
  const G = createG();
379
391
  const rectangle = getRectangleByPoints(element.points);
380
- const offset = (getStrokeWidthByElement(element) + 1) / 2 - 0.1;
381
- const activeRectangle = RectangleClient.getOutlineRectangle(rectangle, -offset);
392
+ const activeRectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
382
393
  const maskG = drawGeometry(board, activeRectangle, element.shape, {
383
394
  stroke: SELECTION_BORDER_COLOR,
384
395
  strokeWidth: 1,
@@ -401,9 +412,9 @@ const drawBoundMask = (board, element) => {
401
412
  const drawGeometry = (board, outerRectangle, shape, options) => {
402
413
  return getEngine(shape).draw(board, outerRectangle, options);
403
414
  };
404
- const getNearestPoint = (element, point, offset = 0) => {
415
+ const getNearestPoint = (element, point, inflateDelta = 0) => {
405
416
  const rectangle = getRectangleByPoints(element.points);
406
- const activeRectangle = RectangleClient.getOutlineRectangle(rectangle, -offset);
417
+ const activeRectangle = RectangleClient.inflate(rectangle, inflateDelta);
407
418
  return getEngine(element.shape).getNearestPoint(activeRectangle, point);
408
419
  };
409
420
  const getCenterPointsOnPolygon = (points) => {
@@ -415,7 +426,91 @@ const getCenterPointsOnPolygon = (points) => {
415
426
  return centerPoint;
416
427
  };
417
428
 
418
- const BOUNDED_HANDLE_OFFSET = 0.5;
429
+ const drawLineArrow = (element, points, options) => {
430
+ const arrowG = createG();
431
+ if (PlaitLine.isSourceMark(element, LineMarkerType.none) && PlaitLine.isTargetMark(element, LineMarkerType.none)) {
432
+ return null;
433
+ }
434
+ if (!PlaitLine.isSourceMark(element, LineMarkerType.none)) {
435
+ const sourceArrow = getArrow(element, element.source.marker, points[1], points[0], options);
436
+ sourceArrow && arrowG.appendChild(sourceArrow);
437
+ }
438
+ if (!PlaitLine.isTargetMark(element, LineMarkerType.none)) {
439
+ const arrow = getArrow(element, element.target.marker, points[points.length - 2], points[points.length - 1], options);
440
+ arrow && arrowG.appendChild(arrow);
441
+ }
442
+ return arrowG;
443
+ };
444
+ const getArrow = (element, marker, source, target, options) => {
445
+ let targetArrow;
446
+ switch (marker) {
447
+ case LineMarkerType.openTriangle: {
448
+ targetArrow = drawOpenTriangle(element, source, target, options);
449
+ break;
450
+ }
451
+ case LineMarkerType.solidTriangle: {
452
+ targetArrow = drawSolidTriangle(source, target, options);
453
+ break;
454
+ }
455
+ case LineMarkerType.arrow: {
456
+ targetArrow = drawArrow(element, source, target, options);
457
+ break;
458
+ }
459
+ case LineMarkerType.sharpArrow: {
460
+ targetArrow = drawSharpArrow(source, target, options);
461
+ break;
462
+ }
463
+ }
464
+ return targetArrow;
465
+ };
466
+ const drawSharpArrow = (source, target, options) => {
467
+ const directionFactor = getFactorByPoints(source, target);
468
+ const startPoint = target;
469
+ // const startPoint: Point = [
470
+ // target[0],
471
+ // target[1]
472
+ // ];
473
+ const { pointLeft, pointRight } = arrowPoints(source, target, 12, 20);
474
+ const g = createG();
475
+ const path = createPath();
476
+ let polylinePath = `M${pointRight[0]},${pointRight[1]}A8,8,20,0,1,${pointLeft[0]},${pointLeft[1]}L${startPoint[0]},${startPoint[1]}Z`;
477
+ path.setAttribute('d', polylinePath);
478
+ path.setAttribute('stroke', `${options?.stroke}`);
479
+ path.setAttribute('stroke-width', `${options?.strokeWidth}`);
480
+ path.setAttribute('fill', `${options?.stroke}`);
481
+ g.appendChild(path);
482
+ return g;
483
+ };
484
+ const drawArrow = (element, source, target, options) => {
485
+ const directionFactor = getFactorByPoints(source, target);
486
+ const strokeWidth = getStrokeWidthByElement(element);
487
+ const endPoint = [
488
+ target[0] + strokeWidth * directionFactor.x / 2,
489
+ target[1] + strokeWidth * directionFactor.y / 2
490
+ ];
491
+ const middlePoint = [endPoint[0] - 8 * directionFactor.x, endPoint[1] - 8 * directionFactor.y];
492
+ const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 30);
493
+ const arrowG = drawLinearPath([pointLeft, endPoint, pointRight, middlePoint], { ...options, fill: options.stroke }, true);
494
+ const path = arrowG.querySelector('path');
495
+ path.setAttribute('stroke-linejoin', 'round');
496
+ return arrowG;
497
+ };
498
+ const drawSolidTriangle = (source, target, options) => {
499
+ const endPoint = target;
500
+ const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 30);
501
+ return drawLinearPath([pointLeft, endPoint, pointRight], { ...options, fill: options.stroke }, true);
502
+ };
503
+ const drawOpenTriangle = (element, source, target, options) => {
504
+ const directionFactor = getFactorByPoints(source, target);
505
+ const strokeWidth = getStrokeWidthByElement(element);
506
+ const endPoint = [
507
+ target[0] + strokeWidth * directionFactor.x / 2,
508
+ target[1] + strokeWidth * directionFactor.y / 2
509
+ ];
510
+ const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 40);
511
+ return drawLinearPath([pointLeft, endPoint, pointRight], options);
512
+ };
513
+
419
514
  const createLineElement = (shape, points, source, target, options) => {
420
515
  return {
421
516
  id: idCreator(),
@@ -429,6 +524,12 @@ const createLineElement = (shape, points, source, target, options) => {
429
524
  ...options
430
525
  };
431
526
  };
527
+ const getLinePoints = (board, element) => {
528
+ return element.shape === LineShape.elbow ? getElbowPoints(board, element) : getStraightPoints(board, element);
529
+ };
530
+ const getStraightPoints = (board, element) => {
531
+ return [getSourcePoint(board, element), getTargetPoint(board, element)];
532
+ };
432
533
  const getElbowPoints = (board, element) => {
433
534
  if (element.points.length === 2) {
434
535
  const source = getSourcePoint(board, element);
@@ -469,50 +570,50 @@ const getHitLineTextIndex = (board, element, point) => {
469
570
  const isHitLineText = (board, element, point) => {
470
571
  return getHitLineTextIndex(board, element, point) !== -1;
471
572
  };
472
- const drawElbowLine = (board, element) => {
573
+ const drawLine = (board, element) => {
473
574
  const strokeWidth = getStrokeWidthByElement(element);
474
575
  const strokeColor = getStrokeColorByElement(element);
475
576
  const strokeLineDash = getLineDashByElement(element);
476
577
  const options = { stroke: strokeColor, strokeWidth, strokeLineDash };
477
578
  const lineG = createG();
478
- const points = getElbowPoints(board, element);
479
- const elbowLine = PlaitBoard.getRoughSVG(board).linearPath(points, options);
480
- const path = elbowLine.querySelector('path');
481
- path?.setAttribute('mask', `url(#${element.id})`);
482
- setPathStrokeLinecap(elbowLine, 'square');
483
- lineG.appendChild(elbowLine);
579
+ const points = getLinePoints(board, element);
580
+ const line = drawLinearPath(points, options);
581
+ line.setAttribute('mask', `url(#${element.id})`);
582
+ lineG.appendChild(line);
583
+ const { mask, maskTargetFillRect } = drawMask(board, element);
584
+ lineG.appendChild(mask);
585
+ line.appendChild(maskTargetFillRect);
484
586
  const arrow = drawLineArrow(element, points, options);
485
587
  arrow && lineG.appendChild(arrow);
486
588
  return lineG;
487
589
  };
488
- const drawLineArrow = (element, points, options) => {
489
- const arrowG = createG();
490
- if (PlaitLine.isSourceMark(element, LineMarkerType.none) && PlaitLine.isTargetMark(element, LineMarkerType.none)) {
491
- return null;
492
- }
493
- if (PlaitLine.isSourceMark(element, LineMarkerType.arrow)) {
494
- const sourcePoint = points[0];
495
- const { pointLeft, pointRight } = arrowPoints(points[1], sourcePoint, 12, 40);
496
- const sourceArrow = drawLinearPath([pointLeft, sourcePoint, pointRight], options);
497
- arrowG.appendChild(sourceArrow);
498
- }
499
- if (PlaitLine.isTargetMark(element, LineMarkerType.arrow)) {
500
- const _endPoint = points[points.length - 1];
501
- const arrowDirection = getDirectionBetweenPointAndPoint(points[points.length - 2], _endPoint);
502
- const directionFactor = getDirectionFactor(arrowDirection);
503
- const endPoint = [
504
- _endPoint[0] + BOUNDED_HANDLE_OFFSET * directionFactor.x,
505
- _endPoint[1] + BOUNDED_HANDLE_OFFSET * directionFactor.y
506
- ];
507
- const { pointLeft, pointRight } = arrowPoints(points[points.length - 2], endPoint, 12, 40);
508
- const targetArrow = drawLinearPath([pointLeft, endPoint, pointRight], options);
509
- arrowG.appendChild(targetArrow);
510
- }
511
- return arrowG;
512
- };
590
+ function drawMask(board, element) {
591
+ const mask = createMask();
592
+ mask.setAttribute('id', element.id);
593
+ const points = getLinePoints(board, element);
594
+ let rectangle = getRectangleByPoints(points);
595
+ rectangle = RectangleClient.getOutlineRectangle(rectangle, -30);
596
+ const maskFillRect = createRect(rectangle, {
597
+ fill: 'white'
598
+ });
599
+ mask.appendChild(maskFillRect);
600
+ const texts = element.texts;
601
+ texts.forEach((text, index) => {
602
+ const textRectangle = getLineTextRectangle(board, element, index);
603
+ const rect = createRect(textRectangle, {
604
+ fill: 'black'
605
+ });
606
+ mask.appendChild(rect);
607
+ });
608
+ //撑开 line
609
+ const maskTargetFillRect = createRect(rectangle);
610
+ maskTargetFillRect.setAttribute('opacity', '0');
611
+ return { mask, maskTargetFillRect };
612
+ }
513
613
  const getSourcePoint = (board, element) => {
514
614
  if (element.source.boundId) {
515
- const connectionOffset = PlaitLine.isSourceMark(element, LineMarkerType.arrow) ? BOUNDED_HANDLE_OFFSET : 0;
615
+ const strokeWidth = getStrokeWidthByElement(element);
616
+ const connectionOffset = PlaitLine.isSourceMark(element, LineMarkerType.none) ? 0 : strokeWidth;
516
617
  const boundElement = getElementById(board, element.source.boundId);
517
618
  return boundElement ? getConnectionPoint(boundElement, element.source.connection, connectionOffset) : element.points[0];
518
619
  }
@@ -520,7 +621,8 @@ const getSourcePoint = (board, element) => {
520
621
  };
521
622
  const getTargetPoint = (board, element) => {
522
623
  if (element.target.boundId) {
523
- const connectionOffset = PlaitLine.isTargetMark(element, LineMarkerType.arrow) ? BOUNDED_HANDLE_OFFSET : 0;
624
+ const strokeWidth = getStrokeWidthByElement(element);
625
+ const connectionOffset = PlaitLine.isTargetMark(element, LineMarkerType.none) ? 0 : strokeWidth;
524
626
  const boundElement = getElementById(board, element.target.boundId);
525
627
  return boundElement
526
628
  ? getConnectionPoint(boundElement, element.target.connection, connectionOffset)
@@ -530,18 +632,16 @@ const getTargetPoint = (board, element) => {
530
632
  };
531
633
  const getConnectionPoint = (geometry, connection, offset) => {
532
634
  const rectangle = getRectangleByPoints(geometry.points);
533
- const strokeWidth = getStrokeWidthByElement(geometry);
534
635
  const directionFactor = getDirectionFactor(getDirectionByPoint(connection, Direction.bottom));
535
636
  return [
536
- rectangle.x + rectangle.width * connection[0] + strokeWidth * directionFactor.x + offset * directionFactor.x,
537
- rectangle.y + rectangle.height * connection[1] + strokeWidth * directionFactor.y + offset * directionFactor.y
637
+ rectangle.x + rectangle.width * connection[0] + directionFactor.x * offset,
638
+ rectangle.y + rectangle.height * connection[1] + directionFactor.y * offset
538
639
  ];
539
640
  };
540
641
  const transformPointToConnection = (board, point, hitElement) => {
541
- const offset = (getStrokeWidthByElement(hitElement) + 1) / 2;
542
642
  let rectangle = getRectangleByPoints(hitElement.points);
543
- rectangle = RectangleClient.getOutlineRectangle(rectangle, -offset);
544
- let nearestPoint = getNearestPoint(hitElement, point, offset);
643
+ rectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
644
+ let nearestPoint = getNearestPoint(hitElement, point, ACTIVE_STROKE_WIDTH);
545
645
  const hitConnector = getHitConnectorPoint(nearestPoint, hitElement, rectangle);
546
646
  nearestPoint = hitConnector ? hitConnector : nearestPoint;
547
647
  return [(nearestPoint[0] - rectangle.x) / rectangle.width, (nearestPoint[1] - rectangle.y) / rectangle.height];
@@ -556,7 +656,7 @@ const getHitConnectorPoint = (movingPoint, hitElement, rectangle) => {
556
656
  };
557
657
  const getLineTextRectangle = (board, element, index) => {
558
658
  const text = element.texts[index];
559
- const elbowPoints = getElbowPoints(board, element);
659
+ const elbowPoints = getLinePoints(board, element);
560
660
  const point = getPointOnPolyline(elbowPoints, text.position);
561
661
  return {
562
662
  x: point[0] - text.width / 2,
@@ -590,7 +690,7 @@ class GeometryShapeGenerator extends Generator {
590
690
  return true;
591
691
  }
592
692
  baseDraw(element, data) {
593
- const outerRectangle = getRectangleByPoints(element.points);
693
+ const rectangle = getRectangleByPoints(element.points);
594
694
  const shape = element.shape;
595
695
  if (shape === GeometryShape.text) {
596
696
  return;
@@ -599,7 +699,7 @@ class GeometryShapeGenerator extends Generator {
599
699
  const strokeColor = getStrokeColorByElement(element);
600
700
  const fill = getFillByElement(element);
601
701
  const strokeLineDash = getLineDashByElement(element);
602
- return drawGeometry(this.board, outerRectangle, shape, { stroke: strokeColor, strokeWidth, fill, strokeLineDash });
702
+ return drawGeometry(this.board, RectangleClient.inflate(rectangle, -strokeWidth), shape, { stroke: strokeColor, strokeWidth, fill, strokeLineDash });
603
703
  }
604
704
  }
605
705
 
@@ -693,6 +793,12 @@ const removeLineText = (board, element, index) => {
693
793
  newTexts.splice(index, 1);
694
794
  Transforms.setNode(board, { texts: newTexts }, path);
695
795
  };
796
+ const setLineMark = (board, element, handleKey, marker) => {
797
+ const path = PlaitBoard.findPath(board, element);
798
+ let handle = handleKey === LineHandleKey.source ? element.source : element.target;
799
+ handle = { ...handle, marker };
800
+ Transforms.setNode(board, { [handleKey]: handle }, path);
801
+ };
696
802
 
697
803
  const DrawTransforms = {
698
804
  setText,
@@ -702,10 +808,14 @@ const DrawTransforms = {
702
808
  setTextSize,
703
809
  resizeLine,
704
810
  setLineTexts,
705
- removeLineText
811
+ removeLineText,
812
+ setLineMark
706
813
  };
707
814
 
708
- class GeometryComponent extends PlaitPluginElementComponent {
815
+ class GeometryComponent extends CommonPluginElement {
816
+ get textManage() {
817
+ return this.getTextManages()[0];
818
+ }
709
819
  constructor(viewContainerRef, cdr) {
710
820
  super(cdr);
711
821
  this.viewContainerRef = viewContainerRef;
@@ -726,9 +836,6 @@ class GeometryComponent extends PlaitPluginElementComponent {
726
836
  getRectangle: (element) => {
727
837
  return getRectangleByPoints(element.points);
728
838
  },
729
- getStrokeWidthByElement: (element) => {
730
- return getStrokeWidthByElement(element);
731
- },
732
839
  hasResizeHandle: () => {
733
840
  const selectedElements = getSelectedElements(this.board);
734
841
  if (PlaitBoard.hasBeenTextEditing(this.board) && PlaitDrawElement.isText(this.element)) {
@@ -774,7 +881,8 @@ class GeometryComponent extends PlaitPluginElementComponent {
774
881
  this.textManage.updateRectangle();
775
882
  }
776
883
  initializeTextManage() {
777
- this.textManage = new TextManage(this.board, this.viewContainerRef, {
884
+ const plugins = this.board.getPluginOptions(WithTextPluginKey).textPlugins;
885
+ const manage = new TextManage(this.board, this.viewContainerRef, {
778
886
  getRectangle: () => {
779
887
  return getTextRectangle(this.element);
780
888
  },
@@ -791,8 +899,10 @@ class GeometryComponent extends PlaitPluginElementComponent {
791
899
  getMaxWidth: () => {
792
900
  const width = getTextRectangle(this.element).width;
793
901
  return this.element?.autoSize ? GeometryThreshold.defaultTextMaxWidth : width;
794
- }
902
+ },
903
+ textPlugins: plugins
795
904
  });
905
+ this.initializeTextManages([manage]);
796
906
  }
797
907
  ngOnDestroy() {
798
908
  super.ngOnDestroy();
@@ -821,8 +931,8 @@ class LineShapeGenerator extends Generator {
821
931
  let lineG;
822
932
  switch (shape) {
823
933
  case LineShape.elbow:
824
- lineG = drawElbowLine(this.board, element);
825
- drawMask(this.board, lineG, element);
934
+ case LineShape.straight:
935
+ lineG = drawLine(this.board, element);
826
936
  break;
827
937
  default:
828
938
  break;
@@ -830,26 +940,6 @@ class LineShapeGenerator extends Generator {
830
940
  return lineG;
831
941
  }
832
942
  }
833
- function drawMask(board, g, element) {
834
- const mask = createMask();
835
- mask.setAttribute('id', element.id);
836
- const points = getElbowPoints(board, element);
837
- let rectangle = getRectangleByPoints(points);
838
- rectangle = RectangleClient.getOutlineRectangle(rectangle, -3);
839
- const maskRect = createRect(rectangle, {
840
- fill: 'white'
841
- });
842
- mask.appendChild(maskRect);
843
- const texts = element.texts;
844
- texts.forEach((text, index) => {
845
- const textRectangle = getLineTextRectangle(board, element, index);
846
- const rect = createRect(textRectangle, {
847
- fill: 'black'
848
- });
849
- mask.appendChild(rect);
850
- });
851
- g.appendChild(mask);
852
- }
853
943
 
854
944
  class LineActiveGenerator extends Generator {
855
945
  canDraw(element, data) {
@@ -1032,7 +1122,11 @@ const withDrawHotkey = (board) => {
1032
1122
  const selectedElements = getSelectedElements(board);
1033
1123
  const isSingleSelection = selectedElements.length === 1;
1034
1124
  const targetElement = selectedElements[0];
1035
- if (!isVirtualKey(event) && !isSpaceHotkey(event) && isSingleSelection && PlaitDrawElement.isGeometry(targetElement)) {
1125
+ if (!isVirtualKey(event) &&
1126
+ !isDelete(event) &&
1127
+ !isSpaceHotkey(event) &&
1128
+ isSingleSelection &&
1129
+ PlaitDrawElement.isGeometry(targetElement)) {
1036
1130
  event.preventDefault();
1037
1131
  PlaitElement.getComponent(targetElement).editText();
1038
1132
  return;
@@ -1097,7 +1191,7 @@ const withGeometryCreateByDrag = (board) => {
1097
1191
  }
1098
1192
  geometryShapeG?.remove();
1099
1193
  geometryShapeG = null;
1100
- preventTouchMove(board, false);
1194
+ preventTouchMove(board, event, false);
1101
1195
  pointerUp(event);
1102
1196
  };
1103
1197
  return board;
@@ -1121,8 +1215,8 @@ const withGeometryCreateByDraw = (board) => {
1121
1215
  if (isGeometryPointer && isDrawingMode(board)) {
1122
1216
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1123
1217
  start = point;
1124
- preventTouchMove(board, true);
1125
1218
  const pointer = PlaitBoard.getPointer(board);
1219
+ preventTouchMove(board, event, true);
1126
1220
  if (pointer === DrawPointerType.text) {
1127
1221
  const points = getDefaultGeometryPoints(pointer, point);
1128
1222
  const textElement = createGeometryElement(GeometryShape.text, points, DefaultTextProperty.text);
@@ -1131,7 +1225,6 @@ const withGeometryCreateByDraw = (board) => {
1131
1225
  addSelectedElement(board, textElement);
1132
1226
  BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1133
1227
  start = null;
1134
- preventTouchMove(board, false);
1135
1228
  }
1136
1229
  }
1137
1230
  pointerDown(event);
@@ -1180,7 +1273,7 @@ const withGeometryCreateByDraw = (board) => {
1180
1273
  geometryShapeG = null;
1181
1274
  start = null;
1182
1275
  temporaryElement = null;
1183
- preventTouchMove(board, false);
1276
+ preventTouchMove(board, event, false);
1184
1277
  pointerUp(event);
1185
1278
  };
1186
1279
  return board;
@@ -1256,21 +1349,17 @@ const insertClipboardData = (board, elements, startPoint) => {
1256
1349
 
1257
1350
  const withDrawFragment = (baseBoard) => {
1258
1351
  const board = baseBoard;
1259
- const { deleteFragment, setFragment, insertFragment } = board;
1260
- board.deleteFragment = (data) => {
1352
+ const { getDeletedFragment, setFragment, insertFragment } = board;
1353
+ board.getDeletedFragment = (data) => {
1261
1354
  const drawElements = getSelectedDrawElements(board);
1262
1355
  if (drawElements.length) {
1263
1356
  const lines = getBoardLines(board);
1264
1357
  const geometryElements = drawElements.filter(value => PlaitDrawElement.isGeometry(value));
1265
1358
  const lineElements = drawElements.filter(value => PlaitDrawElement.isLine(value));
1266
1359
  const boundLineElements = lines.filter(line => geometryElements.find(geometry => PlaitLine.isBoundElementOfSource(line, geometry) || PlaitLine.isBoundElementOfTarget(line, geometry)));
1267
- CommonTransforms.removeElements(board, [
1268
- ...geometryElements,
1269
- ...lineElements,
1270
- ...boundLineElements.filter(line => !lineElements.includes(line))
1271
- ]);
1360
+ data.push(...[...geometryElements, ...lineElements, ...boundLineElements.filter(line => !lineElements.includes(line))]);
1272
1361
  }
1273
- deleteFragment(data);
1362
+ return getDeletedFragment(data);
1274
1363
  };
1275
1364
  board.setFragment = (data, rectangle) => {
1276
1365
  const targetDrawElements = getSelectedDrawElements(board);
@@ -1349,7 +1438,7 @@ const withLineCreateByDraw = (board) => {
1349
1438
  sourceRef.connection = transformPointToConnection(board, point, hitElement);
1350
1439
  sourceRef.boundId = hitElement.id;
1351
1440
  }
1352
- preventTouchMove(board, true);
1441
+ preventTouchMove(board, event, true);
1353
1442
  }
1354
1443
  pointerDown(event);
1355
1444
  };
@@ -1384,7 +1473,7 @@ const withLineCreateByDraw = (board) => {
1384
1473
  sourceRef = {};
1385
1474
  targetRef = {};
1386
1475
  temporaryElement = null;
1387
- preventTouchMove(board, false);
1476
+ preventTouchMove(board, event, false);
1388
1477
  pointerUp(event);
1389
1478
  };
1390
1479
  return board;
@@ -1408,7 +1497,7 @@ const withGeometryResize = (board) => {
1408
1497
  },
1409
1498
  detect: (point) => {
1410
1499
  const selectedGeometryElements = getSelectedGeometryElements(board);
1411
- if (selectedGeometryElements.length !== 1) {
1500
+ if (selectedGeometryElements.length !== 1 || getSelectedElements(board).length !== 1) {
1412
1501
  return null;
1413
1502
  }
1414
1503
  const target = selectedGeometryElements[0];
@@ -1446,8 +1535,7 @@ const withGeometryResize = (board) => {
1446
1535
  ];
1447
1536
  }
1448
1537
  points = normalizeShapePoints(points, isShift);
1449
- const component = PlaitElement.getComponent(resizeRef.element);
1450
- const { height: textHeight } = component.textManage.getSize();
1538
+ const { height: textHeight } = PlaitGeometry.getTextManage(resizeRef.element).getSize();
1451
1539
  DrawTransforms.resizeGeometry(board, points, textHeight, resizeRef.path);
1452
1540
  }
1453
1541
  };
@@ -1544,15 +1632,14 @@ const withLineBoundReaction = (board) => {
1544
1632
  const hitElement = getHitOutlineGeometry(board, movingPoint, -4);
1545
1633
  if (hitElement) {
1546
1634
  boundShapeG = drawBoundMask(board, hitElement);
1547
- const offset = (getStrokeWidthByElement(hitElement) + 1) / 2;
1548
- let nearestPoint = getNearestPoint(hitElement, movingPoint, offset);
1635
+ let nearestPoint = getNearestPoint(hitElement, movingPoint, ACTIVE_STROKE_WIDTH);
1549
1636
  const rectangle = getRectangleByPoints(hitElement.points);
1550
- const activeRectangle = RectangleClient.getOutlineRectangle(rectangle, -offset);
1637
+ const activeRectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
1551
1638
  const hitConnector = getHitConnectorPoint(nearestPoint, hitElement, activeRectangle);
1552
1639
  nearestPoint = hitConnector ? hitConnector : nearestPoint;
1553
1640
  const circleG = drawCircle(PlaitBoard.getRoughSVG(board), nearestPoint, 6, {
1554
1641
  stroke: SELECTION_BORDER_COLOR,
1555
- strokeWidth: 1,
1642
+ strokeWidth: ACTIVE_STROKE_WIDTH,
1556
1643
  fill: SELECTION_BORDER_COLOR,
1557
1644
  fillStyle: 'solid'
1558
1645
  });
@@ -1578,7 +1665,7 @@ const withLineText = (board) => {
1578
1665
  return PlaitDrawElement.isLine(element);
1579
1666
  })[0];
1580
1667
  if (hitTarget) {
1581
- const points = getElbowPoints(board, hitTarget);
1668
+ const points = getLinePoints(board, hitTarget);
1582
1669
  const point = getNearestPointBetweenPointAndSegments(clickPoint, points);
1583
1670
  const texts = hitTarget.texts?.length ? [...hitTarget.texts] : [];
1584
1671
  const textIndex = getHitLineTextIndex(board, hitTarget, clickPoint);
@@ -1651,7 +1738,7 @@ const withDraw = (board) => {
1651
1738
  return RectangleClient.isHit(rangeRectangle, client);
1652
1739
  }
1653
1740
  if (PlaitDrawElement.isLine(element)) {
1654
- const points = getElbowPoints(board, element);
1741
+ const points = getLinePoints(board, element);
1655
1742
  const strokeWidth = getStrokeWidthByElement(element);
1656
1743
  const isHitText = isHitLineText(board, element, range.focus);
1657
1744
  const isHit = isHitPolyLine(points, range.focus, strokeWidth, 3) || isHitText;
@@ -1680,5 +1767,5 @@ const withDraw = (board) => {
1680
1767
  * Generated bundle index. Do not edit.
1681
1768
  */
1682
1769
 
1683
- export { DefaultGeometryActiveStyle, DefaultGeometryProperty, DefaultGeometryStyle, DefaultTextProperty, DrawPointerType, GeometryComponent, GeometryPointer, GeometryShape, GeometryThreshold, LineComponent, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, ShapeDefaultSpace, StrokeStyle, createGeometryElement, createLineElement, drawBoundMask, drawElbowLine, drawGeometry, drawLineArrow, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getElbowPoints, getFillByElement, getHitConnectorPoint, getHitLineTextIndex, getLineDashByElement, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedLineElements, getSourcePoint, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTargetPoint, getTextRectangle, isHitLineText, isHitPolyLine, transformPointToConnection, withDraw };
1770
+ export { DefaultGeometryActiveStyle, DefaultGeometryProperty, DefaultGeometryStyle, DefaultTextProperty, DrawPointerType, DrawTransforms, GeometryComponent, GeometryPointer, GeometryShape, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, ShapeDefaultSpace, StrokeStyle, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getElbowPoints, getFillByElement, getHitConnectorPoint, getHitLineTextIndex, getLineDashByElement, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedLineElements, getSourcePoint, getStraightPoints, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTargetPoint, getTextRectangle, isHitLineText, isHitPolyLine, transformPointToConnection, withDraw };
1684
1771
  //# sourceMappingURL=plait-draw.mjs.map