@plait/draw 0.52.0-next.0 → 0.53.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.
- package/esm2022/interfaces/line.mjs +20 -8
- package/esm2022/line.component.mjs +5 -17
- package/esm2022/plugins/with-draw-fragment.mjs +1 -1
- package/esm2022/plugins/with-draw-hotkey.mjs +9 -7
- package/esm2022/plugins/with-draw-resize.mjs +63 -9
- package/esm2022/plugins/with-draw.mjs +2 -9
- package/esm2022/plugins/with-geometry-resize.mjs +14 -4
- package/esm2022/plugins/with-line-auto-complete-reaction.mjs +6 -3
- package/esm2022/plugins/with-line-auto-complete.mjs +5 -5
- package/esm2022/plugins/with-line-bound-reaction.mjs +7 -4
- package/esm2022/plugins/with-line-resize.mjs +3 -3
- package/esm2022/utils/hit.mjs +7 -5
- package/esm2022/utils/line/elbow.mjs +12 -4
- package/esm2022/utils/line/line-basic.mjs +9 -5
- package/esm2022/utils/line/line-common.mjs +25 -13
- package/esm2022/utils/line/line-resize.mjs +6 -10
- package/esm2022/utils/position/geometry.mjs +8 -6
- package/fesm2022/plait-draw.mjs +167 -136
- package/fesm2022/plait-draw.mjs.map +1 -1
- package/package.json +1 -1
- package/plugins/with-draw-resize.d.ts +6 -0
- package/utils/line/elbow.d.ts +3 -13
- package/utils/line/line-common.d.ts +3 -13
- package/utils/position/geometry.d.ts +2 -3
- package/esm2022/generators/group.generator.mjs +0 -20
- package/esm2022/group.component.mjs +0 -47
- package/generators/group.generator.d.ts +0 -6
- package/group.component.d.ts +0 -17
package/fesm2022/plait-draw.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ACTIVE_STROKE_WIDTH, ThemeColorMode, Point, RectangleClient, getElementById, createG, arrowPoints, createPath, distanceBetweenPointAndPoint, drawLinearPath, rotate, depthFirstRecursion, getIsRecursionFunc, idCreator, catmullRomFitting, PlaitBoard, findElements, createMask, createRect, getSelectedElements, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, isPolylineHitRectangle,
|
|
2
|
-
import { removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, isSourceAndTargetIntersect, getPoints, getPointByVectorComponent, getExtendPoint, getUnitVectorByPointAndPoint, Generator, getRectangleResizeHandleRefs, RESIZE_HANDLE_DIAMETER, getMemorizedLatest, memorizeLatest, getPointOnPolyline,
|
|
1
|
+
import { ACTIVE_STROKE_WIDTH, ThemeColorMode, createDebugGenerator, Point, RectangleClient, getElementById, rotatePointsByElement, createG, arrowPoints, createPath, distanceBetweenPointAndPoint, drawLinearPath, rotate, rotatePoints, depthFirstRecursion, rotateAntiPointsByElement, getIsRecursionFunc, idCreator, catmullRomFitting, PlaitBoard, findElements, createMask, createRect, getSelectedElements, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, isPolylineHitRectangle, isPointInPolygon, setStrokeLinecap, getNearestPointBetweenPointAndSegments, isPointInEllipse, getEllipseTangentSlope, getVectorFromPointAndSlope, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, Direction, hasValidAngle, Path, PlaitNode, toViewBoxPoint, toHostPoint, isSelectionMoving, RgbaToHEX, PlaitElement, getHitElementByPoint, preventTouchMove, createClipboardContext, WritableClipboardType, addClipboardContext, getRectangleByElements, getSelectionAngle, rotatedDataPoints, setAngleForG, CursorClass, temporaryDisableSelection, PRESS_AND_MOVE_BUFFER } from '@plait/core';
|
|
2
|
+
import { removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, isSourceAndTargetIntersect, getPoints, getPointByVectorComponent, getExtendPoint, getUnitVectorByPointAndPoint, Generator, getRectangleResizeHandleRefs, RESIZE_HANDLE_DIAMETER, getMemorizedLatest, memorizeLatest, getPointOnPolyline, TRANSPARENT, getCrossingPointsBetweenPointAndSegment, isPointOnSegment, getDirectionByVector, getOppositeDirection, getDirectionFactor, rotateVector, getDirectionByPointOfRectangle, rotateVectorAnti90, getSourceAndTargetOuterRectangle, getNextPoint, normalizeShapePoints, getFirstTextEditor, PRIMARY_COLOR, CommonPluginElement, ActiveGenerator, WithTextPluginKey, drawPrimaryHandle, drawFillPrimaryHandle, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, getElementsText, acceptImageTypes, getElementOfFocusedImage, buildImage, getDirectionFactorByDirectionComponent, isCornerHandle, resetPointsAfterResize, getFirstTextManage, withResize, drawHandle, getIndexByResizeHandle, getSymmetricHandleIndex, getResizeHandlePointByIndex, isResizingByCondition, getRatioByPoint, ImageGenerator, ResizeHandle } from '@plait/common';
|
|
3
3
|
import { Alignment, buildText, DEFAULT_FONT_SIZE, getTextSize, AlignEditor, TextManage } from '@plait/text';
|
|
4
4
|
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
@@ -166,6 +166,8 @@ const LINE_AUTO_COMPLETE_HOVERED_OPACITY = 0.8;
|
|
|
166
166
|
const LINE_AUTO_COMPLETE_HOVERED_DIAMETER = 10;
|
|
167
167
|
const LINE_ALIGN_TOLERANCE = 3;
|
|
168
168
|
|
|
169
|
+
const debugKey$2 = 'debug:plait:line-mirror';
|
|
170
|
+
const debugGenerator$2 = createDebugGenerator(debugKey$2);
|
|
169
171
|
const alignPoints = (basePoint, movingPoint) => {
|
|
170
172
|
const newPoint = [...movingPoint];
|
|
171
173
|
if (Point.isVertical(newPoint, basePoint, LINE_ALIGN_TOLERANCE)) {
|
|
@@ -429,6 +431,7 @@ function findOrthogonalParallelSegments(segment, keyPoints) {
|
|
|
429
431
|
return parallelSegments;
|
|
430
432
|
}
|
|
431
433
|
function findMirrorSegments(board, segment, parallelSegments, sourceRectangle, targetRectangle) {
|
|
434
|
+
debugGenerator$2.isDebug() && debugGenerator$2.clear();
|
|
432
435
|
const mirrorSegments = [];
|
|
433
436
|
for (let index = 0; index < parallelSegments.length; index++) {
|
|
434
437
|
const parallelPath = parallelSegments[index];
|
|
@@ -442,14 +445,7 @@ function findMirrorSegments(board, segment, parallelSegments, sourceRectangle, t
|
|
|
442
445
|
const isValid = !RectangleClient.isHit(fakeRectangle, sourceRectangle) && !RectangleClient.isHit(fakeRectangle, targetRectangle);
|
|
443
446
|
if (isValid) {
|
|
444
447
|
mirrorSegments.push([startPoint, endPoint]);
|
|
445
|
-
|
|
446
|
-
// fakeRectangle.x,
|
|
447
|
-
// fakeRectangle.y,
|
|
448
|
-
// fakeRectangle.width,
|
|
449
|
-
// fakeRectangle.height,
|
|
450
|
-
// { stroke: 'blue' }
|
|
451
|
-
// );
|
|
452
|
-
// PlaitBoard.getElementActiveHost(board).append(fakeRectangleG);
|
|
448
|
+
debugGenerator$2.isDebug() && debugGenerator$2.drawPolygon(board, RectangleClient.getCornerPoints(fakeRectangle));
|
|
453
449
|
}
|
|
454
450
|
}
|
|
455
451
|
return mirrorSegments;
|
|
@@ -549,8 +545,16 @@ const getSourceAndTargetRectangle = (board, element, handleRefPair) => {
|
|
|
549
545
|
const target = handleRefPair.target;
|
|
550
546
|
targetElement = createFakeElement(target.point, target.vector);
|
|
551
547
|
}
|
|
552
|
-
|
|
553
|
-
const
|
|
548
|
+
let sourceRectangle = RectangleClient.getRectangleByPoints(sourceElement.points);
|
|
549
|
+
const rotatedSourceCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(sourceRectangle), sourceElement) ||
|
|
550
|
+
RectangleClient.getCornerPoints(sourceRectangle);
|
|
551
|
+
sourceRectangle = RectangleClient.getRectangleByPoints(rotatedSourceCornerPoints);
|
|
552
|
+
sourceRectangle = RectangleClient.inflate(sourceRectangle, getStrokeWidthByElement(sourceElement) * 2);
|
|
553
|
+
let targetRectangle = RectangleClient.getRectangleByPoints(targetElement.points);
|
|
554
|
+
const rotatedTargetCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(targetRectangle), targetElement) ||
|
|
555
|
+
RectangleClient.getCornerPoints(targetRectangle);
|
|
556
|
+
targetRectangle = RectangleClient.getRectangleByPoints(rotatedTargetCornerPoints);
|
|
557
|
+
targetRectangle = RectangleClient.inflate(targetRectangle, getStrokeWidthByElement(targetElement) * 2);
|
|
554
558
|
return {
|
|
555
559
|
sourceRectangle,
|
|
556
560
|
targetRectangle
|
|
@@ -706,10 +710,12 @@ class LineShapeGenerator extends Generator {
|
|
|
706
710
|
}
|
|
707
711
|
}
|
|
708
712
|
|
|
709
|
-
const getHitRectangleResizeHandleRef = (board, rectangle, point) => {
|
|
710
|
-
const
|
|
713
|
+
const getHitRectangleResizeHandleRef = (board, rectangle, point, angle = 0) => {
|
|
714
|
+
const centerPoint = RectangleClient.getCenterPoint(rectangle);
|
|
715
|
+
const rotatedPoint = rotatePoints([point], centerPoint, -angle)[0];
|
|
716
|
+
const resizeHandleRefs = getRectangleResizeHandleRefs(rectangle, RESIZE_HANDLE_DIAMETER, angle);
|
|
711
717
|
const result = resizeHandleRefs.find(resizeHandleRef => {
|
|
712
|
-
return RectangleClient.isHit(RectangleClient.getRectangleByPoints([
|
|
718
|
+
return RectangleClient.isHit(RectangleClient.getRectangleByPoints([rotatedPoint, rotatedPoint]), resizeHandleRef.rectangle);
|
|
713
719
|
});
|
|
714
720
|
return result;
|
|
715
721
|
};
|
|
@@ -720,7 +726,7 @@ const getHitOutlineGeometry = (board, point, offset = 0) => {
|
|
|
720
726
|
let client = RectangleClient.getRectangleByPoints(node.points);
|
|
721
727
|
client = RectangleClient.getOutlineRectangle(client, offset);
|
|
722
728
|
const shape = getShape(node);
|
|
723
|
-
const isHit = getEngine(shape).isInsidePoint(client, point);
|
|
729
|
+
const isHit = getEngine(shape).isInsidePoint(client, rotateAntiPointsByElement(point, node) || point);
|
|
724
730
|
if (isHit) {
|
|
725
731
|
geometry = node;
|
|
726
732
|
}
|
|
@@ -996,8 +1002,12 @@ const Q2C = (points) => {
|
|
|
996
1002
|
};
|
|
997
1003
|
const handleLineCreating = (board, lineShape, sourcePoint, movingPoint, sourceElement, lineShapeG) => {
|
|
998
1004
|
const hitElement = getHitOutlineGeometry(board, movingPoint, REACTION_MARGIN);
|
|
999
|
-
const targetConnection = hitElement
|
|
1000
|
-
|
|
1005
|
+
const targetConnection = hitElement
|
|
1006
|
+
? getConnectionByNearestPoint(board, rotateAntiPointsByElement(movingPoint, hitElement) || movingPoint, hitElement)
|
|
1007
|
+
: undefined;
|
|
1008
|
+
const sourceConnection = sourceElement
|
|
1009
|
+
? getConnectionByNearestPoint(board, rotateAntiPointsByElement(sourcePoint, sourceElement) || sourcePoint, sourceElement)
|
|
1010
|
+
: undefined;
|
|
1001
1011
|
const targetBoundId = hitElement ? hitElement.id : undefined;
|
|
1002
1012
|
const lineGenerator = new LineShapeGenerator(board);
|
|
1003
1013
|
const memorizedLatest = getLineMemorizedLatest();
|
|
@@ -1006,7 +1016,7 @@ const handleLineCreating = (board, lineShape, sourcePoint, movingPoint, sourceEl
|
|
|
1006
1016
|
targetMarker = memorizedLatest.target;
|
|
1007
1017
|
sourceMarker && delete memorizedLatest.source;
|
|
1008
1018
|
targetMarker && delete memorizedLatest.target;
|
|
1009
|
-
const temporaryLineElement = createLineElement(lineShape, [sourcePoint, movingPoint], { marker: sourceMarker || LineMarkerType.none, connection:
|
|
1019
|
+
const temporaryLineElement = createLineElement(lineShape, [sourcePoint, movingPoint], { marker: sourceMarker || LineMarkerType.none, connection: sourceConnection, boundId: sourceElement?.id }, { marker: targetMarker || LineMarkerType.arrow, connection: targetConnection, boundId: targetBoundId }, [], {
|
|
1010
1020
|
strokeWidth: DefaultLineStyle.strokeWidth,
|
|
1011
1021
|
...memorizedLatest
|
|
1012
1022
|
});
|
|
@@ -1157,7 +1167,7 @@ const isRectangleHitDrawElement = (board, element, selection) => {
|
|
|
1157
1167
|
if (PlaitDrawElement.isImage(element)) {
|
|
1158
1168
|
const client = RectangleClient.getRectangleByPoints(element.points);
|
|
1159
1169
|
const rotatedCornerPoints = rotatePoints(RectangleClient.getCornerPoints(client), RectangleClient.getCenterPoint(client), element.angle);
|
|
1160
|
-
return isPolylineHitRectangle(rotatedCornerPoints,
|
|
1170
|
+
return isPolylineHitRectangle(rotatedCornerPoints, rangeRectangle);
|
|
1161
1171
|
}
|
|
1162
1172
|
if (PlaitDrawElement.isLine(element)) {
|
|
1163
1173
|
const points = getLinePoints(board, element);
|
|
@@ -1203,7 +1213,9 @@ const isHitDrawElement = (board, element, point) => {
|
|
|
1203
1213
|
}
|
|
1204
1214
|
}
|
|
1205
1215
|
if (PlaitDrawElement.isImage(element)) {
|
|
1206
|
-
|
|
1216
|
+
const client = RectangleClient.getRectangleByPoints(element.points);
|
|
1217
|
+
const rotatedCornerPoints = rotatePoints(RectangleClient.getCornerPoints(client), RectangleClient.getCenterPoint(client), element.angle);
|
|
1218
|
+
return isPointInPolygon(point, rotatedCornerPoints);
|
|
1207
1219
|
}
|
|
1208
1220
|
if (PlaitDrawElement.isLine(element)) {
|
|
1209
1221
|
return isHitLine(board, element, point);
|
|
@@ -2537,24 +2549,36 @@ const getLineHandleRefPair = (board, element) => {
|
|
|
2537
2549
|
if (sourceBoundElement) {
|
|
2538
2550
|
const connectionOffset = PlaitLine.isSourceMarkOrTargetMark(element, LineMarkerType.none, LineHandleKey.source) ? 0 : strokeWidth;
|
|
2539
2551
|
const sourceVector = getVectorByConnection(sourceBoundElement, element.source.connection);
|
|
2540
|
-
|
|
2541
|
-
sourceDirection = direction ? direction : sourceDirection;
|
|
2542
|
-
sourcePoint = getConnectionPoint(sourceBoundElement, element.source.connection, sourceDirection, connectionOffset);
|
|
2552
|
+
sourceHandleRef.vector = sourceVector;
|
|
2543
2553
|
sourceHandleRef.boundElement = sourceBoundElement;
|
|
2554
|
+
if (hasValidAngle(sourceBoundElement)) {
|
|
2555
|
+
const direction = getDirectionByVector(rotateVector(sourceVector, sourceBoundElement.angle));
|
|
2556
|
+
sourceDirection = direction ? direction : sourceDirection;
|
|
2557
|
+
}
|
|
2558
|
+
else {
|
|
2559
|
+
const direction = getDirectionByVector(sourceVector);
|
|
2560
|
+
sourceDirection = direction ? direction : sourceDirection;
|
|
2561
|
+
}
|
|
2544
2562
|
sourceHandleRef.direction = sourceDirection;
|
|
2545
|
-
|
|
2546
|
-
sourceHandleRef.
|
|
2563
|
+
sourcePoint = getConnectionPoint(sourceBoundElement, element.source.connection, sourceDirection, connectionOffset);
|
|
2564
|
+
sourceHandleRef.point = rotatePointsByElement(sourcePoint, sourceBoundElement) || sourcePoint;
|
|
2547
2565
|
}
|
|
2548
2566
|
if (targetBoundElement) {
|
|
2549
2567
|
const connectionOffset = PlaitLine.isSourceMarkOrTargetMark(element, LineMarkerType.none, LineHandleKey.target) ? 0 : strokeWidth;
|
|
2550
2568
|
const targetVector = getVectorByConnection(targetBoundElement, element.target.connection);
|
|
2551
|
-
|
|
2552
|
-
targetDirection = direction ? direction : targetDirection;
|
|
2553
|
-
targetPoint = getConnectionPoint(targetBoundElement, element.target.connection, targetDirection, connectionOffset);
|
|
2569
|
+
targetHandleRef.vector = targetVector;
|
|
2554
2570
|
targetHandleRef.boundElement = targetBoundElement;
|
|
2571
|
+
if (hasValidAngle(targetBoundElement)) {
|
|
2572
|
+
const direction = getDirectionByVector(rotateVector(targetVector, targetBoundElement.angle));
|
|
2573
|
+
targetDirection = direction ? direction : targetDirection;
|
|
2574
|
+
}
|
|
2575
|
+
else {
|
|
2576
|
+
const direction = getDirectionByVector(targetVector);
|
|
2577
|
+
targetDirection = direction ? direction : targetDirection;
|
|
2578
|
+
}
|
|
2555
2579
|
targetHandleRef.direction = targetDirection;
|
|
2556
|
-
|
|
2557
|
-
targetHandleRef.
|
|
2580
|
+
targetPoint = getConnectionPoint(targetBoundElement, element.target.connection, targetDirection, connectionOffset);
|
|
2581
|
+
targetHandleRef.point = rotatePointsByElement(targetPoint, targetBoundElement) || targetPoint;
|
|
2558
2582
|
}
|
|
2559
2583
|
return { source: sourceHandleRef, target: targetHandleRef };
|
|
2560
2584
|
};
|
|
@@ -2659,12 +2683,24 @@ const PlaitLine = {
|
|
|
2659
2683
|
return line.target.boundId === element.id;
|
|
2660
2684
|
},
|
|
2661
2685
|
getPoints(board, line) {
|
|
2662
|
-
let sourcePoint
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2686
|
+
let sourcePoint;
|
|
2687
|
+
if (line.source.boundId) {
|
|
2688
|
+
const sourceElement = getElementById(board, line.source.boundId);
|
|
2689
|
+
const sourceConnectionPoint = getConnectionPoint(sourceElement, line.source.connection);
|
|
2690
|
+
sourcePoint = rotatePointsByElement(sourceConnectionPoint, sourceElement) || sourceConnectionPoint;
|
|
2691
|
+
}
|
|
2692
|
+
else {
|
|
2693
|
+
sourcePoint = line.points[0];
|
|
2694
|
+
}
|
|
2695
|
+
let targetPoint;
|
|
2696
|
+
if (line.target.boundId) {
|
|
2697
|
+
const targetElement = getElementById(board, line.target.boundId);
|
|
2698
|
+
const targetConnectionPoint = getConnectionPoint(targetElement, line.target.connection);
|
|
2699
|
+
targetPoint = rotatePointsByElement(targetConnectionPoint, targetElement) || targetConnectionPoint;
|
|
2700
|
+
}
|
|
2701
|
+
else {
|
|
2702
|
+
targetPoint = line.points[line.points.length - 1];
|
|
2703
|
+
}
|
|
2668
2704
|
const restPoints = line.points.length > 2 ? line.points.slice(1, line.points.length - 1) : [];
|
|
2669
2705
|
return [sourcePoint, ...restPoints, targetPoint];
|
|
2670
2706
|
}
|
|
@@ -3235,6 +3271,8 @@ class LineActiveGenerator extends Generator {
|
|
|
3235
3271
|
}
|
|
3236
3272
|
}
|
|
3237
3273
|
|
|
3274
|
+
const debugKey$1 = 'debug:plait:line-turning';
|
|
3275
|
+
const debugGenerator$1 = createDebugGenerator(debugKey$1);
|
|
3238
3276
|
class LineComponent extends CommonPluginElement {
|
|
3239
3277
|
constructor(viewContainerRef, cdr) {
|
|
3240
3278
|
super(cdr);
|
|
@@ -3259,21 +3297,7 @@ class LineComponent extends CommonPluginElement {
|
|
|
3259
3297
|
super.ngOnInit();
|
|
3260
3298
|
this.boundedElements = this.getBoundedElements();
|
|
3261
3299
|
this.drawText();
|
|
3262
|
-
|
|
3263
|
-
// points.forEach((p, index) => {
|
|
3264
|
-
// if (index === 0) {
|
|
3265
|
-
// return;
|
|
3266
|
-
// }
|
|
3267
|
-
// if (index === points.length - 1) {
|
|
3268
|
-
// return;
|
|
3269
|
-
// }
|
|
3270
|
-
// const dataPointG = PlaitBoard.getRoughSVG(this.board).circle(p[0], p[1], 8 * index, {
|
|
3271
|
-
// stroke: '#f08c02',
|
|
3272
|
-
// fill: '#f08c02',
|
|
3273
|
-
// fillStyle: 'solid'
|
|
3274
|
-
// });
|
|
3275
|
-
// PlaitBoard.getElementActiveHost(this.board).append(dataPointG);
|
|
3276
|
-
// });
|
|
3300
|
+
debugGenerator$1.isDebug() && debugGenerator$1.drawCircles(this.board, this.element.points.slice(1, -1), 4, true);
|
|
3277
3301
|
}
|
|
3278
3302
|
getBoundedElements() {
|
|
3279
3303
|
const boundedElements = {};
|
|
@@ -3429,10 +3453,13 @@ const withDrawHotkey = (board) => {
|
|
|
3429
3453
|
};
|
|
3430
3454
|
board.dblClick = (event) => {
|
|
3431
3455
|
event.preventDefault();
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
const
|
|
3435
|
-
|
|
3456
|
+
if (!PlaitBoard.isReadonly(board)) {
|
|
3457
|
+
const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
3458
|
+
const hitElement = getHitElementByPoint(board, point);
|
|
3459
|
+
if (hitElement && PlaitDrawElement.isGeometry(hitElement)) {
|
|
3460
|
+
const component = PlaitElement.getComponent(hitElement);
|
|
3461
|
+
component.editText();
|
|
3462
|
+
}
|
|
3436
3463
|
}
|
|
3437
3464
|
dblClick(event);
|
|
3438
3465
|
};
|
|
@@ -4122,6 +4149,8 @@ function getResizeAlignRef(board, resizeRef, resizeState, resizeOriginPointAndHa
|
|
|
4122
4149
|
});
|
|
4123
4150
|
}
|
|
4124
4151
|
|
|
4152
|
+
const debugKey = 'debug:plait:resize-for-rotation';
|
|
4153
|
+
const debugGenerator = createDebugGenerator(debugKey);
|
|
4125
4154
|
function withDrawResize(board) {
|
|
4126
4155
|
const { afterChange } = board;
|
|
4127
4156
|
let alignG;
|
|
@@ -4136,7 +4165,8 @@ function withDrawResize(board) {
|
|
|
4136
4165
|
hitTest: (point) => {
|
|
4137
4166
|
const elements = getSelectedElements(board);
|
|
4138
4167
|
const boundingRectangle = getRectangleByElements(board, elements, false);
|
|
4139
|
-
const
|
|
4168
|
+
const angle = getSelectionAngle(elements);
|
|
4169
|
+
const handleRef = getHitRectangleResizeHandleRef(board, boundingRectangle, point, angle);
|
|
4140
4170
|
if (handleRef) {
|
|
4141
4171
|
return {
|
|
4142
4172
|
element: elements,
|
|
@@ -4149,20 +4179,66 @@ function withDrawResize(board) {
|
|
|
4149
4179
|
},
|
|
4150
4180
|
onResize: (resizeRef, resizeState) => {
|
|
4151
4181
|
alignG?.remove();
|
|
4182
|
+
debugGenerator.isDebug() && debugGenerator.clear();
|
|
4152
4183
|
const isFromCorner = isCornerHandle(board, resizeRef.handle);
|
|
4153
4184
|
const isAspectRatio = resizeState.isShift || isFromCorner;
|
|
4185
|
+
const centerPoint = RectangleClient.getCenterPoint(resizeRef.rectangle);
|
|
4154
4186
|
const { originPoint, handlePoint } = getResizeOriginPointAndHandlePoint(board, resizeRef);
|
|
4187
|
+
const angle = getSelectionAngle(resizeRef.element);
|
|
4188
|
+
let bulkRotationRef;
|
|
4189
|
+
if (angle) {
|
|
4190
|
+
bulkRotationRef = {
|
|
4191
|
+
angle: angle,
|
|
4192
|
+
offsetX: 0,
|
|
4193
|
+
offsetY: 0,
|
|
4194
|
+
newCenterPoint: [0, 0]
|
|
4195
|
+
};
|
|
4196
|
+
const [rotatedStartPoint, rotateEndPoint] = rotatePoints([resizeState.startPoint, resizeState.endPoint], centerPoint, -bulkRotationRef.angle);
|
|
4197
|
+
resizeState.startPoint = rotatedStartPoint;
|
|
4198
|
+
resizeState.endPoint = rotateEndPoint;
|
|
4199
|
+
}
|
|
4155
4200
|
const resizeAlignRef = getResizeAlignRef(board, resizeRef, resizeState, {
|
|
4156
4201
|
originPoint,
|
|
4157
4202
|
handlePoint
|
|
4158
4203
|
}, isAspectRatio, isFromCorner);
|
|
4159
4204
|
alignG = resizeAlignRef.alignG;
|
|
4160
4205
|
PlaitBoard.getElementActiveHost(board).append(alignG);
|
|
4161
|
-
|
|
4162
|
-
const
|
|
4163
|
-
|
|
4206
|
+
if (bulkRotationRef) {
|
|
4207
|
+
const boundingBoxCornerPoints = RectangleClient.getPoints(resizeRef.rectangle);
|
|
4208
|
+
const resizedBoundingBoxCornerPoints = boundingBoxCornerPoints.map(p => {
|
|
4164
4209
|
return movePointByZoomAndOriginPoint(p, originPoint, resizeAlignRef.xZoom, resizeAlignRef.yZoom);
|
|
4165
4210
|
});
|
|
4211
|
+
const newBoundingBox = RectangleClient.getRectangleByPoints(resizedBoundingBoxCornerPoints);
|
|
4212
|
+
debugGenerator.isDebug() && debugGenerator.drawRectangle(board, newBoundingBox, { stroke: 'blue' });
|
|
4213
|
+
const newBoundingBoxCenter = RectangleClient.getCenterPoint(newBoundingBox);
|
|
4214
|
+
const adjustedNewBoundingBoxPoints = resetPointsAfterResize(RectangleClient.getRectangleByPoints(boundingBoxCornerPoints), RectangleClient.getRectangleByPoints(resizedBoundingBoxCornerPoints), centerPoint, newBoundingBoxCenter, bulkRotationRef.angle);
|
|
4215
|
+
const newCenter = RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(adjustedNewBoundingBoxPoints));
|
|
4216
|
+
bulkRotationRef = Object.assign(bulkRotationRef, {
|
|
4217
|
+
offsetX: newCenter[0] - newBoundingBoxCenter[0],
|
|
4218
|
+
offsetY: newCenter[1] - newBoundingBoxCenter[1],
|
|
4219
|
+
newCenterPoint: newCenter
|
|
4220
|
+
});
|
|
4221
|
+
debugGenerator.isDebug() && debugGenerator.drawRectangle(board, adjustedNewBoundingBoxPoints);
|
|
4222
|
+
}
|
|
4223
|
+
resizeRef.element.forEach(target => {
|
|
4224
|
+
const path = PlaitBoard.findPath(board, target);
|
|
4225
|
+
let points;
|
|
4226
|
+
if (bulkRotationRef) {
|
|
4227
|
+
const reversedPoints = rotatedDataPoints(target.points, centerPoint, -bulkRotationRef.angle);
|
|
4228
|
+
points = reversedPoints.map((p) => {
|
|
4229
|
+
return movePointByZoomAndOriginPoint(p, originPoint, resizeAlignRef.xZoom, resizeAlignRef.yZoom);
|
|
4230
|
+
});
|
|
4231
|
+
const adjustTargetPoints = points.map(p => [
|
|
4232
|
+
p[0] + bulkRotationRef.offsetX,
|
|
4233
|
+
p[1] + bulkRotationRef.offsetY
|
|
4234
|
+
]);
|
|
4235
|
+
points = rotatedDataPoints(adjustTargetPoints, bulkRotationRef.newCenterPoint, bulkRotationRef.angle);
|
|
4236
|
+
}
|
|
4237
|
+
else {
|
|
4238
|
+
points = target.points.map(p => {
|
|
4239
|
+
return movePointByZoomAndOriginPoint(p, originPoint, resizeAlignRef.xZoom, resizeAlignRef.yZoom);
|
|
4240
|
+
});
|
|
4241
|
+
}
|
|
4166
4242
|
if (PlaitDrawElement.isGeometry(target)) {
|
|
4167
4243
|
const { height: textHeight } = getFirstTextManage(target).getSize();
|
|
4168
4244
|
DrawTransforms.resizeGeometry(board, points, textHeight, path);
|
|
@@ -4201,8 +4277,13 @@ function withDrawResize(board) {
|
|
|
4201
4277
|
handleG = createG();
|
|
4202
4278
|
const elements = getSelectedElements(board);
|
|
4203
4279
|
const boundingRectangle = getRectangleByElements(board, elements, false);
|
|
4204
|
-
|
|
4205
|
-
|
|
4280
|
+
let corners = RectangleClient.getCornerPoints(boundingRectangle);
|
|
4281
|
+
const angle = getSelectionAngle(elements);
|
|
4282
|
+
if (angle) {
|
|
4283
|
+
const centerPoint = RectangleClient.getCenterPoint(boundingRectangle);
|
|
4284
|
+
corners = rotatePoints(corners, centerPoint, angle);
|
|
4285
|
+
}
|
|
4286
|
+
corners.forEach(corner => {
|
|
4206
4287
|
const g = drawHandle(board, corner);
|
|
4207
4288
|
handleG && handleG.append(g);
|
|
4208
4289
|
});
|
|
@@ -4281,7 +4362,7 @@ const withGeometryResize = (board) => {
|
|
|
4281
4362
|
const targetComponent = PlaitElement.getComponent(selectedElements[0]);
|
|
4282
4363
|
if (targetComponent.activeGenerator.hasResizeHandle) {
|
|
4283
4364
|
const rectangle = board.getRectangle(target);
|
|
4284
|
-
const handleRef = getHitRectangleResizeHandleRef(board, rectangle, point);
|
|
4365
|
+
const handleRef = getHitRectangleResizeHandleRef(board, rectangle, point, target.angle);
|
|
4285
4366
|
if (handleRef) {
|
|
4286
4367
|
return {
|
|
4287
4368
|
element: target,
|
|
@@ -4294,6 +4375,13 @@ const withGeometryResize = (board) => {
|
|
|
4294
4375
|
return null;
|
|
4295
4376
|
},
|
|
4296
4377
|
onResize: (resizeRef, resizeState) => {
|
|
4378
|
+
const centerPoint = RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(resizeRef.element.points));
|
|
4379
|
+
const angle = resizeRef.element.angle;
|
|
4380
|
+
if (angle) {
|
|
4381
|
+
const [rotatedStartPoint, rotateEndPoint] = rotatePoints([resizeState.startPoint, resizeState.endPoint], centerPoint, -resizeRef.element.angle);
|
|
4382
|
+
resizeState.startPoint = rotatedStartPoint;
|
|
4383
|
+
resizeState.endPoint = rotateEndPoint;
|
|
4384
|
+
}
|
|
4297
4385
|
alignG?.remove();
|
|
4298
4386
|
const isFromCorner = isCornerHandle(board, resizeRef.handle);
|
|
4299
4387
|
const isAspectRatio = resizeState.isShift || PlaitDrawElement.isImage(resizeRef.element);
|
|
@@ -4305,6 +4393,9 @@ const withGeometryResize = (board) => {
|
|
|
4305
4393
|
alignG = resizeAlignRef.alignG;
|
|
4306
4394
|
PlaitBoard.getElementActiveHost(board).append(alignG);
|
|
4307
4395
|
let points = resizeAlignRef.activePoints;
|
|
4396
|
+
if (angle) {
|
|
4397
|
+
points = resetPointsAfterResize(resizeRef.rectangle, RectangleClient.getRectangleByPoints(points), centerPoint, RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(points)), angle);
|
|
4398
|
+
}
|
|
4308
4399
|
if (PlaitDrawElement.isGeometry(resizeRef.element)) {
|
|
4309
4400
|
const { height: textHeight } = getFirstTextManage(resizeRef.element).getSize();
|
|
4310
4401
|
DrawTransforms.resizeGeometry(board, points, textHeight, resizeRef.path);
|
|
@@ -4382,7 +4473,7 @@ const withLineResize = (board) => {
|
|
|
4382
4473
|
const object = resizeRef.handle === LineResizeHandle.source ? source : target;
|
|
4383
4474
|
points[handleIndex] = resizeState.endPoint;
|
|
4384
4475
|
if (hitElement) {
|
|
4385
|
-
object.connection = getConnectionByNearestPoint(board, resizeState.endPoint, hitElement);
|
|
4476
|
+
object.connection = getConnectionByNearestPoint(board, rotateAntiPointsByElement(resizeState.endPoint, hitElement) || resizeState.endPoint, hitElement);
|
|
4386
4477
|
object.boundId = hitElement.id;
|
|
4387
4478
|
}
|
|
4388
4479
|
else {
|
|
@@ -4490,9 +4581,9 @@ const withLineBoundReaction = (board) => {
|
|
|
4490
4581
|
if (isLinePointer || isLineResizing) {
|
|
4491
4582
|
const hitElement = getHitOutlineGeometry(board, movingPoint, -4);
|
|
4492
4583
|
if (hitElement) {
|
|
4493
|
-
boundShapeG = drawBoundMask(board, hitElement);
|
|
4494
|
-
let nearestPoint = getNearestPoint(hitElement, movingPoint);
|
|
4495
4584
|
const rectangle = RectangleClient.getRectangleByPoints(hitElement.points);
|
|
4585
|
+
boundShapeG = drawBoundMask(board, hitElement);
|
|
4586
|
+
let nearestPoint = getNearestPoint(hitElement, rotateAntiPointsByElement(movingPoint, hitElement) || movingPoint);
|
|
4496
4587
|
const activeRectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
|
|
4497
4588
|
const hitConnector = getHitConnectorPoint(nearestPoint, hitElement, activeRectangle);
|
|
4498
4589
|
nearestPoint = hitConnector ? hitConnector : nearestPoint;
|
|
@@ -4504,6 +4595,9 @@ const withLineBoundReaction = (board) => {
|
|
|
4504
4595
|
});
|
|
4505
4596
|
boundShapeG.appendChild(circleG);
|
|
4506
4597
|
PlaitBoard.getElementActiveHost(board).append(boundShapeG);
|
|
4598
|
+
if (hasValidAngle(hitElement)) {
|
|
4599
|
+
setAngleForG(boundShapeG, RectangleClient.getCenterPoint(rectangle), hitElement.angle);
|
|
4600
|
+
}
|
|
4507
4601
|
}
|
|
4508
4602
|
}
|
|
4509
4603
|
pointerMove(event);
|
|
@@ -4654,7 +4748,7 @@ const withLineAutoCompleteReaction = (board) => {
|
|
|
4654
4748
|
const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
4655
4749
|
if (!PlaitBoard.isReadonly(board) && !isSelectionMoving(board) && targetElement && PlaitDrawElement.isShape(targetElement)) {
|
|
4656
4750
|
const points = getAutoCompletePoints(targetElement);
|
|
4657
|
-
const hitIndex = getHitIndexOfAutoCompletePoint(movingPoint, points);
|
|
4751
|
+
const hitIndex = getHitIndexOfAutoCompletePoint(rotateAntiPointsByElement(movingPoint, targetElement) || movingPoint, points);
|
|
4658
4752
|
const hitPoint = points[hitIndex];
|
|
4659
4753
|
const component = PlaitElement.getComponent(targetElement);
|
|
4660
4754
|
component.lineAutoCompleteGenerator.recoverAutoCompleteG();
|
|
@@ -4667,6 +4761,9 @@ const withLineAutoCompleteReaction = (board) => {
|
|
|
4667
4761
|
});
|
|
4668
4762
|
PlaitBoard.getElementActiveHost(board).append(reactionG);
|
|
4669
4763
|
PlaitBoard.getBoardContainer(board).classList.add(CursorClass.crosshair);
|
|
4764
|
+
if (hasValidAngle(targetElement)) {
|
|
4765
|
+
setAngleForG(reactionG, RectangleClient.getCenterPoint(board.getRectangle(targetElement)), targetElement.angle);
|
|
4766
|
+
}
|
|
4670
4767
|
}
|
|
4671
4768
|
}
|
|
4672
4769
|
pointerMove(event);
|
|
@@ -4687,7 +4784,7 @@ const withLineAutoComplete = (board) => {
|
|
|
4687
4784
|
const clickPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
4688
4785
|
if (!PlaitBoard.isReadonly(board) && targetElement && PlaitDrawElement.isShape(targetElement)) {
|
|
4689
4786
|
const points = getAutoCompletePoints(targetElement);
|
|
4690
|
-
const index = getHitIndexOfAutoCompletePoint(clickPoint, points);
|
|
4787
|
+
const index = getHitIndexOfAutoCompletePoint(rotateAntiPointsByElement(clickPoint, targetElement) || clickPoint, points);
|
|
4691
4788
|
const hitPoint = points[index];
|
|
4692
4789
|
if (hitPoint) {
|
|
4693
4790
|
temporaryDisableSelection(board);
|
|
@@ -4703,7 +4800,7 @@ const withLineAutoComplete = (board) => {
|
|
|
4703
4800
|
lineShapeG = createG();
|
|
4704
4801
|
let movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
4705
4802
|
if (startPoint && sourceElement) {
|
|
4706
|
-
const distance = distanceBetweenPointAndPoint(...movingPoint, ...startPoint);
|
|
4803
|
+
const distance = distanceBetweenPointAndPoint(...movingPoint, ...(rotatePointsByElement(startPoint, sourceElement) || startPoint));
|
|
4707
4804
|
if (distance > PRESS_AND_MOVE_BUFFER) {
|
|
4708
4805
|
const rectangle = RectangleClient.getRectangleByPoints(sourceElement.points);
|
|
4709
4806
|
const shape = getShape(sourceElement);
|
|
@@ -4713,7 +4810,7 @@ const withLineAutoComplete = (board) => {
|
|
|
4713
4810
|
const crossingPoint = engine.getNearestCrossingPoint(rectangle, startPoint);
|
|
4714
4811
|
sourcePoint = crossingPoint;
|
|
4715
4812
|
}
|
|
4716
|
-
temporaryElement = handleLineCreating(board, LineShape.elbow, sourcePoint, movingPoint, sourceElement, lineShapeG);
|
|
4813
|
+
temporaryElement = handleLineCreating(board, LineShape.elbow, rotatePointsByElement(sourcePoint, sourceElement) || sourcePoint, movingPoint, sourceElement, lineShapeG);
|
|
4717
4814
|
}
|
|
4718
4815
|
}
|
|
4719
4816
|
pointerMove(event);
|
|
@@ -4787,66 +4884,6 @@ const withLineTextMove = (board) => {
|
|
|
4787
4884
|
return board;
|
|
4788
4885
|
};
|
|
4789
4886
|
|
|
4790
|
-
class GroupGenerator extends Generator {
|
|
4791
|
-
canDraw(element) {
|
|
4792
|
-
return true;
|
|
4793
|
-
}
|
|
4794
|
-
draw(element, partialSelected) {
|
|
4795
|
-
const options = {
|
|
4796
|
-
stroke: '',
|
|
4797
|
-
strokeWidth: ACTIVE_STROKE_WIDTH,
|
|
4798
|
-
strokeLineDash: [5]
|
|
4799
|
-
};
|
|
4800
|
-
if (partialSelected) {
|
|
4801
|
-
options.stroke = '#999';
|
|
4802
|
-
}
|
|
4803
|
-
const rectangle = getRectangleByGroup(this.board, element, true);
|
|
4804
|
-
return drawRectangle(this.board, rectangle, options);
|
|
4805
|
-
}
|
|
4806
|
-
}
|
|
4807
|
-
|
|
4808
|
-
class GroupComponent extends CommonPluginElement {
|
|
4809
|
-
constructor(viewContainerRef, cdr) {
|
|
4810
|
-
super(cdr);
|
|
4811
|
-
this.viewContainerRef = viewContainerRef;
|
|
4812
|
-
this.cdr = cdr;
|
|
4813
|
-
}
|
|
4814
|
-
initializeGenerator() {
|
|
4815
|
-
this.activeGenerator = new ActiveGenerator(this.board, {
|
|
4816
|
-
getRectangle: (element) => {
|
|
4817
|
-
return getRectangleByGroup(this.board, element);
|
|
4818
|
-
},
|
|
4819
|
-
getStrokeWidth: () => 0,
|
|
4820
|
-
getStrokeOpacity: () => 0,
|
|
4821
|
-
hasResizeHandle: () => {
|
|
4822
|
-
return !isSelectionMoving(this.board);
|
|
4823
|
-
}
|
|
4824
|
-
});
|
|
4825
|
-
this.groupGenerator = new GroupGenerator(this.board);
|
|
4826
|
-
}
|
|
4827
|
-
ngOnInit() {
|
|
4828
|
-
super.ngOnInit();
|
|
4829
|
-
this.initializeGenerator();
|
|
4830
|
-
}
|
|
4831
|
-
onContextChanged(value, previous) {
|
|
4832
|
-
const elementsInGroup = getElementsInGroup(this.board, value.element, false, true);
|
|
4833
|
-
const isPartialSelectGroup = elementsInGroup.some(item => isSelectedElementOrGroup(this.board, item)) &&
|
|
4834
|
-
!elementsInGroup.every(item => isSelectedElementOrGroup(this.board, item));
|
|
4835
|
-
this.groupGenerator.processDrawing(value.element, this.g, isPartialSelectGroup);
|
|
4836
|
-
}
|
|
4837
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: GroupComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4838
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: GroupComponent, isStandalone: true, selector: "plait-group", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4839
|
-
}
|
|
4840
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: GroupComponent, decorators: [{
|
|
4841
|
-
type: Component,
|
|
4842
|
-
args: [{
|
|
4843
|
-
selector: 'plait-group',
|
|
4844
|
-
template: ``,
|
|
4845
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
4846
|
-
standalone: true
|
|
4847
|
-
}]
|
|
4848
|
-
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }] });
|
|
4849
|
-
|
|
4850
4887
|
const withDraw = (board) => {
|
|
4851
4888
|
const { drawElement, getRectangle, isRectangleHit, isHit, isInsidePoint, isMovable, isAlign, getRelatedFragment } = board;
|
|
4852
4889
|
board.drawElement = (context) => {
|
|
@@ -4859,9 +4896,6 @@ const withDraw = (board) => {
|
|
|
4859
4896
|
else if (PlaitDrawElement.isImage(context.element)) {
|
|
4860
4897
|
return ImageComponent;
|
|
4861
4898
|
}
|
|
4862
|
-
else if (PlaitGroupElement.isGroup(context.element)) {
|
|
4863
|
-
return GroupComponent;
|
|
4864
|
-
}
|
|
4865
4899
|
return drawElement(context);
|
|
4866
4900
|
};
|
|
4867
4901
|
board.getRectangle = (element) => {
|
|
@@ -4880,9 +4914,6 @@ const withDraw = (board) => {
|
|
|
4880
4914
|
if (PlaitDrawElement.isImage(element)) {
|
|
4881
4915
|
return RectangleClient.getRectangleByPoints(element.points);
|
|
4882
4916
|
}
|
|
4883
|
-
if (PlaitGroupElement.isGroup(element)) {
|
|
4884
|
-
return getRectangleByGroup(board, element);
|
|
4885
|
-
}
|
|
4886
4917
|
return getRectangle(element);
|
|
4887
4918
|
};
|
|
4888
4919
|
board.isRectangleHit = (element, selection) => {
|