@plait/draw 0.54.0 → 0.55.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/constants/geometry.d.ts +22 -0
- package/engines/basic-shapes/circle.d.ts +8 -0
- package/engines/basic-shapes/cloud.d.ts +2 -0
- package/engines/flowchart/off-page.d.ts +4 -0
- package/engines/flowchart/or.d.ts +2 -0
- package/engines/flowchart/predefined-process.d.ts +2 -0
- package/engines/flowchart/summing-junction.d.ts +2 -0
- package/esm2022/constants/geometry.mjs +12 -2
- package/esm2022/engines/basic-shapes/circle.mjs +51 -0
- package/esm2022/engines/basic-shapes/cloud.mjs +57 -0
- package/esm2022/engines/basic-shapes/ellipse.mjs +3 -41
- package/esm2022/engines/flowchart/off-page.mjs +32 -0
- package/esm2022/engines/flowchart/or.mjs +25 -0
- package/esm2022/engines/flowchart/predefined-process.mjs +47 -0
- package/esm2022/engines/flowchart/summing-junction.mjs +28 -0
- package/esm2022/engines/index.mjs +12 -2
- package/esm2022/geometry.component.mjs +7 -8
- package/esm2022/image.component.mjs +6 -7
- package/esm2022/interfaces/element.mjs +2 -1
- package/esm2022/interfaces/geometry.mjs +6 -1
- package/esm2022/line.component.mjs +8 -9
- package/esm2022/plugins/with-draw-fragment.mjs +7 -7
- package/esm2022/plugins/with-draw-hotkey.mjs +1 -1
- package/esm2022/plugins/with-draw-resize.mjs +23 -23
- package/esm2022/plugins/with-draw-rotate.mjs +127 -0
- package/esm2022/plugins/with-draw.mjs +3 -2
- package/esm2022/plugins/with-geometry-create.mjs +21 -5
- package/esm2022/plugins/with-geometry-resize.mjs +15 -14
- package/esm2022/plugins/with-line-auto-complete.mjs +4 -3
- package/esm2022/utils/geometry.mjs +5 -2
- package/esm2022/utils/line/line-basic.mjs +6 -3
- package/esm2022/utils/position/geometry.mjs +10 -2
- package/esm2022/utils/snap-resizing.mjs +185 -0
- package/esm2022/utils/style/stroke.mjs +9 -2
- package/fesm2022/plait-draw.mjs +1126 -942
- package/fesm2022/plait-draw.mjs.map +1 -1
- package/geometry.component.d.ts +2 -3
- package/image.component.d.ts +2 -3
- package/interfaces/element.d.ts +2 -1
- package/interfaces/geometry.d.ts +7 -2
- package/line.component.d.ts +2 -3
- package/package.json +1 -1
- package/plugins/with-draw-resize.d.ts +3 -5
- package/plugins/with-draw-rotate.d.ts +2 -0
- package/utils/position/geometry.d.ts +6 -0
- package/utils/snap-resizing.d.ts +25 -0
- package/esm2022/utils/resize-snap.mjs +0 -361
- package/utils/resize-snap.d.ts +0 -49
package/fesm2022/plait-draw.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ACTIVE_STROKE_WIDTH, ThemeColorMode, createDebugGenerator, Point, RectangleClient, getElementById, rotatePointsByElement, createG, arrowPoints, createPath, distanceBetweenPointAndPoint, drawLinearPath, rotate, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, isPolylineHitRectangle, rotateAntiPointsByElement, rotatePoints, depthFirstRecursion, PlaitBoard, getIsRecursionFunc, idCreator, catmullRomFitting, findElements, createMask, createRect, getSelectedElements,
|
|
2
|
-
import { removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, isSourceAndTargetIntersect, getPoints, DEFAULT_ROUTE_MARGIN, getPointByVectorComponent, getExtendPoint, getUnitVectorByPointAndPoint, Generator, RESIZE_HANDLE_DIAMETER, getPointOnPolyline, TRANSPARENT, getRectangleResizeHandleRefs, getRotatedResizeCursorClassByAngle, getMemorizedLatest, memorizeLatest, getCrossingPointsBetweenPointAndSegment, isPointOnSegment, getDirectionByVector, getOppositeDirection, getDirectionFactor, rotateVector, getDirectionByPointOfRectangle, rotateVectorAnti90, getSourceAndTargetOuterRectangle, getNextPoint, normalizeShapePoints, getFirstTextEditor, PRIMARY_COLOR, CommonPluginElement, ActiveGenerator, WithTextPluginKey, drawPrimaryHandle, drawFillPrimaryHandle, isVirtualKey, isDelete, isSpaceHotkey,
|
|
1
|
+
import { ACTIVE_STROKE_WIDTH, ThemeColorMode, createDebugGenerator, Point, RectangleClient, getElementById, rotatePointsByElement, createG, arrowPoints, createPath, distanceBetweenPointAndPoint, drawLinearPath, rotate, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, isPolylineHitRectangle, rotateAntiPointsByElement, rotatePoints, depthFirstRecursion, PlaitBoard, getIsRecursionFunc, idCreator, catmullRomFitting, setStrokeLinecap, findElements, createMask, createRect, getSelectedElements, isPointInPolygon, getNearestPointBetweenPointAndSegments, isPointInEllipse, getEllipseTangentSlope, getVectorFromPointAndSlope, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, setPathStrokeLinecap, getCrossingPointsBetweenEllipseAndSegment, SNAPPING_STROKE_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, Direction, hasValidAngle, Path, PlaitNode, toViewBoxPoint, toHostPoint, isSelectionMoving, RgbaToHEX, PlaitElement, getHitElementByPoint, getRectangleByElements, getSelectionAngle, rotatedDataPoints, isAxisChangedByAngle, getRectangleByAngle, getSnapRectangles, getTripleAxis, getMinPointDelta, SNAP_TOLERANCE, drawPointSnapLines, drawSolidLines, preventTouchMove, createClipboardContext, WritableClipboardType, addClipboardContext, setAngleForG, CursorClass, temporaryDisableSelection, PRESS_AND_MOVE_BUFFER, isMainPointer, throttleRAF, getAngleBetweenPoints, degreesToRadians, normalizeAngle, rotateElements, MERGING, ROTATE_HANDLE_CLASS_NAME, SELECTION_RECTANGLE_CLASS_NAME } from '@plait/core';
|
|
2
|
+
import { removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, isSourceAndTargetIntersect, getPoints, DEFAULT_ROUTE_MARGIN, getPointByVectorComponent, getExtendPoint, getUnitVectorByPointAndPoint, Generator, RESIZE_HANDLE_DIAMETER, getPointOnPolyline, TRANSPARENT, getRectangleResizeHandleRefs, getRotatedResizeCursorClassByAngle, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, getMemorizedLatest, memorizeLatest, getCrossingPointsBetweenPointAndSegment, isPointOnSegment, getDirectionByVector, getOppositeDirection, getDirectionFactor, rotateVector, getDirectionByPointOfRectangle, rotateVectorAnti90, getSourceAndTargetOuterRectangle, getNextPoint, normalizeShapePoints, getFirstTextEditor, PRIMARY_COLOR, CommonPluginElement, ActiveGenerator, WithTextPluginKey, drawPrimaryHandle, drawFillPrimaryHandle, isVirtualKey, isDelete, isSpaceHotkey, isCornerHandle, getIndexByResizeHandle, resetPointsAfterResize, getFirstTextManage, withResize, drawHandle, getSymmetricHandleIndex, getResizeHandlePointByIndex, getDirectionFactorByDirectionComponent, isDndMode, isDrawingMode, getElementsText, acceptImageTypes, getElementOfFocusedImage, buildImage, isResizingByCondition, getRatioByPoint, ImageGenerator, ResizeHandle, addRotating, removeRotating, drawRotateHandle } 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';
|
|
@@ -30,6 +30,7 @@ var BasicShapes;
|
|
|
30
30
|
BasicShapes["twoWayArrow"] = "twoWayArrow";
|
|
31
31
|
BasicShapes["comment"] = "comment";
|
|
32
32
|
BasicShapes["roundComment"] = "roundComment";
|
|
33
|
+
BasicShapes["cloud"] = "cloud";
|
|
33
34
|
})(BasicShapes || (BasicShapes = {}));
|
|
34
35
|
var FlowchartSymbols;
|
|
35
36
|
(function (FlowchartSymbols) {
|
|
@@ -44,6 +45,10 @@ var FlowchartSymbols;
|
|
|
44
45
|
FlowchartSymbols["merge"] = "merge";
|
|
45
46
|
FlowchartSymbols["delay"] = "delay";
|
|
46
47
|
FlowchartSymbols["storedData"] = "storedData";
|
|
48
|
+
FlowchartSymbols["or"] = "or";
|
|
49
|
+
FlowchartSymbols["summingJunction"] = "summingJunction";
|
|
50
|
+
FlowchartSymbols["predefinedProcess"] = "predefinedProcess";
|
|
51
|
+
FlowchartSymbols["offPage"] = "offPage";
|
|
47
52
|
})(FlowchartSymbols || (FlowchartSymbols = {}));
|
|
48
53
|
const PlaitGeometry = {};
|
|
49
54
|
|
|
@@ -66,6 +71,12 @@ const DefaultBasicShapeProperty = {
|
|
|
66
71
|
strokeColor: '#333',
|
|
67
72
|
strokeWidth: 2
|
|
68
73
|
};
|
|
74
|
+
const DefaultCloudShapeProperty = {
|
|
75
|
+
width: 120,
|
|
76
|
+
height: 100,
|
|
77
|
+
strokeColor: '#333',
|
|
78
|
+
strokeWidth: 2
|
|
79
|
+
};
|
|
69
80
|
const DefaultTextProperty = {
|
|
70
81
|
width: 36,
|
|
71
82
|
height: 20,
|
|
@@ -109,7 +120,11 @@ const DefaultFlowchartPropertyMap = {
|
|
|
109
120
|
[FlowchartSymbols.manualLoop]: DefaultFlowchartProperty,
|
|
110
121
|
[FlowchartSymbols.merge]: DefaultMergeProperty,
|
|
111
122
|
[FlowchartSymbols.delay]: DefaultFlowchartProperty,
|
|
112
|
-
[FlowchartSymbols.storedData]: DefaultFlowchartProperty
|
|
123
|
+
[FlowchartSymbols.storedData]: DefaultFlowchartProperty,
|
|
124
|
+
[FlowchartSymbols.or]: DefaultConnectorProperty,
|
|
125
|
+
[FlowchartSymbols.summingJunction]: DefaultConnectorProperty,
|
|
126
|
+
[FlowchartSymbols.predefinedProcess]: DefaultFlowchartProperty,
|
|
127
|
+
[FlowchartSymbols.offPage]: DefaultFlowchartProperty
|
|
113
128
|
};
|
|
114
129
|
const LINE_HIT_GEOMETRY_BUFFER = 10;
|
|
115
130
|
const LINE_SNAPPING_BUFFER = 6;
|
|
@@ -950,6 +965,14 @@ const traverseDrawShapes = (board, callback) => {
|
|
|
950
965
|
}
|
|
951
966
|
}, getIsRecursionFunc(board), true);
|
|
952
967
|
};
|
|
968
|
+
const getRotateHandleRectangle = (rectangle) => {
|
|
969
|
+
return {
|
|
970
|
+
x: rectangle.x - ROTATE_HANDLE_DISTANCE_TO_ELEMENT - ROTATE_HANDLE_SIZE,
|
|
971
|
+
y: rectangle.y + rectangle.height + ROTATE_HANDLE_DISTANCE_TO_ELEMENT,
|
|
972
|
+
width: ROTATE_HANDLE_SIZE,
|
|
973
|
+
height: ROTATE_HANDLE_SIZE
|
|
974
|
+
};
|
|
975
|
+
};
|
|
953
976
|
|
|
954
977
|
const SHAPE_MAX_LENGTH = 6;
|
|
955
978
|
const memorizedShape = new WeakMap();
|
|
@@ -1158,6 +1181,9 @@ const drawLine = (board, element) => {
|
|
|
1158
1181
|
}
|
|
1159
1182
|
const id = idCreator();
|
|
1160
1183
|
line.setAttribute('mask', `url(#${id})`);
|
|
1184
|
+
if (element.strokeStyle === StrokeStyle.dotted) {
|
|
1185
|
+
setStrokeLinecap(line, 'round');
|
|
1186
|
+
}
|
|
1161
1187
|
lineG.appendChild(line);
|
|
1162
1188
|
const { mask, maskTargetFillRect } = drawMask(board, element, id);
|
|
1163
1189
|
lineG.appendChild(mask);
|
|
@@ -1457,44 +1483,55 @@ const DiamondEngine = createPolygonEngine({
|
|
|
1457
1483
|
}
|
|
1458
1484
|
});
|
|
1459
1485
|
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1486
|
+
function createEllipseEngine(createOptions) {
|
|
1487
|
+
const engine = {
|
|
1488
|
+
draw(board, rectangle, options) {
|
|
1489
|
+
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
1490
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
1491
|
+
return rs.ellipse(centerPoint[0], centerPoint[1], rectangle.width, rectangle.height, { ...options, fillStyle: 'solid' });
|
|
1492
|
+
},
|
|
1493
|
+
isInsidePoint(rectangle, point) {
|
|
1494
|
+
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
1495
|
+
return isPointInEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
|
|
1496
|
+
},
|
|
1497
|
+
getCornerPoints(rectangle) {
|
|
1498
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
1499
|
+
},
|
|
1500
|
+
getNearestPoint(rectangle, point) {
|
|
1501
|
+
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
1502
|
+
return getNearestPointBetweenPointAndEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
|
|
1503
|
+
},
|
|
1504
|
+
getTangentVectorByConnectionPoint(rectangle, pointOfRectangle) {
|
|
1505
|
+
const connectionPoint = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
1506
|
+
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
1507
|
+
const point = [connectionPoint[0] - centerPoint[0], -(connectionPoint[1] - centerPoint[1])];
|
|
1508
|
+
const a = rectangle.width / 2;
|
|
1509
|
+
const b = rectangle.height / 2;
|
|
1510
|
+
const slope = getEllipseTangentSlope(point[0], point[1], a, b);
|
|
1511
|
+
const vector = getVectorFromPointAndSlope(point[0], point[1], slope);
|
|
1512
|
+
return vector;
|
|
1513
|
+
},
|
|
1514
|
+
getConnectorPoints(rectangle) {
|
|
1515
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
1516
|
+
},
|
|
1517
|
+
getTextRectangle(element) {
|
|
1518
|
+
const rectangle = getTextRectangle(element);
|
|
1519
|
+
const width = rectangle.width;
|
|
1520
|
+
rectangle.width = (rectangle.width * 3) / 4;
|
|
1521
|
+
rectangle.x += width / 8;
|
|
1522
|
+
return rectangle;
|
|
1523
|
+
}
|
|
1524
|
+
};
|
|
1525
|
+
if (createOptions?.draw) {
|
|
1526
|
+
engine.draw = createOptions.draw;
|
|
1496
1527
|
}
|
|
1497
|
-
|
|
1528
|
+
if (createOptions?.getTextRectangle) {
|
|
1529
|
+
engine.getTextRectangle = createOptions.getTextRectangle;
|
|
1530
|
+
}
|
|
1531
|
+
return engine;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
const EllipseEngine = createEllipseEngine();
|
|
1498
1535
|
function getNearestPointBetweenPointAndEllipse(point, center, rx, ry, rotation = 0) {
|
|
1499
1536
|
const rectangleClient = {
|
|
1500
1537
|
x: center[0] - rx,
|
|
@@ -2282,6 +2319,176 @@ const StoredDataEngine = {
|
|
|
2282
2319
|
}
|
|
2283
2320
|
};
|
|
2284
2321
|
|
|
2322
|
+
const PredefinedProcessEngine = {
|
|
2323
|
+
draw(board, rectangle, options) {
|
|
2324
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
2325
|
+
const shape = rs.path(`M${rectangle.x} ${rectangle.y} H${rectangle.x + rectangle.width} V${rectangle.y + rectangle.height} H${rectangle.x} Z M${rectangle.x + rectangle.width * 0.06} ${rectangle.y} L${rectangle.x + rectangle.width * 0.06} ${rectangle.y +
|
|
2326
|
+
rectangle.height} M${rectangle.x + rectangle.width - rectangle.width * 0.06} ${rectangle.y} L${rectangle.x +
|
|
2327
|
+
rectangle.width -
|
|
2328
|
+
rectangle.width * 0.06} ${rectangle.y + rectangle.height}`, { ...options, fillStyle: 'solid' });
|
|
2329
|
+
setStrokeLinecap(shape, 'round');
|
|
2330
|
+
return shape;
|
|
2331
|
+
},
|
|
2332
|
+
isInsidePoint(rectangle, point) {
|
|
2333
|
+
const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
|
|
2334
|
+
return RectangleClient.isHit(rectangle, rangeRectangle);
|
|
2335
|
+
},
|
|
2336
|
+
getCornerPoints(rectangle) {
|
|
2337
|
+
return RectangleClient.getCornerPoints(rectangle);
|
|
2338
|
+
},
|
|
2339
|
+
getNearestPoint(rectangle, point) {
|
|
2340
|
+
return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
|
|
2341
|
+
},
|
|
2342
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
2343
|
+
const corners = RectangleEngine.getCornerPoints(rectangle);
|
|
2344
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
2345
|
+
return getPolygonEdgeByConnectionPoint(corners, point);
|
|
2346
|
+
},
|
|
2347
|
+
getConnectorPoints(rectangle) {
|
|
2348
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
2349
|
+
},
|
|
2350
|
+
getTextRectangle: (element) => {
|
|
2351
|
+
const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
|
|
2352
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
2353
|
+
const height = element.textHeight;
|
|
2354
|
+
const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2 - elementRectangle.width * 0.06 * 2;
|
|
2355
|
+
return {
|
|
2356
|
+
height,
|
|
2357
|
+
width: width > 0 ? width : 0,
|
|
2358
|
+
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth + elementRectangle.width * 0.06,
|
|
2359
|
+
y: elementRectangle.y + (elementRectangle.height - height) / 2
|
|
2360
|
+
};
|
|
2361
|
+
}
|
|
2362
|
+
};
|
|
2363
|
+
|
|
2364
|
+
const getOffPagePoints = (rectangle) => {
|
|
2365
|
+
return [
|
|
2366
|
+
[rectangle.x, rectangle.y],
|
|
2367
|
+
[rectangle.x + rectangle.width, rectangle.y],
|
|
2368
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2],
|
|
2369
|
+
[rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height],
|
|
2370
|
+
[rectangle.x, rectangle.y + rectangle.height / 2]
|
|
2371
|
+
];
|
|
2372
|
+
};
|
|
2373
|
+
const OffPageEngine = createPolygonEngine({
|
|
2374
|
+
getPolygonPoints: getOffPagePoints,
|
|
2375
|
+
getConnectorPoints: (rectangle) => {
|
|
2376
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
2377
|
+
},
|
|
2378
|
+
getTextRectangle: (element) => {
|
|
2379
|
+
const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
|
|
2380
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
2381
|
+
const height = element.textHeight;
|
|
2382
|
+
const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
|
|
2383
|
+
return {
|
|
2384
|
+
width: width > 0 ? width : 0,
|
|
2385
|
+
height: height,
|
|
2386
|
+
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
|
|
2387
|
+
y: elementRectangle.y + (elementRectangle.height - elementRectangle.height / 2 - height) / 2
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2390
|
+
});
|
|
2391
|
+
|
|
2392
|
+
const CloudEngine = {
|
|
2393
|
+
draw(board, rectangle, options) {
|
|
2394
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
2395
|
+
const divisionWidth = rectangle.width / 7;
|
|
2396
|
+
const divisionHeight = rectangle.height / 3.2;
|
|
2397
|
+
const xRadius = divisionWidth / 8.5;
|
|
2398
|
+
const yRadius = divisionHeight / 20;
|
|
2399
|
+
const svgElement = rs.path(`M ${rectangle.x + divisionWidth} ${rectangle.y + divisionHeight}
|
|
2400
|
+
A ${xRadius} ${yRadius * 1.2} 0 1 1 ${rectangle.x + divisionWidth * 2} ${rectangle.y + divisionHeight / 2}
|
|
2401
|
+
A ${xRadius} ${yRadius} 0 1 1 ${rectangle.x + divisionWidth * 4.2} ${rectangle.y + divisionHeight / 2.2}
|
|
2402
|
+
A ${xRadius} ${yRadius} 0 1 1 ${rectangle.x + divisionWidth * 5.8} ${rectangle.y + divisionHeight}
|
|
2403
|
+
A ${xRadius} ${yRadius * 1.3} 0 1 1 ${rectangle.x + divisionWidth * 6} ${rectangle.y + divisionHeight * 2.2}
|
|
2404
|
+
A ${xRadius} ${yRadius * 1.2} 0 1 1 ${rectangle.x + divisionWidth * 5} ${rectangle.y + divisionHeight * 2.8}
|
|
2405
|
+
A ${xRadius} ${yRadius / 1.2} 0 1 1 ${rectangle.x + divisionWidth * 2.8} ${rectangle.y + divisionHeight * 2.8}
|
|
2406
|
+
A ${xRadius} ${yRadius} 0 1 1 ${rectangle.x + divisionWidth} ${rectangle.y + divisionHeight * 2.2}
|
|
2407
|
+
A ${xRadius} ${yRadius * 1.42} 0 1 1 ${rectangle.x + divisionWidth} ${rectangle.y + divisionHeight}
|
|
2408
|
+
Z`, { ...options, fillStyle: 'solid' });
|
|
2409
|
+
setPathStrokeLinecap(svgElement, 'round');
|
|
2410
|
+
return svgElement;
|
|
2411
|
+
},
|
|
2412
|
+
isInsidePoint(rectangle, point) {
|
|
2413
|
+
const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
|
|
2414
|
+
return RectangleClient.isHit(rectangle, rangeRectangle);
|
|
2415
|
+
},
|
|
2416
|
+
getCornerPoints(rectangle) {
|
|
2417
|
+
return RectangleClient.getCornerPoints(rectangle);
|
|
2418
|
+
},
|
|
2419
|
+
getNearestPoint(rectangle, point) {
|
|
2420
|
+
return getNearestPointBetweenPointAndSegments(point, CloudEngine.getCornerPoints(rectangle));
|
|
2421
|
+
},
|
|
2422
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
2423
|
+
const corners = CloudEngine.getCornerPoints(rectangle);
|
|
2424
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
2425
|
+
return getPolygonEdgeByConnectionPoint(corners, point);
|
|
2426
|
+
},
|
|
2427
|
+
getConnectorPoints(rectangle) {
|
|
2428
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
2429
|
+
},
|
|
2430
|
+
getTextRectangle(element) {
|
|
2431
|
+
const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
|
|
2432
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
2433
|
+
const height = element.textHeight;
|
|
2434
|
+
const originWidth = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
|
|
2435
|
+
const width = originWidth / 1.5;
|
|
2436
|
+
return {
|
|
2437
|
+
height,
|
|
2438
|
+
width: width > 0 ? width : 0,
|
|
2439
|
+
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth + originWidth / 6,
|
|
2440
|
+
y: elementRectangle.y + elementRectangle.height / 6 + ((elementRectangle.height * 4) / 6 - height) / 2
|
|
2441
|
+
};
|
|
2442
|
+
}
|
|
2443
|
+
};
|
|
2444
|
+
|
|
2445
|
+
const OrEngine = createEllipseEngine({
|
|
2446
|
+
draw(board, rectangle, options) {
|
|
2447
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
2448
|
+
const rx = rectangle.width / 2;
|
|
2449
|
+
const ry = rectangle.height / 2;
|
|
2450
|
+
const startPoint = [rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2];
|
|
2451
|
+
return rs.path(`M${startPoint[0]} ${startPoint[1]}
|
|
2452
|
+
A${rx},${ry} 0 1,1 ${startPoint[0]} ${startPoint[1] - 0.01}
|
|
2453
|
+
M${rectangle.x} ${rectangle.y + rectangle.height / 2}
|
|
2454
|
+
L${rectangle.x + rectangle.width} ${rectangle.y + rectangle.height / 2}
|
|
2455
|
+
M${rectangle.x + rectangle.width / 2} ${rectangle.y}
|
|
2456
|
+
L${rectangle.x + rectangle.width / 2} ${rectangle.y + rectangle.height}
|
|
2457
|
+
`, { ...options, fillStyle: 'solid' });
|
|
2458
|
+
},
|
|
2459
|
+
getTextRectangle(element) {
|
|
2460
|
+
const rectangle = getTextRectangle(element);
|
|
2461
|
+
rectangle.width = 0;
|
|
2462
|
+
rectangle.height = 0;
|
|
2463
|
+
return rectangle;
|
|
2464
|
+
}
|
|
2465
|
+
});
|
|
2466
|
+
|
|
2467
|
+
const SummingJunctionEngine = createEllipseEngine({
|
|
2468
|
+
draw(board, rectangle, options) {
|
|
2469
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
2470
|
+
const rx = rectangle.width / 2;
|
|
2471
|
+
const ry = rectangle.height / 2;
|
|
2472
|
+
const startPoint = [rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2];
|
|
2473
|
+
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
2474
|
+
const line1Points = getCrossingPointsBetweenEllipseAndSegment([rectangle.x, rectangle.y], [rectangle.x + rectangle.width, rectangle.y + rectangle.height], centerPoint[0], centerPoint[1], rx, ry);
|
|
2475
|
+
const line2Points = getCrossingPointsBetweenEllipseAndSegment([rectangle.x + rectangle.width, rectangle.y], [rectangle.x, rectangle.y + rectangle.height], centerPoint[0], centerPoint[1], rx, ry);
|
|
2476
|
+
return rs.path(`M${startPoint[0]} ${startPoint[1]}
|
|
2477
|
+
A${rx},${ry} 0 1,1 ${startPoint[0]} ${startPoint[1] - 0.01}
|
|
2478
|
+
M${line1Points[0][0]} ${line1Points[0][1]}
|
|
2479
|
+
L${line1Points[1][0]} ${line1Points[1][1]}
|
|
2480
|
+
M${line2Points[0][0]} ${line2Points[0][1]}
|
|
2481
|
+
L${line2Points[1][0]} ${line2Points[1][1]}
|
|
2482
|
+
`, { ...options, fillStyle: 'solid' });
|
|
2483
|
+
},
|
|
2484
|
+
getTextRectangle(element) {
|
|
2485
|
+
const rectangle = getTextRectangle(element);
|
|
2486
|
+
rectangle.width = 0;
|
|
2487
|
+
rectangle.height = 0;
|
|
2488
|
+
return rectangle;
|
|
2489
|
+
}
|
|
2490
|
+
});
|
|
2491
|
+
|
|
2285
2492
|
const ShapeEngineMap = {
|
|
2286
2493
|
[BasicShapes.rectangle]: RectangleEngine,
|
|
2287
2494
|
[BasicShapes.diamond]: DiamondEngine,
|
|
@@ -2303,6 +2510,7 @@ const ShapeEngineMap = {
|
|
|
2303
2510
|
[BasicShapes.twoWayArrow]: TwoWayArrowEngine,
|
|
2304
2511
|
[BasicShapes.comment]: CommentEngine,
|
|
2305
2512
|
[BasicShapes.roundComment]: RoundCommentEngine,
|
|
2513
|
+
[BasicShapes.cloud]: CloudEngine,
|
|
2306
2514
|
[FlowchartSymbols.process]: RectangleEngine,
|
|
2307
2515
|
[FlowchartSymbols.decision]: DiamondEngine,
|
|
2308
2516
|
[FlowchartSymbols.connector]: EllipseEngine,
|
|
@@ -2313,7 +2521,11 @@ const ShapeEngineMap = {
|
|
|
2313
2521
|
[FlowchartSymbols.manualLoop]: ManualLoopEngine,
|
|
2314
2522
|
[FlowchartSymbols.merge]: MergeEngine,
|
|
2315
2523
|
[FlowchartSymbols.delay]: DelayEngine,
|
|
2316
|
-
[FlowchartSymbols.storedData]: StoredDataEngine
|
|
2524
|
+
[FlowchartSymbols.storedData]: StoredDataEngine,
|
|
2525
|
+
[FlowchartSymbols.or]: OrEngine,
|
|
2526
|
+
[FlowchartSymbols.summingJunction]: SummingJunctionEngine,
|
|
2527
|
+
[FlowchartSymbols.predefinedProcess]: PredefinedProcessEngine,
|
|
2528
|
+
[FlowchartSymbols.offPage]: OffPageEngine
|
|
2317
2529
|
};
|
|
2318
2530
|
const getEngine = (shape) => {
|
|
2319
2531
|
return ShapeEngineMap[shape];
|
|
@@ -2502,6 +2714,9 @@ const getDefaultGeometryProperty = (pointer) => {
|
|
|
2502
2714
|
return getDefaultFlowchartProperty(pointer);
|
|
2503
2715
|
}
|
|
2504
2716
|
else {
|
|
2717
|
+
if (pointer === BasicShapes.cloud) {
|
|
2718
|
+
return DefaultCloudShapeProperty;
|
|
2719
|
+
}
|
|
2505
2720
|
return DefaultBasicShapeProperty;
|
|
2506
2721
|
}
|
|
2507
2722
|
};
|
|
@@ -2553,7 +2768,14 @@ const getFillByElement = (board, element) => {
|
|
|
2553
2768
|
return fill;
|
|
2554
2769
|
};
|
|
2555
2770
|
const getLineDashByElement = (element) => {
|
|
2556
|
-
|
|
2771
|
+
switch (element.strokeStyle) {
|
|
2772
|
+
case StrokeStyle.dashed:
|
|
2773
|
+
return [8, 8 + getStrokeWidthByElement(element)];
|
|
2774
|
+
case StrokeStyle.dotted:
|
|
2775
|
+
return [0, 4 + getStrokeWidthByElement(element)];
|
|
2776
|
+
default:
|
|
2777
|
+
return undefined;
|
|
2778
|
+
}
|
|
2557
2779
|
};
|
|
2558
2780
|
const getStrokeStyleByElement = (element) => {
|
|
2559
2781
|
return element.strokeStyle || StrokeStyle.solid;
|
|
@@ -2747,6 +2969,7 @@ var StrokeStyle;
|
|
|
2747
2969
|
(function (StrokeStyle) {
|
|
2748
2970
|
StrokeStyle["solid"] = "solid";
|
|
2749
2971
|
StrokeStyle["dashed"] = "dashed";
|
|
2972
|
+
StrokeStyle["dotted"] = "dotted";
|
|
2750
2973
|
})(StrokeStyle || (StrokeStyle = {}));
|
|
2751
2974
|
var MemorizeKey;
|
|
2752
2975
|
(function (MemorizeKey) {
|
|
@@ -3095,9 +3318,8 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
3095
3318
|
get textManage() {
|
|
3096
3319
|
return this.getTextManages()[0];
|
|
3097
3320
|
}
|
|
3098
|
-
constructor(
|
|
3321
|
+
constructor(cdr) {
|
|
3099
3322
|
super(cdr);
|
|
3100
|
-
this.viewContainerRef = viewContainerRef;
|
|
3101
3323
|
this.cdr = cdr;
|
|
3102
3324
|
this.destroy$ = new Subject();
|
|
3103
3325
|
}
|
|
@@ -3139,7 +3361,7 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
3139
3361
|
ngOnInit() {
|
|
3140
3362
|
super.ngOnInit();
|
|
3141
3363
|
this.initializeGenerator();
|
|
3142
|
-
this.shapeGenerator.processDrawing(this.element, this.
|
|
3364
|
+
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
3143
3365
|
this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
|
|
3144
3366
|
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
|
|
3145
3367
|
selected: this.selected
|
|
@@ -3149,7 +3371,7 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
3149
3371
|
onContextChanged(value, previous) {
|
|
3150
3372
|
const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
|
|
3151
3373
|
if (value.element !== previous.element || isChangeTheme) {
|
|
3152
|
-
this.shapeGenerator.processDrawing(this.element, this.
|
|
3374
|
+
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
3153
3375
|
this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
|
|
3154
3376
|
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
|
|
3155
3377
|
selected: this.selected
|
|
@@ -3173,7 +3395,7 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
3173
3395
|
}
|
|
3174
3396
|
drawText() {
|
|
3175
3397
|
this.textManage.draw(this.element.text);
|
|
3176
|
-
this.
|
|
3398
|
+
this.getElementG().append(this.textManage.g);
|
|
3177
3399
|
const centerPoint = RectangleClient.getCenterPoint(this.board.getRectangle(this.element));
|
|
3178
3400
|
this.textManage.updateAngle(centerPoint, this.element.angle);
|
|
3179
3401
|
}
|
|
@@ -3224,7 +3446,7 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
3224
3446
|
this.activeGenerator.destroy();
|
|
3225
3447
|
this.lineAutoCompleteGenerator.destroy();
|
|
3226
3448
|
}
|
|
3227
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: GeometryComponent, deps: [{ token: i0.
|
|
3449
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: GeometryComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3228
3450
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: GeometryComponent, isStandalone: true, selector: "plait-draw-geometry", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3229
3451
|
}
|
|
3230
3452
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: GeometryComponent, decorators: [{
|
|
@@ -3235,7 +3457,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImpor
|
|
|
3235
3457
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3236
3458
|
standalone: true
|
|
3237
3459
|
}]
|
|
3238
|
-
}], ctorParameters: () => [{ type: i0.
|
|
3460
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
3239
3461
|
|
|
3240
3462
|
class LineActiveGenerator extends Generator {
|
|
3241
3463
|
constructor() {
|
|
@@ -3311,9 +3533,8 @@ class LineActiveGenerator extends Generator {
|
|
|
3311
3533
|
const debugKey$2 = 'debug:plait:line-turning';
|
|
3312
3534
|
const debugGenerator$2 = createDebugGenerator(debugKey$2);
|
|
3313
3535
|
class LineComponent extends CommonPluginElement {
|
|
3314
|
-
constructor(
|
|
3536
|
+
constructor(cdr) {
|
|
3315
3537
|
super(cdr);
|
|
3316
|
-
this.viewContainerRef = viewContainerRef;
|
|
3317
3538
|
this.cdr = cdr;
|
|
3318
3539
|
this.destroy$ = new Subject();
|
|
3319
3540
|
this.boundedElements = {};
|
|
@@ -3325,7 +3546,7 @@ class LineComponent extends CommonPluginElement {
|
|
|
3325
3546
|
}
|
|
3326
3547
|
ngOnInit() {
|
|
3327
3548
|
this.initializeGenerator();
|
|
3328
|
-
this.shapeGenerator.processDrawing(this.element, this.
|
|
3549
|
+
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
3329
3550
|
const linePoints = getLinePoints(this.board, this.element);
|
|
3330
3551
|
this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
|
|
3331
3552
|
selected: this.selected,
|
|
@@ -3359,7 +3580,7 @@ class LineComponent extends CommonPluginElement {
|
|
|
3359
3580
|
const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
|
|
3360
3581
|
const linePoints = getLinePoints(this.board, this.element);
|
|
3361
3582
|
if (value.element !== previous.element || isChangeTheme) {
|
|
3362
|
-
this.shapeGenerator.processDrawing(this.element, this.
|
|
3583
|
+
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
3363
3584
|
this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
|
|
3364
3585
|
selected: this.selected,
|
|
3365
3586
|
linePoints
|
|
@@ -3377,7 +3598,7 @@ class LineComponent extends CommonPluginElement {
|
|
|
3377
3598
|
}
|
|
3378
3599
|
}
|
|
3379
3600
|
if (isBoundedElementsChanged) {
|
|
3380
|
-
this.shapeGenerator.processDrawing(this.element, this.
|
|
3601
|
+
this.shapeGenerator.processDrawing(this.element, this.getElementG());
|
|
3381
3602
|
this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
|
|
3382
3603
|
selected: this.selected,
|
|
3383
3604
|
linePoints
|
|
@@ -3400,7 +3621,7 @@ class LineComponent extends CommonPluginElement {
|
|
|
3400
3621
|
if (this.element.texts?.length) {
|
|
3401
3622
|
this.getTextManages().forEach((manage, index) => {
|
|
3402
3623
|
manage.draw(this.element.texts[index].text);
|
|
3403
|
-
this.
|
|
3624
|
+
this.getElementG().append(manage.g);
|
|
3404
3625
|
});
|
|
3405
3626
|
}
|
|
3406
3627
|
}
|
|
@@ -3457,7 +3678,7 @@ class LineComponent extends CommonPluginElement {
|
|
|
3457
3678
|
this.destroy$.complete();
|
|
3458
3679
|
this.destroyTextManages();
|
|
3459
3680
|
}
|
|
3460
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: LineComponent, deps: [{ token: i0.
|
|
3681
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: LineComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3461
3682
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: LineComponent, isStandalone: true, selector: "plait-draw-line", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3462
3683
|
}
|
|
3463
3684
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: LineComponent, decorators: [{
|
|
@@ -3468,7 +3689,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImpor
|
|
|
3468
3689
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3469
3690
|
standalone: true
|
|
3470
3691
|
}]
|
|
3471
|
-
}], ctorParameters: () => [{ type: i0.
|
|
3692
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
3472
3693
|
|
|
3473
3694
|
const withDrawHotkey = (board) => {
|
|
3474
3695
|
const { keyDown, dblClick } = board;
|
|
@@ -3503,583 +3724,388 @@ const withDrawHotkey = (board) => {
|
|
|
3503
3724
|
return board;
|
|
3504
3725
|
};
|
|
3505
3726
|
|
|
3506
|
-
const
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
let
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
const
|
|
3516
|
-
|
|
3517
|
-
const dragMode = isGeometryPointer && isDndMode(board);
|
|
3518
|
-
const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
3519
|
-
const pointer = PlaitBoard.getPointer(board);
|
|
3520
|
-
if (dragMode) {
|
|
3521
|
-
const memorizedLatest = getMemorizedLatestByPointer(pointer);
|
|
3522
|
-
if (pointer === BasicShapes.text) {
|
|
3523
|
-
const property = getTextShapeProperty(board, DefaultTextProperty.text, memorizedLatest.textProperties['font-size']);
|
|
3524
|
-
const points = RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(movingPoint, property.width, property.height));
|
|
3525
|
-
temporaryElement = createTextElement(board, points);
|
|
3526
|
-
if (!fakeCreateTextRef) {
|
|
3527
|
-
const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, {
|
|
3528
|
-
getRectangle: () => {
|
|
3529
|
-
return getTextRectangle(temporaryElement);
|
|
3530
|
-
}
|
|
3531
|
-
});
|
|
3532
|
-
PlaitBoard.getComponent(board)
|
|
3533
|
-
.viewContainerRef.injector.get(NgZone)
|
|
3534
|
-
.run(() => {
|
|
3535
|
-
textManage.draw(temporaryElement.text);
|
|
3536
|
-
});
|
|
3537
|
-
fakeCreateTextRef = {
|
|
3538
|
-
g: createG(),
|
|
3539
|
-
textManage
|
|
3540
|
-
};
|
|
3541
|
-
PlaitBoard.getHost(board).append(fakeCreateTextRef.g);
|
|
3542
|
-
fakeCreateTextRef.g.append(textManage.g);
|
|
3543
|
-
}
|
|
3544
|
-
else {
|
|
3545
|
-
fakeCreateTextRef.textManage.updateRectangle();
|
|
3546
|
-
fakeCreateTextRef.g.append(fakeCreateTextRef.textManage.g);
|
|
3547
|
-
}
|
|
3548
|
-
}
|
|
3549
|
-
else {
|
|
3550
|
-
const points = getDefaultGeometryPoints(pointer, movingPoint);
|
|
3551
|
-
temporaryElement = createDefaultGeometry(board, points, pointer);
|
|
3552
|
-
geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
|
|
3553
|
-
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
3554
|
-
}
|
|
3555
|
-
}
|
|
3556
|
-
pointerMove(event);
|
|
3557
|
-
};
|
|
3558
|
-
board.globalPointerUp = (event) => {
|
|
3559
|
-
const geometryPointers = getGeometryPointers();
|
|
3560
|
-
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
3561
|
-
const dragMode = isGeometryPointer && isDndMode(board);
|
|
3562
|
-
if (dragMode && temporaryElement) {
|
|
3563
|
-
insertElement(board, temporaryElement);
|
|
3564
|
-
fakeCreateTextRef?.textManage.destroy();
|
|
3565
|
-
fakeCreateTextRef?.g.remove();
|
|
3566
|
-
fakeCreateTextRef = null;
|
|
3567
|
-
}
|
|
3568
|
-
geometryShapeG?.remove();
|
|
3569
|
-
geometryShapeG = null;
|
|
3570
|
-
preventTouchMove(board, event, false);
|
|
3571
|
-
globalPointerUp(event);
|
|
3727
|
+
const debugKey$1 = 'debug:plait:resize-for-rotation';
|
|
3728
|
+
const debugGenerator$1 = createDebugGenerator(debugKey$1);
|
|
3729
|
+
function withDrawResize(board) {
|
|
3730
|
+
const { afterChange, drawActiveRectangle } = board;
|
|
3731
|
+
let snapG;
|
|
3732
|
+
let handleG;
|
|
3733
|
+
let needCustomActiveRectangle = false;
|
|
3734
|
+
let resizeActivePoints = null;
|
|
3735
|
+
const canResize = () => {
|
|
3736
|
+
const elements = getSelectedElements(board);
|
|
3737
|
+
return elements.length > 1 && elements.every(el => PlaitDrawElement.isDrawElement(el));
|
|
3572
3738
|
};
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
const
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3739
|
+
const options = {
|
|
3740
|
+
key: 'draw-elements',
|
|
3741
|
+
canResize,
|
|
3742
|
+
hitTest: (point) => {
|
|
3743
|
+
const elements = getSelectedElements(board);
|
|
3744
|
+
const boundingRectangle = getRectangleByElements(board, elements, false);
|
|
3745
|
+
const angle = getSelectionAngle(elements);
|
|
3746
|
+
const handleRef = getHitRectangleResizeHandleRef(board, boundingRectangle, point, angle);
|
|
3747
|
+
if (handleRef) {
|
|
3748
|
+
return {
|
|
3749
|
+
element: elements,
|
|
3750
|
+
rectangle: boundingRectangle,
|
|
3751
|
+
handle: handleRef.handle,
|
|
3752
|
+
cursorClass: handleRef.cursorClass
|
|
3753
|
+
};
|
|
3754
|
+
}
|
|
3755
|
+
return null;
|
|
3756
|
+
},
|
|
3757
|
+
onResize: (resizeRef, resizeState) => {
|
|
3758
|
+
snapG?.remove();
|
|
3759
|
+
debugGenerator$1.isDebug() && debugGenerator$1.clear();
|
|
3760
|
+
const isFromCorner = isCornerHandle(board, resizeRef.handle);
|
|
3761
|
+
const isAspectRatio = resizeState.isShift || isFromCorner;
|
|
3762
|
+
const centerPoint = RectangleClient.getCenterPoint(resizeRef.rectangle);
|
|
3763
|
+
const handleIndex = getIndexByResizeHandle(resizeRef.handle);
|
|
3764
|
+
const { originPoint, handlePoint } = getResizeOriginPointAndHandlePoint(board, handleIndex, resizeRef.rectangle);
|
|
3765
|
+
const angle = getSelectionAngle(resizeRef.element);
|
|
3766
|
+
let bulkRotationRef;
|
|
3767
|
+
if (angle) {
|
|
3768
|
+
bulkRotationRef = {
|
|
3769
|
+
angle: angle,
|
|
3770
|
+
offsetX: 0,
|
|
3771
|
+
offsetY: 0,
|
|
3772
|
+
newCenterPoint: [0, 0]
|
|
3773
|
+
};
|
|
3774
|
+
const [rotatedStartPoint, rotateEndPoint] = rotatePoints([resizeState.startPoint, resizeState.endPoint], centerPoint, -bulkRotationRef.angle);
|
|
3775
|
+
resizeState.startPoint = rotatedStartPoint;
|
|
3776
|
+
resizeState.endPoint = rotateEndPoint;
|
|
3777
|
+
}
|
|
3778
|
+
const resizeSnapRefOptions = getSnapResizingRefOptions(board, resizeRef, resizeState, {
|
|
3779
|
+
originPoint,
|
|
3780
|
+
handlePoint
|
|
3781
|
+
}, isAspectRatio, isFromCorner);
|
|
3782
|
+
const resizeSnapRef = getSnapResizingRef(board, resizeRef.element, resizeSnapRefOptions);
|
|
3783
|
+
resizeActivePoints = resizeSnapRef.activePoints;
|
|
3784
|
+
snapG = resizeSnapRef.snapG;
|
|
3785
|
+
PlaitBoard.getElementActiveHost(board).append(snapG);
|
|
3786
|
+
if (bulkRotationRef) {
|
|
3787
|
+
const boundingBoxCornerPoints = RectangleClient.getPoints(resizeRef.rectangle);
|
|
3788
|
+
const resizedBoundingBoxCornerPoints = boundingBoxCornerPoints.map(p => {
|
|
3789
|
+
return movePointByZoomAndOriginPoint(p, originPoint, resizeSnapRef.xZoom, resizeSnapRef.yZoom);
|
|
3790
|
+
});
|
|
3791
|
+
const newBoundingBox = RectangleClient.getRectangleByPoints(resizedBoundingBoxCornerPoints);
|
|
3792
|
+
debugGenerator$1.isDebug() && debugGenerator$1.drawRectangle(board, newBoundingBox, { stroke: 'blue' });
|
|
3793
|
+
const newBoundingBoxCenter = RectangleClient.getCenterPoint(newBoundingBox);
|
|
3794
|
+
const adjustedNewBoundingBoxPoints = resetPointsAfterResize(RectangleClient.getRectangleByPoints(boundingBoxCornerPoints), RectangleClient.getRectangleByPoints(resizedBoundingBoxCornerPoints), centerPoint, newBoundingBoxCenter, bulkRotationRef.angle);
|
|
3795
|
+
const newCenter = RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(adjustedNewBoundingBoxPoints));
|
|
3796
|
+
bulkRotationRef = Object.assign(bulkRotationRef, {
|
|
3797
|
+
offsetX: newCenter[0] - newBoundingBoxCenter[0],
|
|
3798
|
+
offsetY: newCenter[1] - newBoundingBoxCenter[1],
|
|
3799
|
+
newCenterPoint: newCenter
|
|
3800
|
+
});
|
|
3801
|
+
debugGenerator$1.isDebug() && debugGenerator$1.drawRectangle(board, adjustedNewBoundingBoxPoints);
|
|
3802
|
+
}
|
|
3803
|
+
resizeRef.element.forEach(target => {
|
|
3804
|
+
const path = PlaitBoard.findPath(board, target);
|
|
3805
|
+
let points;
|
|
3806
|
+
if (bulkRotationRef) {
|
|
3807
|
+
const reversedPoints = rotatedDataPoints(target.points, centerPoint, -bulkRotationRef.angle);
|
|
3808
|
+
points = reversedPoints.map((p) => {
|
|
3809
|
+
return movePointByZoomAndOriginPoint(p, originPoint, resizeSnapRef.xZoom, resizeSnapRef.yZoom);
|
|
3810
|
+
});
|
|
3811
|
+
const adjustTargetPoints = points.map(p => [
|
|
3812
|
+
p[0] + bulkRotationRef.offsetX,
|
|
3813
|
+
p[1] + bulkRotationRef.offsetY
|
|
3814
|
+
]);
|
|
3815
|
+
points = rotatedDataPoints(adjustTargetPoints, bulkRotationRef.newCenterPoint, bulkRotationRef.angle);
|
|
3816
|
+
}
|
|
3817
|
+
else {
|
|
3818
|
+
if (hasValidAngle(target)) {
|
|
3819
|
+
needCustomActiveRectangle = true;
|
|
3820
|
+
}
|
|
3821
|
+
if (hasValidAngle(target) && isAxisChangedByAngle(target.angle)) {
|
|
3822
|
+
points = getResizePointsByOtherwiseAxis(board, target.points, originPoint, resizeSnapRef.xZoom, resizeSnapRef.yZoom);
|
|
3823
|
+
}
|
|
3824
|
+
else {
|
|
3825
|
+
points = target.points.map(p => {
|
|
3826
|
+
return movePointByZoomAndOriginPoint(p, originPoint, resizeSnapRef.xZoom, resizeSnapRef.yZoom);
|
|
3827
|
+
});
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
if (PlaitDrawElement.isGeometry(target)) {
|
|
3831
|
+
const { height: textHeight } = getFirstTextManage(target).getSize();
|
|
3832
|
+
DrawTransforms.resizeGeometry(board, points, textHeight, path);
|
|
3833
|
+
}
|
|
3834
|
+
else if (PlaitDrawElement.isLine(target)) {
|
|
3835
|
+
Transforms.setNode(board, { points }, path);
|
|
3836
|
+
}
|
|
3837
|
+
else if (PlaitDrawElement.isImage(target)) {
|
|
3838
|
+
if (isAspectRatio) {
|
|
3839
|
+
Transforms.setNode(board, { points }, path);
|
|
3840
|
+
}
|
|
3841
|
+
else {
|
|
3842
|
+
// The image element does not follow the resize, but moves based on the center point.
|
|
3843
|
+
const targetRectangle = RectangleClient.getRectangleByPoints(target.points);
|
|
3844
|
+
const centerPoint = RectangleClient.getCenterPoint(targetRectangle);
|
|
3845
|
+
const newCenterPoint = movePointByZoomAndOriginPoint(centerPoint, originPoint, resizeSnapRef.xZoom, resizeSnapRef.yZoom);
|
|
3846
|
+
const newTargetRectangle = RectangleClient.getRectangleByCenterPoint(newCenterPoint, targetRectangle.width, targetRectangle.height);
|
|
3847
|
+
Transforms.setNode(board, { points: RectangleClient.getPoints(newTargetRectangle) }, path);
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
});
|
|
3851
|
+
},
|
|
3852
|
+
afterResize: (resizeRef) => {
|
|
3853
|
+
snapG?.remove();
|
|
3854
|
+
snapG = null;
|
|
3855
|
+
if (needCustomActiveRectangle) {
|
|
3856
|
+
needCustomActiveRectangle = false;
|
|
3857
|
+
resizeActivePoints = null;
|
|
3858
|
+
const selectedElements = getSelectedElements(board);
|
|
3859
|
+
Transforms.addSelectionWithTemporaryElements(board, selectedElements);
|
|
3604
3860
|
}
|
|
3605
3861
|
}
|
|
3606
|
-
pointerDown(event);
|
|
3607
3862
|
};
|
|
3608
|
-
board
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
const pointer = PlaitBoard.getPointer(board);
|
|
3615
|
-
if (drawMode && pointer !== BasicShapes.text) {
|
|
3616
|
-
const points = normalizeShapePoints([start, movingPoint], isShift);
|
|
3617
|
-
temporaryElement = createDefaultGeometry(board, points, pointer);
|
|
3618
|
-
geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
|
|
3619
|
-
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
3863
|
+
withResize(board, options);
|
|
3864
|
+
board.afterChange = () => {
|
|
3865
|
+
afterChange();
|
|
3866
|
+
if (handleG) {
|
|
3867
|
+
handleG.remove();
|
|
3868
|
+
handleG = null;
|
|
3620
3869
|
}
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
temporaryElement = createDefaultGeometry(board, points, pointer);
|
|
3633
|
-
}
|
|
3870
|
+
if (canResize() && !isSelectionMoving(board)) {
|
|
3871
|
+
handleG = createG();
|
|
3872
|
+
const elements = getSelectedElements(board);
|
|
3873
|
+
const boundingRectangle = needCustomActiveRectangle
|
|
3874
|
+
? RectangleClient.getRectangleByPoints(resizeActivePoints)
|
|
3875
|
+
: getRectangleByElements(board, elements, false);
|
|
3876
|
+
let corners = RectangleClient.getCornerPoints(boundingRectangle);
|
|
3877
|
+
const angle = getSelectionAngle(elements);
|
|
3878
|
+
if (angle) {
|
|
3879
|
+
const centerPoint = RectangleClient.getCenterPoint(boundingRectangle);
|
|
3880
|
+
corners = rotatePoints(corners, centerPoint, angle);
|
|
3634
3881
|
}
|
|
3882
|
+
corners.forEach(corner => {
|
|
3883
|
+
const g = drawHandle(board, corner);
|
|
3884
|
+
handleG && handleG.append(g);
|
|
3885
|
+
});
|
|
3886
|
+
PlaitBoard.getElementActiveHost(board).append(handleG);
|
|
3635
3887
|
}
|
|
3636
|
-
|
|
3637
|
-
|
|
3888
|
+
};
|
|
3889
|
+
board.drawActiveRectangle = () => {
|
|
3890
|
+
if (needCustomActiveRectangle) {
|
|
3891
|
+
const rectangle = RectangleClient.getRectangleByPoints(resizeActivePoints);
|
|
3892
|
+
return drawRectangle(board, RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH), {
|
|
3893
|
+
stroke: SELECTION_BORDER_COLOR,
|
|
3894
|
+
strokeWidth: ACTIVE_STROKE_WIDTH
|
|
3895
|
+
});
|
|
3638
3896
|
}
|
|
3639
|
-
|
|
3640
|
-
geometryShapeG = null;
|
|
3641
|
-
start = null;
|
|
3642
|
-
temporaryElement = null;
|
|
3643
|
-
preventTouchMove(board, event, false);
|
|
3644
|
-
pointerUp(event);
|
|
3897
|
+
return drawActiveRectangle();
|
|
3645
3898
|
};
|
|
3646
3899
|
return board;
|
|
3900
|
+
}
|
|
3901
|
+
const getResizeOriginPointAndHandlePoint = (board, handleIndex, rectangle) => {
|
|
3902
|
+
const symmetricHandleIndex = getSymmetricHandleIndex(board, handleIndex);
|
|
3903
|
+
const originPoint = getResizeHandlePointByIndex(rectangle, symmetricHandleIndex);
|
|
3904
|
+
const handlePoint = getResizeHandlePointByIndex(rectangle, handleIndex);
|
|
3905
|
+
return {
|
|
3906
|
+
originPoint,
|
|
3907
|
+
handlePoint
|
|
3908
|
+
};
|
|
3647
3909
|
};
|
|
3648
|
-
|
|
3649
|
-
const
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3910
|
+
const getResizeZoom = (resizeStartAndEnd, resizeOriginPoint, resizeHandlePoint, isFromCorner, isAspectRatio) => {
|
|
3911
|
+
const [startPoint, endPoint] = resizeStartAndEnd;
|
|
3912
|
+
let xZoom = 0;
|
|
3913
|
+
let yZoom = 0;
|
|
3914
|
+
if (isFromCorner) {
|
|
3915
|
+
if (isAspectRatio) {
|
|
3916
|
+
let normalizedOffsetX = Point.getOffsetX(startPoint, endPoint);
|
|
3917
|
+
xZoom = normalizedOffsetX / (resizeHandlePoint[0] - resizeOriginPoint[0]);
|
|
3918
|
+
yZoom = xZoom;
|
|
3654
3919
|
}
|
|
3655
|
-
|
|
3656
|
-
let
|
|
3657
|
-
let
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3920
|
+
else {
|
|
3921
|
+
let normalizedOffsetX = Point.getOffsetX(startPoint, endPoint);
|
|
3922
|
+
let normalizedOffsetY = Point.getOffsetY(startPoint, endPoint);
|
|
3923
|
+
xZoom = normalizedOffsetX / (resizeHandlePoint[0] - resizeOriginPoint[0]);
|
|
3924
|
+
yZoom = normalizedOffsetY / (resizeHandlePoint[1] - resizeOriginPoint[1]);
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
else {
|
|
3928
|
+
const isHorizontal = Point.isHorizontal(resizeOriginPoint, resizeHandlePoint, 0.1) || false;
|
|
3929
|
+
let normalizedOffset = isHorizontal ? Point.getOffsetX(startPoint, endPoint) : Point.getOffsetY(startPoint, endPoint);
|
|
3930
|
+
let benchmarkOffset = isHorizontal ? resizeHandlePoint[0] - resizeOriginPoint[0] : resizeHandlePoint[1] - resizeOriginPoint[1];
|
|
3931
|
+
const zoom = normalizedOffset / benchmarkOffset;
|
|
3932
|
+
if (isAspectRatio) {
|
|
3933
|
+
xZoom = zoom;
|
|
3934
|
+
yZoom = zoom;
|
|
3935
|
+
}
|
|
3936
|
+
else {
|
|
3937
|
+
if (isHorizontal) {
|
|
3938
|
+
xZoom = zoom;
|
|
3665
3939
|
}
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
if (!getElementById(board, element.target.boundId, elements)) {
|
|
3669
|
-
delete target.boundId;
|
|
3670
|
-
delete target.connection;
|
|
3671
|
-
}
|
|
3940
|
+
else {
|
|
3941
|
+
yZoom = zoom;
|
|
3672
3942
|
}
|
|
3673
|
-
points = points.map(point => [point[0] - startPoint[0], point[1] - startPoint[1]]);
|
|
3674
|
-
return { ...element, points, source, target };
|
|
3675
3943
|
}
|
|
3676
|
-
|
|
3677
|
-
}
|
|
3944
|
+
}
|
|
3945
|
+
return { xZoom, yZoom };
|
|
3678
3946
|
};
|
|
3679
|
-
const
|
|
3680
|
-
const
|
|
3681
|
-
const
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
|
|
3698
|
-
Transforms.insertNode(board, element, [board.children.length]);
|
|
3699
|
-
});
|
|
3700
|
-
lines.forEach(element => {
|
|
3701
|
-
element.id = idCreator();
|
|
3702
|
-
element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
|
|
3703
|
-
Transforms.insertNode(board, element, [board.children.length]);
|
|
3947
|
+
const movePointByZoomAndOriginPoint = (p, resizeOriginPoint, xZoom, yZoom) => {
|
|
3948
|
+
const offsetX = (p[0] - resizeOriginPoint[0]) * xZoom;
|
|
3949
|
+
const offsetY = (p[1] - resizeOriginPoint[1]) * yZoom;
|
|
3950
|
+
return [p[0] + offsetX, p[1] + offsetY];
|
|
3951
|
+
};
|
|
3952
|
+
/**
|
|
3953
|
+
* 1. Rotate 90°
|
|
3954
|
+
* 2. Scale based on the rotated points
|
|
3955
|
+
* 3. Reverse rotate the scaled points by 90°
|
|
3956
|
+
*/
|
|
3957
|
+
const getResizePointsByOtherwiseAxis = (board, points, resizeOriginPoint, xZoom, yZoom) => {
|
|
3958
|
+
const currentRectangle = RectangleClient.getRectangleByPoints(points);
|
|
3959
|
+
debugGenerator$1.isDebug() && debugGenerator$1.drawRectangle(board, currentRectangle, { stroke: 'black' });
|
|
3960
|
+
let resultPoints = points;
|
|
3961
|
+
resultPoints = rotatePoints(resultPoints, RectangleClient.getCenterPoint(currentRectangle), (1 / 2) * Math.PI);
|
|
3962
|
+
debugGenerator$1.isDebug() && debugGenerator$1.drawRectangle(board, resultPoints, { stroke: 'blue' });
|
|
3963
|
+
resultPoints = resultPoints.map(p => {
|
|
3964
|
+
return movePointByZoomAndOriginPoint(p, resizeOriginPoint, xZoom, yZoom);
|
|
3704
3965
|
});
|
|
3705
|
-
|
|
3966
|
+
debugGenerator$1.isDebug() && debugGenerator$1.drawRectangle(board, resultPoints);
|
|
3967
|
+
const newRectangle = RectangleClient.getRectangleByPoints(resultPoints);
|
|
3968
|
+
return rotatePoints(resultPoints, RectangleClient.getCenterPoint(newRectangle), -(1 / 2) * Math.PI);
|
|
3706
3969
|
};
|
|
3707
3970
|
|
|
3708
|
-
const
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3971
|
+
const debugKey = 'debug:plait:point-for-geometry';
|
|
3972
|
+
const debugGenerator = createDebugGenerator(debugKey);
|
|
3973
|
+
const EQUAL_SPACING = 10;
|
|
3974
|
+
function getSnapResizingRefOptions(board, resizeRef, resizeState, resizeOriginPointAndHandlePoint, isAspectRatio, isFromCorner) {
|
|
3975
|
+
const { originPoint, handlePoint } = resizeOriginPointAndHandlePoint;
|
|
3976
|
+
const resizePoints = [resizeState.startPoint, resizeState.endPoint];
|
|
3977
|
+
const { xZoom, yZoom } = getResizeZoom(resizePoints, originPoint, handlePoint, isFromCorner, isAspectRatio);
|
|
3978
|
+
let activeElements;
|
|
3979
|
+
let resizeOriginPoint = [];
|
|
3980
|
+
if (Array.isArray(resizeRef.element)) {
|
|
3981
|
+
activeElements = resizeRef.element;
|
|
3982
|
+
const rectangle = getRectangleByElements(board, resizeRef.element, false);
|
|
3983
|
+
resizeOriginPoint = RectangleClient.getPoints(rectangle);
|
|
3984
|
+
}
|
|
3985
|
+
else {
|
|
3986
|
+
activeElements = [resizeRef.element];
|
|
3987
|
+
resizeOriginPoint = resizeRef.element.points;
|
|
3988
|
+
}
|
|
3989
|
+
const points = resizeOriginPoint.map(p => {
|
|
3990
|
+
return movePointByZoomAndOriginPoint(p, originPoint, xZoom, yZoom);
|
|
3991
|
+
});
|
|
3992
|
+
const activeRectangle = getRectangleByAngle(RectangleClient.getRectangleByPoints(points), getSelectionAngle(activeElements)) ||
|
|
3993
|
+
RectangleClient.getRectangleByPoints(points);
|
|
3994
|
+
const resizeHandlePoint = movePointByZoomAndOriginPoint(handlePoint, originPoint, xZoom, yZoom);
|
|
3995
|
+
const [x, y] = getUnitVectorByPointAndPoint(originPoint, resizeHandlePoint);
|
|
3996
|
+
return {
|
|
3997
|
+
resizePoints,
|
|
3998
|
+
resizeOriginPoint,
|
|
3999
|
+
activeRectangle,
|
|
4000
|
+
originPoint,
|
|
4001
|
+
handlePoint,
|
|
4002
|
+
directionFactors: [getDirectionFactorByDirectionComponent(x), getDirectionFactorByDirectionComponent(y)],
|
|
4003
|
+
isAspectRatio,
|
|
4004
|
+
isFromCorner
|
|
3729
4005
|
};
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
data: elements
|
|
3750
|
-
});
|
|
3751
|
-
}
|
|
3752
|
-
}
|
|
3753
|
-
setFragment(data, clipboardContext, rectangle, type);
|
|
4006
|
+
}
|
|
4007
|
+
function getSnapResizingRef(board, activeElements, resizeSnapOptions) {
|
|
4008
|
+
const snapG = createG();
|
|
4009
|
+
const snapRectangles = getSnapRectangles(board, activeElements);
|
|
4010
|
+
let snapLineDelta = getIsometricLineDelta(snapRectangles, resizeSnapOptions);
|
|
4011
|
+
if (snapLineDelta.deltaX === 0 && snapLineDelta.deltaY === 0) {
|
|
4012
|
+
snapLineDelta = getSnapPointDelta(snapRectangles, resizeSnapOptions);
|
|
4013
|
+
}
|
|
4014
|
+
const angle = getSelectionAngle(activeElements);
|
|
4015
|
+
const activePointAndZoom = getActivePointAndZoom(snapLineDelta, resizeSnapOptions, angle);
|
|
4016
|
+
const isometricLinesG = drawIsometricSnapLines(board, activePointAndZoom.activePoints, snapRectangles, resizeSnapOptions, angle);
|
|
4017
|
+
const pointLinesG = drawResizingPointSnapLines(board, activePointAndZoom.activePoints, snapRectangles, resizeSnapOptions, angle);
|
|
4018
|
+
snapG.append(isometricLinesG, pointLinesG);
|
|
4019
|
+
return { ...activePointAndZoom, ...snapLineDelta, snapG };
|
|
4020
|
+
}
|
|
4021
|
+
function getSnapPointDelta(snapRectangles, resizeSnapOptions) {
|
|
4022
|
+
let pointLineDelta = {
|
|
4023
|
+
deltaX: 0,
|
|
4024
|
+
deltaY: 0
|
|
3754
4025
|
};
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
}
|
|
3768
|
-
if (clipboardData?.elements?.length) {
|
|
3769
|
-
const drawElements = clipboardData.elements?.filter(value => PlaitDrawElement.isDrawElement(value));
|
|
3770
|
-
if (clipboardData.elements && clipboardData.elements.length > 0 && drawElements.length > 0) {
|
|
3771
|
-
insertClipboardData(board, drawElements, targetPoint);
|
|
3772
|
-
}
|
|
3773
|
-
}
|
|
3774
|
-
if (clipboardData?.text) {
|
|
3775
|
-
if (!clipboardData.elements || clipboardData.elements.length === 0) {
|
|
3776
|
-
// (* ̄︶ ̄)
|
|
3777
|
-
const insertAsChildren = selectedElements.length === 1 && selectedElements[0].children;
|
|
3778
|
-
const insertAsFreeText = !insertAsChildren;
|
|
3779
|
-
if (insertAsFreeText) {
|
|
3780
|
-
DrawTransforms.insertText(board, targetPoint, clipboardData.text);
|
|
3781
|
-
return;
|
|
3782
|
-
}
|
|
4026
|
+
const { isAspectRatio, activeRectangle, directionFactors } = resizeSnapOptions;
|
|
4027
|
+
const drawHorizontal = directionFactors[0] !== 0 || isAspectRatio;
|
|
4028
|
+
const drawVertical = directionFactors[1] !== 0 || isAspectRatio;
|
|
4029
|
+
if (drawHorizontal) {
|
|
4030
|
+
const xSnapAxis = getTripleAxis(activeRectangle, true);
|
|
4031
|
+
const pointX = directionFactors[0] === -1 ? xSnapAxis[0] : xSnapAxis[2];
|
|
4032
|
+
const deltaX = getMinPointDelta(snapRectangles, pointX, true);
|
|
4033
|
+
if (Math.abs(deltaX) < SNAP_TOLERANCE) {
|
|
4034
|
+
pointLineDelta.deltaX = deltaX;
|
|
4035
|
+
if (pointLineDelta.deltaX !== 0 && isAspectRatio) {
|
|
4036
|
+
pointLineDelta.deltaY = pointLineDelta.deltaX / (activeRectangle.width / activeRectangle.height);
|
|
4037
|
+
return pointLineDelta;
|
|
3783
4038
|
}
|
|
3784
4039
|
}
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
const
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
const { pointerDown, pointerMove, globalPointerUp } = board;
|
|
3796
|
-
let start = null;
|
|
3797
|
-
let sourceElement;
|
|
3798
|
-
let lineShapeG = null;
|
|
3799
|
-
let temporaryElement = null;
|
|
3800
|
-
board.pointerDown = (event) => {
|
|
3801
|
-
const linePointers = getLinePointers();
|
|
3802
|
-
const isLinePointer = PlaitBoard.isInPointer(board, linePointers);
|
|
3803
|
-
if (!PlaitBoard.isReadonly(board) && isLinePointer && isDrawingMode(board)) {
|
|
3804
|
-
const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
3805
|
-
start = point;
|
|
3806
|
-
const hitElement = getSnappingGeometry(board, point);
|
|
3807
|
-
if (hitElement) {
|
|
3808
|
-
sourceElement = hitElement;
|
|
4040
|
+
}
|
|
4041
|
+
if (drawVertical) {
|
|
4042
|
+
const ySnapAxis = getTripleAxis(activeRectangle, false);
|
|
4043
|
+
const pointY = directionFactors[1] === -1 ? ySnapAxis[0] : ySnapAxis[2];
|
|
4044
|
+
const deltaY = getMinPointDelta(snapRectangles, pointY, false);
|
|
4045
|
+
if (Math.abs(deltaY) < SNAP_TOLERANCE) {
|
|
4046
|
+
pointLineDelta.deltaY = deltaY;
|
|
4047
|
+
if (pointLineDelta.deltaY !== 0 && isAspectRatio) {
|
|
4048
|
+
pointLineDelta.deltaX = pointLineDelta.deltaY * (activeRectangle.width / activeRectangle.height);
|
|
4049
|
+
return pointLineDelta;
|
|
3809
4050
|
}
|
|
3810
|
-
preventTouchMove(board, event, true);
|
|
3811
|
-
}
|
|
3812
|
-
pointerDown(event);
|
|
3813
|
-
};
|
|
3814
|
-
board.pointerMove = (event) => {
|
|
3815
|
-
lineShapeG?.remove();
|
|
3816
|
-
lineShapeG = createG();
|
|
3817
|
-
let movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
3818
|
-
if (start) {
|
|
3819
|
-
const lineShape = PlaitBoard.getPointer(board);
|
|
3820
|
-
temporaryElement = handleLineCreating(board, lineShape, start, movingPoint, sourceElement, lineShapeG);
|
|
3821
|
-
}
|
|
3822
|
-
pointerMove(event);
|
|
3823
|
-
};
|
|
3824
|
-
board.globalPointerUp = (event) => {
|
|
3825
|
-
if (temporaryElement) {
|
|
3826
|
-
Transforms.insertNode(board, temporaryElement, [board.children.length]);
|
|
3827
|
-
clearSelectedElement(board);
|
|
3828
|
-
addSelectedElement(board, temporaryElement);
|
|
3829
|
-
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
3830
4051
|
}
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
const
|
|
3843
|
-
const
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
class ResizeSnapReaction {
|
|
3848
|
-
constructor(board, activeElements) {
|
|
3849
|
-
this.board = board;
|
|
3850
|
-
this.activeElements = activeElements;
|
|
3851
|
-
this.alignRectangles = this.getAlignRectangle();
|
|
3852
|
-
this.angle = getSelectionAngle(activeElements);
|
|
3853
|
-
}
|
|
3854
|
-
getAlignRectangle() {
|
|
3855
|
-
const elements = findElements(this.board, {
|
|
3856
|
-
match: element => this.board.isAlign(element) && !this.activeElements.some(item => item.id === element.id),
|
|
3857
|
-
recursion: () => false,
|
|
3858
|
-
isReverse: false
|
|
3859
|
-
});
|
|
3860
|
-
return elements.map(item => getRectangleByAngle(this.board.getRectangle(item), item.angle) || this.board.getRectangle(item));
|
|
3861
|
-
}
|
|
3862
|
-
getSnapRef(resizeAlignDelta, resizeSnapOptions) {
|
|
3863
|
-
const { deltaX, deltaY } = resizeAlignDelta;
|
|
3864
|
-
const { resizeState, originPoint, handlePoint, isFromCorner, isAspectRatio, resizeOriginPoints } = resizeSnapOptions;
|
|
3865
|
-
const newResizeState = {
|
|
3866
|
-
...resizeState,
|
|
3867
|
-
endPoint: [resizeState.endPoint[0] + deltaX, resizeState.endPoint[1] + deltaY]
|
|
3868
|
-
};
|
|
3869
|
-
const { xZoom, yZoom } = getResizeZoom(newResizeState, originPoint, handlePoint, isFromCorner, isAspectRatio);
|
|
3870
|
-
let activePoints = resizeOriginPoints.map(p => {
|
|
4052
|
+
}
|
|
4053
|
+
return pointLineDelta;
|
|
4054
|
+
}
|
|
4055
|
+
function getActivePointAndZoom(resizeSnapDelta, resizeSnapOptions, angle) {
|
|
4056
|
+
const { deltaX, deltaY } = resizeSnapDelta;
|
|
4057
|
+
const { resizePoints, isCreate } = resizeSnapOptions;
|
|
4058
|
+
const newResizePoints = [resizePoints[0], [resizePoints[1][0] + deltaX, resizePoints[1][1] + deltaY]];
|
|
4059
|
+
let activePoints = newResizePoints;
|
|
4060
|
+
let xZoom = 0;
|
|
4061
|
+
let yZoom = 0;
|
|
4062
|
+
if (!isCreate) {
|
|
4063
|
+
const { originPoint, handlePoint, isFromCorner, isAspectRatio, resizeOriginPoint } = resizeSnapOptions;
|
|
4064
|
+
const resizeZoom = getResizeZoom(newResizePoints, originPoint, handlePoint, isFromCorner, isAspectRatio);
|
|
4065
|
+
xZoom = resizeZoom.xZoom;
|
|
4066
|
+
yZoom = resizeZoom.yZoom;
|
|
4067
|
+
activePoints = resizeOriginPoint.map(p => {
|
|
3871
4068
|
return movePointByZoomAndOriginPoint(p, originPoint, xZoom, yZoom);
|
|
3872
4069
|
});
|
|
3873
|
-
if (
|
|
3874
|
-
activePoints = resetPointsAfterResize(RectangleClient.getRectangleByPoints(
|
|
4070
|
+
if (angle) {
|
|
4071
|
+
activePoints = resetPointsAfterResize(RectangleClient.getRectangleByPoints(resizeOriginPoint), RectangleClient.getRectangleByPoints(activePoints), RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(resizeOriginPoint)), RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(activePoints)), angle);
|
|
3875
4072
|
}
|
|
3876
|
-
return {
|
|
3877
|
-
deltaX,
|
|
3878
|
-
deltaY,
|
|
3879
|
-
xZoom,
|
|
3880
|
-
yZoom,
|
|
3881
|
-
activePoints
|
|
3882
|
-
};
|
|
3883
4073
|
}
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
if (isAspectRatio) {
|
|
3905
|
-
const deltaWidth = deltaHeight * (activeRectangle.width / activeRectangle.height);
|
|
3906
|
-
equalLineDelta.deltaX = deltaWidth * resizeSnapOptions.directionFactors[0];
|
|
3907
|
-
return equalLineDelta;
|
|
3908
|
-
}
|
|
3909
|
-
}
|
|
3910
|
-
return equalLineDelta;
|
|
3911
|
-
}
|
|
3912
|
-
drawEqualLines(activePoints, resizeSnapOptions) {
|
|
3913
|
-
let widthEqualPoints = [];
|
|
3914
|
-
let heightEqualPoints = [];
|
|
3915
|
-
const drawHorizontalLine = resizeSnapOptions.directionFactors[0] !== 0 || resizeSnapOptions.isAspectRatio;
|
|
3916
|
-
const drawVerticalLine = resizeSnapOptions.directionFactors[1] !== 0 || resizeSnapOptions.isAspectRatio;
|
|
3917
|
-
const activeRectangle = getRectangleByAngle(RectangleClient.getRectangleByPoints(activePoints), this.angle) ||
|
|
3918
|
-
RectangleClient.getRectangleByPoints(activePoints);
|
|
3919
|
-
for (let alignRectangle of this.alignRectangles) {
|
|
3920
|
-
if (activeRectangle.width === alignRectangle.width && drawHorizontalLine) {
|
|
3921
|
-
widthEqualPoints.push(getEqualLinePoints(alignRectangle, true));
|
|
3922
|
-
}
|
|
3923
|
-
if (activeRectangle.height === alignRectangle.height && drawVerticalLine) {
|
|
3924
|
-
heightEqualPoints.push(getEqualLinePoints(alignRectangle, false));
|
|
3925
|
-
}
|
|
3926
|
-
}
|
|
3927
|
-
if (widthEqualPoints.length && drawHorizontalLine) {
|
|
3928
|
-
widthEqualPoints.push(getEqualLinePoints(activeRectangle, true));
|
|
3929
|
-
}
|
|
3930
|
-
if (heightEqualPoints.length && drawVerticalLine) {
|
|
3931
|
-
heightEqualPoints.push(getEqualLinePoints(activeRectangle, false));
|
|
4074
|
+
return {
|
|
4075
|
+
xZoom,
|
|
4076
|
+
yZoom,
|
|
4077
|
+
activePoints
|
|
4078
|
+
};
|
|
4079
|
+
}
|
|
4080
|
+
function getIsometricLineDelta(snapRectangles, resizeSnapOptions) {
|
|
4081
|
+
let isometricLineDelta = {
|
|
4082
|
+
deltaX: 0,
|
|
4083
|
+
deltaY: 0
|
|
4084
|
+
};
|
|
4085
|
+
const { isAspectRatio, activeRectangle } = resizeSnapOptions;
|
|
4086
|
+
const widthSnapRectangle = snapRectangles.find(item => Math.abs(item.width - activeRectangle.width) < SNAP_TOLERANCE);
|
|
4087
|
+
if (widthSnapRectangle) {
|
|
4088
|
+
const deltaWidth = widthSnapRectangle.width - activeRectangle.width;
|
|
4089
|
+
isometricLineDelta.deltaX = deltaWidth * resizeSnapOptions.directionFactors[0];
|
|
4090
|
+
if (isAspectRatio) {
|
|
4091
|
+
const deltaHeight = deltaWidth / (activeRectangle.width / activeRectangle.height);
|
|
4092
|
+
isometricLineDelta.deltaY = deltaHeight * resizeSnapOptions.directionFactors[1];
|
|
4093
|
+
return isometricLineDelta;
|
|
3932
4094
|
}
|
|
3933
|
-
const equalLinePoints = [...widthEqualPoints, ...heightEqualPoints];
|
|
3934
|
-
return drawEqualLines(this.board, equalLinePoints);
|
|
3935
4095
|
}
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
if (drawHorizontal) {
|
|
3945
|
-
const xAlignAxis = getTripleAlignAxis(activeRectangle, true);
|
|
3946
|
-
const alignX = directionFactors[0] === -1 ? xAlignAxis[0] : xAlignAxis[2];
|
|
3947
|
-
const deltaX = getMinAlignDelta(this.alignRectangles, alignX, true);
|
|
3948
|
-
if (Math.abs(deltaX) < ALIGN_TOLERANCE) {
|
|
3949
|
-
alignLineDelta.deltaX = deltaX;
|
|
3950
|
-
if (alignLineDelta.deltaX !== 0 && isAspectRatio) {
|
|
3951
|
-
alignLineDelta.deltaY = alignLineDelta.deltaX / (activeRectangle.width / activeRectangle.height);
|
|
3952
|
-
return alignLineDelta;
|
|
3953
|
-
}
|
|
3954
|
-
}
|
|
3955
|
-
}
|
|
3956
|
-
if (drawVertical) {
|
|
3957
|
-
const yAlignAxis = getTripleAlignAxis(activeRectangle, false);
|
|
3958
|
-
const alignY = directionFactors[1] === -1 ? yAlignAxis[0] : yAlignAxis[2];
|
|
3959
|
-
const deltaY = getMinAlignDelta(this.alignRectangles, alignY, false);
|
|
3960
|
-
if (Math.abs(deltaY) < ALIGN_TOLERANCE) {
|
|
3961
|
-
alignLineDelta.deltaY = deltaY;
|
|
3962
|
-
if (alignLineDelta.deltaY !== 0 && isAspectRatio) {
|
|
3963
|
-
alignLineDelta.deltaX = alignLineDelta.deltaY * (activeRectangle.width / activeRectangle.height);
|
|
3964
|
-
return alignLineDelta;
|
|
3965
|
-
}
|
|
3966
|
-
}
|
|
3967
|
-
}
|
|
3968
|
-
return alignLineDelta;
|
|
3969
|
-
}
|
|
3970
|
-
drawAlignLines(activePoints, resizeSnapOptions) {
|
|
3971
|
-
debugGenerator$1.isDebug() && debugGenerator$1.clear();
|
|
3972
|
-
let alignLinePoints = [];
|
|
3973
|
-
const activeRectangle = getRectangleByAngle(RectangleClient.getRectangleByPoints(activePoints), this.angle) ||
|
|
3974
|
-
RectangleClient.getRectangleByPoints(activePoints);
|
|
3975
|
-
debugGenerator$1.isDebug() && debugGenerator$1.drawRectangle(this.board, activeRectangle, { stroke: 'green' });
|
|
3976
|
-
const alignAxisX = getTripleAlignAxis(activeRectangle, true);
|
|
3977
|
-
const alignAxisY = getTripleAlignAxis(activeRectangle, false);
|
|
3978
|
-
const alignLineRefs = [
|
|
3979
|
-
{
|
|
3980
|
-
axis: alignAxisX[0],
|
|
3981
|
-
isHorizontal: true,
|
|
3982
|
-
alignRectangles: []
|
|
3983
|
-
},
|
|
3984
|
-
{
|
|
3985
|
-
axis: alignAxisX[2],
|
|
3986
|
-
isHorizontal: true,
|
|
3987
|
-
alignRectangles: []
|
|
3988
|
-
},
|
|
3989
|
-
{
|
|
3990
|
-
axis: alignAxisY[0],
|
|
3991
|
-
isHorizontal: false,
|
|
3992
|
-
alignRectangles: []
|
|
3993
|
-
},
|
|
3994
|
-
{
|
|
3995
|
-
axis: alignAxisY[2],
|
|
3996
|
-
isHorizontal: false,
|
|
3997
|
-
alignRectangles: []
|
|
3998
|
-
}
|
|
3999
|
-
];
|
|
4000
|
-
const setAlignLine = (axis, alignRectangle, isHorizontal) => {
|
|
4001
|
-
const boundingRectangle = RectangleClient.inflate(RectangleClient.getBoundingRectangle([activeRectangle, alignRectangle]), ALIGN_SPACING);
|
|
4002
|
-
if (isHorizontal) {
|
|
4003
|
-
const pointStart = [axis, boundingRectangle.y];
|
|
4004
|
-
const pointEnd = [axis, boundingRectangle.y + boundingRectangle.height];
|
|
4005
|
-
alignLinePoints.push([pointStart, pointEnd]);
|
|
4006
|
-
}
|
|
4007
|
-
else {
|
|
4008
|
-
const pointStart = [boundingRectangle.x, axis];
|
|
4009
|
-
const pointEnd = [boundingRectangle.x + boundingRectangle.width, axis];
|
|
4010
|
-
alignLinePoints.push([pointStart, pointEnd]);
|
|
4011
|
-
}
|
|
4012
|
-
};
|
|
4013
|
-
const { isAspectRatio, directionFactors } = resizeSnapOptions;
|
|
4014
|
-
const drawHorizontal = directionFactors[0] !== 0 || isAspectRatio;
|
|
4015
|
-
const drawVertical = directionFactors[1] !== 0 || isAspectRatio;
|
|
4016
|
-
for (let index = 0; index < this.alignRectangles.length; index++) {
|
|
4017
|
-
const element = this.alignRectangles[index];
|
|
4018
|
-
debugGenerator$1.isDebug() && debugGenerator$1.drawRectangle(this.board, element);
|
|
4019
|
-
if (isAlign(alignLineRefs[0].axis, element, alignLineRefs[0].isHorizontal)) {
|
|
4020
|
-
alignLineRefs[0].alignRectangles.push(element);
|
|
4021
|
-
}
|
|
4022
|
-
if (isAlign(alignLineRefs[1].axis, element, alignLineRefs[1].isHorizontal)) {
|
|
4023
|
-
alignLineRefs[1].alignRectangles.push(element);
|
|
4024
|
-
}
|
|
4025
|
-
if (isAlign(alignLineRefs[2].axis, element, alignLineRefs[2].isHorizontal)) {
|
|
4026
|
-
alignLineRefs[2].alignRectangles.push(element);
|
|
4027
|
-
}
|
|
4028
|
-
if (isAlign(alignLineRefs[3].axis, element, alignLineRefs[3].isHorizontal)) {
|
|
4029
|
-
alignLineRefs[3].alignRectangles.push(element);
|
|
4030
|
-
}
|
|
4096
|
+
const heightSnapRectangle = snapRectangles.find(item => Math.abs(item.height - activeRectangle.height) < SNAP_TOLERANCE);
|
|
4097
|
+
if (heightSnapRectangle) {
|
|
4098
|
+
const deltaHeight = heightSnapRectangle.height - activeRectangle.height;
|
|
4099
|
+
isometricLineDelta.deltaY = deltaHeight * resizeSnapOptions.directionFactors[1];
|
|
4100
|
+
if (isAspectRatio) {
|
|
4101
|
+
const deltaWidth = deltaHeight * (activeRectangle.width / activeRectangle.height);
|
|
4102
|
+
isometricLineDelta.deltaX = deltaWidth * resizeSnapOptions.directionFactors[0];
|
|
4103
|
+
return isometricLineDelta;
|
|
4031
4104
|
}
|
|
4032
|
-
if (drawHorizontal && alignLineRefs[0].alignRectangles.length) {
|
|
4033
|
-
const leftRectangle = alignLineRefs[0].alignRectangles.length === 1
|
|
4034
|
-
? alignLineRefs[0].alignRectangles[0]
|
|
4035
|
-
: getNearestAlignRectangle(alignLineRefs[0].alignRectangles, activeRectangle);
|
|
4036
|
-
setAlignLine(alignLineRefs[0].axis, leftRectangle, alignLineRefs[0].isHorizontal);
|
|
4037
|
-
}
|
|
4038
|
-
if (drawHorizontal && alignLineRefs[1].alignRectangles.length) {
|
|
4039
|
-
const rightRectangle = alignLineRefs[1].alignRectangles.length === 1
|
|
4040
|
-
? alignLineRefs[1].alignRectangles[0]
|
|
4041
|
-
: getNearestAlignRectangle(alignLineRefs[1].alignRectangles, activeRectangle);
|
|
4042
|
-
setAlignLine(alignLineRefs[1].axis, rightRectangle, alignLineRefs[1].isHorizontal);
|
|
4043
|
-
}
|
|
4044
|
-
if (drawVertical && alignLineRefs[2].alignRectangles.length) {
|
|
4045
|
-
const topRectangle = alignLineRefs[2].alignRectangles.length === 1
|
|
4046
|
-
? alignLineRefs[2].alignRectangles[0]
|
|
4047
|
-
: getNearestAlignRectangle(alignLineRefs[2].alignRectangles, activeRectangle);
|
|
4048
|
-
setAlignLine(alignLineRefs[2].axis, topRectangle, alignLineRefs[2].isHorizontal);
|
|
4049
|
-
}
|
|
4050
|
-
if (drawVertical && alignLineRefs[3].alignRectangles.length) {
|
|
4051
|
-
const bottomRectangle = alignLineRefs[3].alignRectangles.length === 1
|
|
4052
|
-
? alignLineRefs[3].alignRectangles[0]
|
|
4053
|
-
: getNearestAlignRectangle(alignLineRefs[3].alignRectangles, activeRectangle);
|
|
4054
|
-
setAlignLine(alignLineRefs[3].axis, bottomRectangle, alignLineRefs[3].isHorizontal);
|
|
4055
|
-
}
|
|
4056
|
-
return drawAlignLines(this.board, alignLinePoints);
|
|
4057
|
-
}
|
|
4058
|
-
handleResizeSnap(resizeSnapOptions) {
|
|
4059
|
-
const alignG = createG();
|
|
4060
|
-
let alignLineDelta = this.getEqualLineDelta(resizeSnapOptions);
|
|
4061
|
-
if (alignLineDelta.deltaX === 0 && alignLineDelta.deltaY === 0) {
|
|
4062
|
-
alignLineDelta = this.getAlignLineDelta(resizeSnapOptions);
|
|
4063
|
-
}
|
|
4064
|
-
const equalLineRef = this.getSnapRef(alignLineDelta, resizeSnapOptions);
|
|
4065
|
-
const equalLinesG = this.drawEqualLines(equalLineRef.activePoints, resizeSnapOptions);
|
|
4066
|
-
const alignLinesG = this.drawAlignLines(equalLineRef.activePoints, resizeSnapOptions);
|
|
4067
|
-
alignG.append(equalLinesG, alignLinesG);
|
|
4068
|
-
return { ...equalLineRef, alignG };
|
|
4069
4105
|
}
|
|
4106
|
+
return isometricLineDelta;
|
|
4070
4107
|
}
|
|
4071
|
-
function
|
|
4072
|
-
return isHorizontal
|
|
4073
|
-
? [
|
|
4074
|
-
[point[0], point[1] - 4],
|
|
4075
|
-
[point[0], point[1] + 4]
|
|
4076
|
-
]
|
|
4077
|
-
: [
|
|
4078
|
-
[point[0] - 4, point[1]],
|
|
4079
|
-
[point[0] + 4, point[1]]
|
|
4080
|
-
];
|
|
4081
|
-
}
|
|
4082
|
-
function getEqualLinePoints(rectangle, isHorizontal) {
|
|
4108
|
+
function getIsometricLinePoints(rectangle, isHorizontal) {
|
|
4083
4109
|
return isHorizontal
|
|
4084
4110
|
? [
|
|
4085
4111
|
[rectangle.x, rectangle.y - EQUAL_SPACING],
|
|
@@ -4090,359 +4116,393 @@ function getEqualLinePoints(rectangle, isHorizontal) {
|
|
|
4090
4116
|
[rectangle.x - EQUAL_SPACING, rectangle.y + rectangle.height]
|
|
4091
4117
|
];
|
|
4092
4118
|
}
|
|
4093
|
-
function
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
});
|
|
4102
|
-
g.appendChild(yAlign);
|
|
4103
|
-
line.forEach(point => {
|
|
4104
|
-
const barPoint = getBarPoint(point, !!Point.isHorizontal(line[0], line[1]));
|
|
4105
|
-
const bar = PlaitBoard.getRoughSVG(board).line(barPoint[0][0], barPoint[0][1], barPoint[1][0], barPoint[1][1], {
|
|
4106
|
-
stroke: SELECTION_BORDER_COLOR,
|
|
4107
|
-
strokeWidth: 1
|
|
4108
|
-
});
|
|
4109
|
-
g.appendChild(bar);
|
|
4110
|
-
});
|
|
4111
|
-
});
|
|
4112
|
-
return g;
|
|
4113
|
-
}
|
|
4114
|
-
function drawAlignLines(board, lines) {
|
|
4115
|
-
const g = createG();
|
|
4116
|
-
lines.forEach(points => {
|
|
4117
|
-
if (!points.length)
|
|
4118
|
-
return;
|
|
4119
|
-
const xAlign = PlaitBoard.getRoughSVG(board).line(points[0][0], points[0][1], points[1][0], points[1][1], {
|
|
4120
|
-
stroke: SELECTION_BORDER_COLOR,
|
|
4121
|
-
strokeWidth: 1,
|
|
4122
|
-
strokeLineDash: [4, 4]
|
|
4123
|
-
});
|
|
4124
|
-
g.appendChild(xAlign);
|
|
4125
|
-
});
|
|
4126
|
-
return g;
|
|
4119
|
+
function drawResizingPointSnapLines(board, activePoints, snapRectangles, resizeSnapOptions, angle) {
|
|
4120
|
+
debugGenerator.isDebug() && debugGenerator.clear();
|
|
4121
|
+
const activeRectangle = getRectangleByAngle(RectangleClient.getRectangleByPoints(activePoints), angle) ||
|
|
4122
|
+
RectangleClient.getRectangleByPoints(activePoints);
|
|
4123
|
+
const { isAspectRatio, directionFactors } = resizeSnapOptions;
|
|
4124
|
+
const drawHorizontal = directionFactors[0] !== 0 || isAspectRatio;
|
|
4125
|
+
const drawVertical = directionFactors[1] !== 0 || isAspectRatio;
|
|
4126
|
+
return drawPointSnapLines(board, activeRectangle, snapRectangles, drawHorizontal, drawVertical);
|
|
4127
4127
|
}
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
const
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
const alignAxis = getTripleAlignAxis(rectangle, isHorizontal);
|
|
4139
|
-
const deltas = alignAxis.map(item => item - axis);
|
|
4140
|
-
const absDeltas = deltas.map(item => Math.abs(item));
|
|
4141
|
-
const index = absDeltas.indexOf(Math.min(...absDeltas));
|
|
4142
|
-
return deltas[index];
|
|
4143
|
-
};
|
|
4144
|
-
function getMinAlignDelta(alignRectangles, axis, isHorizontal) {
|
|
4145
|
-
let delta = ALIGN_TOLERANCE;
|
|
4146
|
-
alignRectangles.forEach(item => {
|
|
4147
|
-
const distance = getClosestDelta(axis, item, isHorizontal);
|
|
4148
|
-
if (Math.abs(distance) < Math.abs(delta)) {
|
|
4149
|
-
delta = distance;
|
|
4128
|
+
function drawIsometricSnapLines(board, activePoints, snapRectangles, resizeSnapOptions, angle) {
|
|
4129
|
+
let widthIsometricPoints = [];
|
|
4130
|
+
let heightIsometricPoints = [];
|
|
4131
|
+
const drawHorizontalLine = resizeSnapOptions.directionFactors[0] !== 0 || resizeSnapOptions.isAspectRatio;
|
|
4132
|
+
const drawVerticalLine = resizeSnapOptions.directionFactors[1] !== 0 || resizeSnapOptions.isAspectRatio;
|
|
4133
|
+
const activeRectangle = getRectangleByAngle(RectangleClient.getRectangleByPoints(activePoints), angle) ||
|
|
4134
|
+
RectangleClient.getRectangleByPoints(activePoints);
|
|
4135
|
+
for (let snapRectangle of snapRectangles) {
|
|
4136
|
+
if (activeRectangle.width === snapRectangle.width && drawHorizontalLine) {
|
|
4137
|
+
widthIsometricPoints.push(getIsometricLinePoints(snapRectangle, true));
|
|
4150
4138
|
}
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
}
|
|
4154
|
-
function getNearestAlignRectangle(alignRectangles, activeRectangle) {
|
|
4155
|
-
let minDistance = Infinity;
|
|
4156
|
-
let nearestRectangle = alignRectangles[0];
|
|
4157
|
-
alignRectangles.forEach(item => {
|
|
4158
|
-
const distance = Math.sqrt(Math.pow(activeRectangle.x - item.x, 2) + Math.pow(activeRectangle.y - item.y, 2));
|
|
4159
|
-
if (distance < minDistance) {
|
|
4160
|
-
minDistance = distance;
|
|
4161
|
-
nearestRectangle = item;
|
|
4139
|
+
if (activeRectangle.height === snapRectangle.height && drawVerticalLine) {
|
|
4140
|
+
heightIsometricPoints.push(getIsometricLinePoints(snapRectangle, false));
|
|
4162
4141
|
}
|
|
4163
|
-
});
|
|
4164
|
-
return nearestRectangle;
|
|
4165
|
-
}
|
|
4166
|
-
function getResizeSnapRef(board, resizeRef, resizeState, resizeOriginPointAndHandlePoint, isAspectRatio, isFromCorner) {
|
|
4167
|
-
const { originPoint, handlePoint } = resizeOriginPointAndHandlePoint;
|
|
4168
|
-
const { xZoom, yZoom } = getResizeZoom(resizeState, originPoint, handlePoint, isFromCorner, isAspectRatio);
|
|
4169
|
-
let activeElements;
|
|
4170
|
-
let resizeOriginPoints = [];
|
|
4171
|
-
if (Array.isArray(resizeRef.element)) {
|
|
4172
|
-
activeElements = resizeRef.element;
|
|
4173
|
-
const rectangle = getRectangleByElements(board, resizeRef.element, false);
|
|
4174
|
-
resizeOriginPoints = RectangleClient.getPoints(rectangle);
|
|
4175
4142
|
}
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
resizeOriginPoints = resizeRef.element.points;
|
|
4143
|
+
if (widthIsometricPoints.length && drawHorizontalLine) {
|
|
4144
|
+
widthIsometricPoints.push(getIsometricLinePoints(activeRectangle, true));
|
|
4179
4145
|
}
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
}
|
|
4183
|
-
const
|
|
4184
|
-
|
|
4185
|
-
const resizeSnapReaction = new ResizeSnapReaction(board, activeElements);
|
|
4186
|
-
const resizeHandlePoint = movePointByZoomAndOriginPoint(handlePoint, originPoint, xZoom, yZoom);
|
|
4187
|
-
const [x, y] = getUnitVectorByPointAndPoint(originPoint, resizeHandlePoint);
|
|
4188
|
-
return resizeSnapReaction.handleResizeSnap({
|
|
4189
|
-
resizeState,
|
|
4190
|
-
resizeOriginPoints,
|
|
4191
|
-
activeRectangle,
|
|
4192
|
-
originPoint,
|
|
4193
|
-
handlePoint,
|
|
4194
|
-
directionFactors: [getDirectionFactorByDirectionComponent(x), getDirectionFactorByDirectionComponent(y)],
|
|
4195
|
-
isAspectRatio,
|
|
4196
|
-
isFromCorner
|
|
4197
|
-
});
|
|
4146
|
+
if (heightIsometricPoints.length && drawVerticalLine) {
|
|
4147
|
+
heightIsometricPoints.push(getIsometricLinePoints(activeRectangle, false));
|
|
4148
|
+
}
|
|
4149
|
+
const isometricLines = [...widthIsometricPoints, ...heightIsometricPoints];
|
|
4150
|
+
return drawSolidLines(board, isometricLines);
|
|
4198
4151
|
}
|
|
4199
4152
|
|
|
4200
|
-
const
|
|
4201
|
-
const
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
let
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
const
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
cursorClass: handleRef.cursorClass
|
|
4226
|
-
};
|
|
4227
|
-
}
|
|
4228
|
-
return null;
|
|
4229
|
-
},
|
|
4230
|
-
onResize: (resizeRef, resizeState) => {
|
|
4231
|
-
alignG?.remove();
|
|
4232
|
-
debugGenerator.isDebug() && debugGenerator.clear();
|
|
4233
|
-
const isFromCorner = isCornerHandle(board, resizeRef.handle);
|
|
4234
|
-
const isAspectRatio = resizeState.isShift || isFromCorner;
|
|
4235
|
-
const centerPoint = RectangleClient.getCenterPoint(resizeRef.rectangle);
|
|
4236
|
-
const { originPoint, handlePoint } = getResizeOriginPointAndHandlePoint(board, resizeRef);
|
|
4237
|
-
const angle = getSelectionAngle(resizeRef.element);
|
|
4238
|
-
let bulkRotationRef;
|
|
4239
|
-
if (angle) {
|
|
4240
|
-
bulkRotationRef = {
|
|
4241
|
-
angle: angle,
|
|
4242
|
-
offsetX: 0,
|
|
4243
|
-
offsetY: 0,
|
|
4244
|
-
newCenterPoint: [0, 0]
|
|
4245
|
-
};
|
|
4246
|
-
const [rotatedStartPoint, rotateEndPoint] = rotatePoints([resizeState.startPoint, resizeState.endPoint], centerPoint, -bulkRotationRef.angle);
|
|
4247
|
-
resizeState.startPoint = rotatedStartPoint;
|
|
4248
|
-
resizeState.endPoint = rotateEndPoint;
|
|
4249
|
-
}
|
|
4250
|
-
const resizeAlignRef = getResizeSnapRef(board, resizeRef, resizeState, {
|
|
4251
|
-
originPoint,
|
|
4252
|
-
handlePoint
|
|
4253
|
-
}, isAspectRatio, isFromCorner);
|
|
4254
|
-
resizeActivePoints = resizeAlignRef.activePoints;
|
|
4255
|
-
alignG = resizeAlignRef.alignG;
|
|
4256
|
-
PlaitBoard.getElementActiveHost(board).append(alignG);
|
|
4257
|
-
if (bulkRotationRef) {
|
|
4258
|
-
const boundingBoxCornerPoints = RectangleClient.getPoints(resizeRef.rectangle);
|
|
4259
|
-
const resizedBoundingBoxCornerPoints = boundingBoxCornerPoints.map(p => {
|
|
4260
|
-
return movePointByZoomAndOriginPoint(p, originPoint, resizeAlignRef.xZoom, resizeAlignRef.yZoom);
|
|
4261
|
-
});
|
|
4262
|
-
const newBoundingBox = RectangleClient.getRectangleByPoints(resizedBoundingBoxCornerPoints);
|
|
4263
|
-
debugGenerator.isDebug() && debugGenerator.drawRectangle(board, newBoundingBox, { stroke: 'blue' });
|
|
4264
|
-
const newBoundingBoxCenter = RectangleClient.getCenterPoint(newBoundingBox);
|
|
4265
|
-
const adjustedNewBoundingBoxPoints = resetPointsAfterResize(RectangleClient.getRectangleByPoints(boundingBoxCornerPoints), RectangleClient.getRectangleByPoints(resizedBoundingBoxCornerPoints), centerPoint, newBoundingBoxCenter, bulkRotationRef.angle);
|
|
4266
|
-
const newCenter = RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(adjustedNewBoundingBoxPoints));
|
|
4267
|
-
bulkRotationRef = Object.assign(bulkRotationRef, {
|
|
4268
|
-
offsetX: newCenter[0] - newBoundingBoxCenter[0],
|
|
4269
|
-
offsetY: newCenter[1] - newBoundingBoxCenter[1],
|
|
4270
|
-
newCenterPoint: newCenter
|
|
4271
|
-
});
|
|
4272
|
-
debugGenerator.isDebug() && debugGenerator.drawRectangle(board, adjustedNewBoundingBoxPoints);
|
|
4273
|
-
}
|
|
4274
|
-
resizeRef.element.forEach(target => {
|
|
4275
|
-
const path = PlaitBoard.findPath(board, target);
|
|
4276
|
-
let points;
|
|
4277
|
-
if (bulkRotationRef) {
|
|
4278
|
-
const reversedPoints = rotatedDataPoints(target.points, centerPoint, -bulkRotationRef.angle);
|
|
4279
|
-
points = reversedPoints.map((p) => {
|
|
4280
|
-
return movePointByZoomAndOriginPoint(p, originPoint, resizeAlignRef.xZoom, resizeAlignRef.yZoom);
|
|
4153
|
+
const withGeometryCreateByDrag = (board) => {
|
|
4154
|
+
const { pointerMove, globalPointerUp } = board;
|
|
4155
|
+
let geometryShapeG = null;
|
|
4156
|
+
let temporaryElement = null;
|
|
4157
|
+
let fakeCreateTextRef = null;
|
|
4158
|
+
board.pointerMove = (event) => {
|
|
4159
|
+
geometryShapeG?.remove();
|
|
4160
|
+
geometryShapeG = createG();
|
|
4161
|
+
const geometryGenerator = new GeometryShapeGenerator(board);
|
|
4162
|
+
const geometryPointers = getGeometryPointers();
|
|
4163
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
4164
|
+
const dragMode = isGeometryPointer && isDndMode(board);
|
|
4165
|
+
const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
4166
|
+
const pointer = PlaitBoard.getPointer(board);
|
|
4167
|
+
if (dragMode) {
|
|
4168
|
+
const memorizedLatest = getMemorizedLatestByPointer(pointer);
|
|
4169
|
+
if (pointer === BasicShapes.text) {
|
|
4170
|
+
const property = getTextShapeProperty(board, DefaultTextProperty.text, memorizedLatest.textProperties['font-size']);
|
|
4171
|
+
const points = RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(movingPoint, property.width, property.height));
|
|
4172
|
+
temporaryElement = createTextElement(board, points);
|
|
4173
|
+
if (!fakeCreateTextRef) {
|
|
4174
|
+
const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, {
|
|
4175
|
+
getRectangle: () => {
|
|
4176
|
+
return getTextRectangle(temporaryElement);
|
|
4177
|
+
}
|
|
4281
4178
|
});
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4179
|
+
PlaitBoard.getComponent(board)
|
|
4180
|
+
.viewContainerRef.injector.get(NgZone)
|
|
4181
|
+
.run(() => {
|
|
4182
|
+
textManage.draw(temporaryElement.text);
|
|
4183
|
+
});
|
|
4184
|
+
fakeCreateTextRef = {
|
|
4185
|
+
g: createG(),
|
|
4186
|
+
textManage
|
|
4187
|
+
};
|
|
4188
|
+
PlaitBoard.getHost(board).append(fakeCreateTextRef.g);
|
|
4189
|
+
fakeCreateTextRef.g.append(textManage.g);
|
|
4287
4190
|
}
|
|
4288
4191
|
else {
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
}
|
|
4292
|
-
if (hasValidAngle(target) && isAxisChangedByAngle(target.angle)) {
|
|
4293
|
-
points = getResizePointsByOtherwiseAxis(board, target.points, originPoint, resizeAlignRef.xZoom, resizeAlignRef.yZoom);
|
|
4294
|
-
}
|
|
4295
|
-
else {
|
|
4296
|
-
points = target.points.map(p => {
|
|
4297
|
-
return movePointByZoomAndOriginPoint(p, originPoint, resizeAlignRef.xZoom, resizeAlignRef.yZoom);
|
|
4298
|
-
});
|
|
4299
|
-
}
|
|
4192
|
+
fakeCreateTextRef.textManage.updateRectangle();
|
|
4193
|
+
fakeCreateTextRef.g.append(fakeCreateTextRef.textManage.g);
|
|
4300
4194
|
}
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4195
|
+
}
|
|
4196
|
+
else {
|
|
4197
|
+
const points = getDefaultGeometryPoints(pointer, movingPoint);
|
|
4198
|
+
temporaryElement = createDefaultGeometry(board, points, pointer);
|
|
4199
|
+
geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
|
|
4200
|
+
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
4201
|
+
}
|
|
4202
|
+
}
|
|
4203
|
+
pointerMove(event);
|
|
4204
|
+
};
|
|
4205
|
+
board.globalPointerUp = (event) => {
|
|
4206
|
+
const geometryPointers = getGeometryPointers();
|
|
4207
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
4208
|
+
const dragMode = isGeometryPointer && isDndMode(board);
|
|
4209
|
+
if (dragMode && temporaryElement) {
|
|
4210
|
+
insertElement(board, temporaryElement);
|
|
4211
|
+
fakeCreateTextRef?.textManage.destroy();
|
|
4212
|
+
fakeCreateTextRef?.g.remove();
|
|
4213
|
+
fakeCreateTextRef = null;
|
|
4214
|
+
}
|
|
4215
|
+
geometryShapeG?.remove();
|
|
4216
|
+
geometryShapeG = null;
|
|
4217
|
+
preventTouchMove(board, event, false);
|
|
4218
|
+
globalPointerUp(event);
|
|
4219
|
+
};
|
|
4220
|
+
return board;
|
|
4221
|
+
};
|
|
4222
|
+
const withGeometryCreateByDrawing = (board) => {
|
|
4223
|
+
const { pointerDown, pointerMove, pointerUp, keyDown, keyUp } = board;
|
|
4224
|
+
let start = null;
|
|
4225
|
+
let geometryShapeG = null;
|
|
4226
|
+
let temporaryElement = null;
|
|
4227
|
+
let isShift = false;
|
|
4228
|
+
let snapG;
|
|
4229
|
+
board.keyDown = (event) => {
|
|
4230
|
+
isShift = isKeyHotkey('shift', event);
|
|
4231
|
+
keyDown(event);
|
|
4232
|
+
};
|
|
4233
|
+
board.keyUp = (event) => {
|
|
4234
|
+
isShift = false;
|
|
4235
|
+
keyUp(event);
|
|
4236
|
+
};
|
|
4237
|
+
board.pointerDown = (event) => {
|
|
4238
|
+
const geometryPointers = getGeometryPointers();
|
|
4239
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
4240
|
+
if (!PlaitBoard.isReadonly(board) && isGeometryPointer && isDrawingMode(board)) {
|
|
4241
|
+
const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
4242
|
+
start = point;
|
|
4243
|
+
const pointer = PlaitBoard.getPointer(board);
|
|
4244
|
+
preventTouchMove(board, event, true);
|
|
4245
|
+
if (pointer === BasicShapes.text) {
|
|
4246
|
+
const memorizedLatest = getMemorizedLatestByPointer(pointer);
|
|
4247
|
+
const property = getTextShapeProperty(board, DefaultTextProperty.text, memorizedLatest.textProperties['font-size']);
|
|
4248
|
+
const points = RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(point, property.width, property.height));
|
|
4249
|
+
const textElement = createTextElement(board, points);
|
|
4250
|
+
insertElement(board, textElement);
|
|
4251
|
+
start = null;
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
pointerDown(event);
|
|
4255
|
+
};
|
|
4256
|
+
board.pointerMove = (event) => {
|
|
4257
|
+
geometryShapeG?.remove();
|
|
4258
|
+
geometryShapeG = createG();
|
|
4259
|
+
const geometryGenerator = new GeometryShapeGenerator(board);
|
|
4260
|
+
const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
4261
|
+
const pointer = PlaitBoard.getPointer(board);
|
|
4262
|
+
snapG?.remove();
|
|
4263
|
+
if (start && pointer !== BasicShapes.text) {
|
|
4264
|
+
let points = normalizeShapePoints([start, movingPoint], isShift);
|
|
4265
|
+
const activeRectangle = RectangleClient.getRectangleByPoints(points);
|
|
4266
|
+
const [x, y] = getUnitVectorByPointAndPoint(start, movingPoint);
|
|
4267
|
+
const resizeSnapRef = getSnapResizingRef(board, [], {
|
|
4268
|
+
resizePoints: points,
|
|
4269
|
+
activeRectangle,
|
|
4270
|
+
directionFactors: [getDirectionFactorByDirectionComponent(x), getDirectionFactorByDirectionComponent(y)],
|
|
4271
|
+
isAspectRatio: isShift,
|
|
4272
|
+
isFromCorner: true,
|
|
4273
|
+
isCreate: true
|
|
4274
|
+
});
|
|
4275
|
+
snapG = resizeSnapRef.snapG;
|
|
4276
|
+
PlaitBoard.getElementActiveHost(board).append(snapG);
|
|
4277
|
+
points = normalizeShapePoints(resizeSnapRef.activePoints, isShift);
|
|
4278
|
+
temporaryElement = createDefaultGeometry(board, points, pointer);
|
|
4279
|
+
geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
|
|
4280
|
+
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
4281
|
+
}
|
|
4282
|
+
pointerMove(event);
|
|
4283
|
+
};
|
|
4284
|
+
board.pointerUp = (event) => {
|
|
4285
|
+
const isDrawMode = !!start;
|
|
4286
|
+
if (isDrawMode) {
|
|
4287
|
+
const targetPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
4288
|
+
const { width, height } = RectangleClient.getRectangleByPoints([start, targetPoint]);
|
|
4289
|
+
if (Math.hypot(width, height) === 0) {
|
|
4290
|
+
const pointer = PlaitBoard.getPointer(board);
|
|
4291
|
+
if (pointer !== BasicShapes.text) {
|
|
4292
|
+
const points = getDefaultGeometryPoints(pointer, targetPoint);
|
|
4293
|
+
temporaryElement = createDefaultGeometry(board, points, pointer);
|
|
4304
4294
|
}
|
|
4305
|
-
|
|
4306
|
-
|
|
4295
|
+
}
|
|
4296
|
+
}
|
|
4297
|
+
if (temporaryElement) {
|
|
4298
|
+
insertElement(board, temporaryElement);
|
|
4299
|
+
}
|
|
4300
|
+
snapG?.remove();
|
|
4301
|
+
geometryShapeG?.remove();
|
|
4302
|
+
geometryShapeG = null;
|
|
4303
|
+
start = null;
|
|
4304
|
+
temporaryElement = null;
|
|
4305
|
+
preventTouchMove(board, event, false);
|
|
4306
|
+
pointerUp(event);
|
|
4307
|
+
};
|
|
4308
|
+
return board;
|
|
4309
|
+
};
|
|
4310
|
+
|
|
4311
|
+
const buildClipboardData = (board, elements, startPoint) => {
|
|
4312
|
+
return elements.map(element => {
|
|
4313
|
+
if (PlaitDrawElement.isGeometry(element) || PlaitDrawElement.isImage(element)) {
|
|
4314
|
+
const points = element.points.map(point => [point[0] - startPoint[0], point[1] - startPoint[1]]);
|
|
4315
|
+
return { ...element, points };
|
|
4316
|
+
}
|
|
4317
|
+
if (PlaitDrawElement.isLine(element)) {
|
|
4318
|
+
let source = { ...element.source };
|
|
4319
|
+
let target = { ...element.target };
|
|
4320
|
+
let points = [...element.points];
|
|
4321
|
+
if (element.source.boundId) {
|
|
4322
|
+
points[0] = getConnectionPoint(getElementById(board, element.source.boundId), element.source.connection);
|
|
4323
|
+
if (!getElementById(board, element.source.boundId, elements)) {
|
|
4324
|
+
delete source.boundId;
|
|
4325
|
+
delete source.connection;
|
|
4307
4326
|
}
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
const targetRectangle = RectangleClient.getRectangleByPoints(target.points);
|
|
4315
|
-
const centerPoint = RectangleClient.getCenterPoint(targetRectangle);
|
|
4316
|
-
const newCenterPoint = movePointByZoomAndOriginPoint(centerPoint, originPoint, resizeAlignRef.xZoom, resizeAlignRef.yZoom);
|
|
4317
|
-
const newTargetRectangle = RectangleClient.getRectangleByCenterPoint(newCenterPoint, targetRectangle.width, targetRectangle.height);
|
|
4318
|
-
Transforms.setNode(board, { points: RectangleClient.getPoints(newTargetRectangle) }, path);
|
|
4319
|
-
}
|
|
4327
|
+
}
|
|
4328
|
+
if (element.target.boundId) {
|
|
4329
|
+
points[points.length - 1] = getConnectionPoint(getElementById(board, element.target.boundId), element.target.connection);
|
|
4330
|
+
if (!getElementById(board, element.target.boundId, elements)) {
|
|
4331
|
+
delete target.boundId;
|
|
4332
|
+
delete target.connection;
|
|
4320
4333
|
}
|
|
4321
|
-
}
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4334
|
+
}
|
|
4335
|
+
points = points.map(point => [point[0] - startPoint[0], point[1] - startPoint[1]]);
|
|
4336
|
+
return { ...element, points, source, target };
|
|
4337
|
+
}
|
|
4338
|
+
return element;
|
|
4339
|
+
});
|
|
4340
|
+
};
|
|
4341
|
+
const insertClipboardData = (board, elements, startPoint) => {
|
|
4342
|
+
const lines = elements.filter(value => PlaitDrawElement.isLine(value));
|
|
4343
|
+
const geometries = elements.filter(value => PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isImage(value));
|
|
4344
|
+
geometries.forEach(element => {
|
|
4345
|
+
const sourceLines = [];
|
|
4346
|
+
const targetLines = [];
|
|
4347
|
+
lines.forEach(line => {
|
|
4348
|
+
if (PlaitLine.isBoundElementOfSource(line, element)) {
|
|
4349
|
+
sourceLines.push(line);
|
|
4350
|
+
}
|
|
4351
|
+
if (PlaitLine.isBoundElementOfTarget(line, element)) {
|
|
4352
|
+
targetLines.push(line);
|
|
4353
|
+
}
|
|
4354
|
+
});
|
|
4355
|
+
element.id = idCreator();
|
|
4356
|
+
// update lines
|
|
4357
|
+
sourceLines.forEach(sourceLine => (sourceLine.source.boundId = element.id));
|
|
4358
|
+
targetLines.forEach(targetLine => (targetLine.target.boundId = element.id));
|
|
4359
|
+
element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
|
|
4360
|
+
Transforms.insertNode(board, element, [board.children.length]);
|
|
4361
|
+
});
|
|
4362
|
+
lines.forEach(element => {
|
|
4363
|
+
element.id = idCreator();
|
|
4364
|
+
element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
|
|
4365
|
+
Transforms.insertNode(board, element, [board.children.length]);
|
|
4366
|
+
});
|
|
4367
|
+
Transforms.addSelectionWithTemporaryElements(board, elements);
|
|
4368
|
+
};
|
|
4369
|
+
|
|
4370
|
+
const withDrawFragment = (baseBoard) => {
|
|
4371
|
+
const board = baseBoard;
|
|
4372
|
+
const { getDeletedFragment, buildFragment, insertFragment } = board;
|
|
4373
|
+
board.getDeletedFragment = (data) => {
|
|
4374
|
+
const drawElements = getSelectedDrawElements(board);
|
|
4375
|
+
if (drawElements.length) {
|
|
4376
|
+
const geometryElements = drawElements.filter(value => PlaitDrawElement.isGeometry(value));
|
|
4377
|
+
const lineElements = drawElements.filter(value => PlaitDrawElement.isLine(value));
|
|
4378
|
+
const imageElements = drawElements.filter(value => PlaitDrawElement.isImage(value));
|
|
4379
|
+
const boundLineElements = [
|
|
4380
|
+
...getBoundedLineElements(board, geometryElements),
|
|
4381
|
+
...getBoundedLineElements(board, imageElements)
|
|
4382
|
+
].filter(line => !lineElements.includes(line));
|
|
4383
|
+
data.push(...[
|
|
4384
|
+
...geometryElements,
|
|
4385
|
+
...lineElements,
|
|
4386
|
+
...imageElements,
|
|
4387
|
+
...boundLineElements.filter(line => !lineElements.includes(line))
|
|
4388
|
+
]);
|
|
4389
|
+
}
|
|
4390
|
+
return getDeletedFragment(data);
|
|
4391
|
+
};
|
|
4392
|
+
board.buildFragment = (clipboardContext, rectangle, type) => {
|
|
4393
|
+
const targetDrawElements = getSelectedDrawElements(board);
|
|
4394
|
+
let boundLineElements = [];
|
|
4395
|
+
if (targetDrawElements.length) {
|
|
4396
|
+
if (type === 'cut') {
|
|
4397
|
+
const geometryElements = targetDrawElements.filter(value => PlaitDrawElement.isGeometry(value));
|
|
4398
|
+
const lineElements = targetDrawElements.filter(value => PlaitDrawElement.isLine(value));
|
|
4399
|
+
boundLineElements = getBoundedLineElements(board, geometryElements).filter(line => !lineElements.includes(line));
|
|
4400
|
+
}
|
|
4401
|
+
const selectedElements = [...targetDrawElements, ...boundLineElements];
|
|
4402
|
+
const elements = buildClipboardData(board, selectedElements, rectangle ? [rectangle.x, rectangle.y] : [0, 0]);
|
|
4403
|
+
const text = getElementsText(selectedElements);
|
|
4404
|
+
if (!clipboardContext) {
|
|
4405
|
+
clipboardContext = createClipboardContext(WritableClipboardType.elements, elements, text);
|
|
4406
|
+
}
|
|
4407
|
+
else {
|
|
4408
|
+
clipboardContext = addClipboardContext(clipboardContext, {
|
|
4409
|
+
text,
|
|
4410
|
+
type: WritableClipboardType.elements,
|
|
4411
|
+
elements
|
|
4412
|
+
});
|
|
4331
4413
|
}
|
|
4332
4414
|
}
|
|
4415
|
+
return buildFragment(clipboardContext, rectangle, type);
|
|
4333
4416
|
};
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4417
|
+
board.insertFragment = (clipboardData, targetPoint) => {
|
|
4418
|
+
const selectedElements = getSelectedElements(board);
|
|
4419
|
+
if (clipboardData?.files?.length) {
|
|
4420
|
+
const acceptImageArray = acceptImageTypes.map(type => 'image/' + type);
|
|
4421
|
+
const canInsertionImage = !getElementOfFocusedImage(board) && !(selectedElements.length === 1 && board.isImageBindingAllowed(selectedElements[0]));
|
|
4422
|
+
if (acceptImageArray.includes(clipboardData.files[0].type) && canInsertionImage) {
|
|
4423
|
+
const imageFile = clipboardData.files[0];
|
|
4424
|
+
buildImage(board, imageFile, DEFAULT_IMAGE_WIDTH, imageItem => {
|
|
4425
|
+
DrawTransforms.insertImage(board, imageItem, targetPoint);
|
|
4426
|
+
});
|
|
4427
|
+
return;
|
|
4428
|
+
}
|
|
4340
4429
|
}
|
|
4341
|
-
if (
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
? RectangleClient.getRectangleByPoints(resizeActivePoints)
|
|
4346
|
-
: getRectangleByElements(board, elements, false);
|
|
4347
|
-
let corners = RectangleClient.getCornerPoints(boundingRectangle);
|
|
4348
|
-
const angle = getSelectionAngle(elements);
|
|
4349
|
-
if (angle) {
|
|
4350
|
-
const centerPoint = RectangleClient.getCenterPoint(boundingRectangle);
|
|
4351
|
-
corners = rotatePoints(corners, centerPoint, angle);
|
|
4430
|
+
if (clipboardData?.elements?.length) {
|
|
4431
|
+
const drawElements = clipboardData.elements?.filter(value => PlaitDrawElement.isDrawElement(value));
|
|
4432
|
+
if (clipboardData.elements && clipboardData.elements.length > 0 && drawElements.length > 0) {
|
|
4433
|
+
insertClipboardData(board, drawElements, targetPoint);
|
|
4352
4434
|
}
|
|
4353
|
-
corners.forEach(corner => {
|
|
4354
|
-
const g = drawHandle(board, corner);
|
|
4355
|
-
handleG && handleG.append(g);
|
|
4356
|
-
});
|
|
4357
|
-
PlaitBoard.getElementActiveHost(board).append(handleG);
|
|
4358
4435
|
}
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4436
|
+
if (clipboardData?.text) {
|
|
4437
|
+
if (!clipboardData.elements || clipboardData.elements.length === 0) {
|
|
4438
|
+
// (* ̄︶ ̄)
|
|
4439
|
+
const insertAsChildren = selectedElements.length === 1 && selectedElements[0].children;
|
|
4440
|
+
const insertAsFreeText = !insertAsChildren;
|
|
4441
|
+
if (insertAsFreeText) {
|
|
4442
|
+
DrawTransforms.insertText(board, targetPoint, clipboardData.text);
|
|
4443
|
+
return;
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4367
4446
|
}
|
|
4368
|
-
|
|
4447
|
+
insertFragment(clipboardData, targetPoint);
|
|
4369
4448
|
};
|
|
4370
4449
|
return board;
|
|
4371
|
-
}
|
|
4372
|
-
const getResizeOriginPointAndHandlePoint = (board, resizeRef) => {
|
|
4373
|
-
const handleIndex = getIndexByResizeHandle(resizeRef.handle);
|
|
4374
|
-
const symmetricHandleIndex = getSymmetricHandleIndex(board, handleIndex);
|
|
4375
|
-
const originPoint = getResizeHandlePointByIndex(resizeRef.rectangle, symmetricHandleIndex);
|
|
4376
|
-
const handlePoint = getResizeHandlePointByIndex(resizeRef.rectangle, handleIndex);
|
|
4377
|
-
return {
|
|
4378
|
-
originPoint,
|
|
4379
|
-
handlePoint
|
|
4380
|
-
};
|
|
4381
4450
|
};
|
|
4382
|
-
const
|
|
4383
|
-
const
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4451
|
+
const getBoundedLineElements = (board, plaitShapes) => {
|
|
4452
|
+
const lines = getLines(board);
|
|
4453
|
+
return lines.filter(line => plaitShapes.find(shape => PlaitLine.isBoundElementOfSource(line, shape) || PlaitLine.isBoundElementOfTarget(line, shape)));
|
|
4454
|
+
};
|
|
4455
|
+
|
|
4456
|
+
const withLineCreateByDraw = (board) => {
|
|
4457
|
+
const { pointerDown, pointerMove, globalPointerUp } = board;
|
|
4458
|
+
let start = null;
|
|
4459
|
+
let sourceElement;
|
|
4460
|
+
let lineShapeG = null;
|
|
4461
|
+
let temporaryElement = null;
|
|
4462
|
+
board.pointerDown = (event) => {
|
|
4463
|
+
const linePointers = getLinePointers();
|
|
4464
|
+
const isLinePointer = PlaitBoard.isInPointer(board, linePointers);
|
|
4465
|
+
if (!PlaitBoard.isReadonly(board) && isLinePointer && isDrawingMode(board)) {
|
|
4466
|
+
const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
4467
|
+
start = point;
|
|
4468
|
+
const hitElement = getSnappingGeometry(board, point);
|
|
4469
|
+
if (hitElement) {
|
|
4470
|
+
sourceElement = hitElement;
|
|
4471
|
+
}
|
|
4472
|
+
preventTouchMove(board, event, true);
|
|
4398
4473
|
}
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
if (
|
|
4406
|
-
|
|
4407
|
-
|
|
4474
|
+
pointerDown(event);
|
|
4475
|
+
};
|
|
4476
|
+
board.pointerMove = (event) => {
|
|
4477
|
+
lineShapeG?.remove();
|
|
4478
|
+
lineShapeG = createG();
|
|
4479
|
+
let movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
4480
|
+
if (start) {
|
|
4481
|
+
const lineShape = PlaitBoard.getPointer(board);
|
|
4482
|
+
temporaryElement = handleLineCreating(board, lineShape, start, movingPoint, sourceElement, lineShapeG);
|
|
4408
4483
|
}
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4484
|
+
pointerMove(event);
|
|
4485
|
+
};
|
|
4486
|
+
board.globalPointerUp = (event) => {
|
|
4487
|
+
if (temporaryElement) {
|
|
4488
|
+
Transforms.insertNode(board, temporaryElement, [board.children.length]);
|
|
4489
|
+
clearSelectedElement(board);
|
|
4490
|
+
addSelectedElement(board, temporaryElement);
|
|
4491
|
+
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
4416
4492
|
}
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
};
|
|
4425
|
-
|
|
4426
|
-
* 1. Rotate 90°
|
|
4427
|
-
* 2. Scale based on the rotated points
|
|
4428
|
-
* 3. Reverse rotate the scaled points by 90°
|
|
4429
|
-
*/
|
|
4430
|
-
const getResizePointsByOtherwiseAxis = (board, points, resizeOriginPoint, xZoom, yZoom) => {
|
|
4431
|
-
const currentRectangle = RectangleClient.getRectangleByPoints(points);
|
|
4432
|
-
debugGenerator.isDebug() && debugGenerator.drawRectangle(board, currentRectangle, { stroke: 'black' });
|
|
4433
|
-
let resultPoints = points;
|
|
4434
|
-
resultPoints = rotatePoints(resultPoints, RectangleClient.getCenterPoint(currentRectangle), (1 / 2) * Math.PI);
|
|
4435
|
-
debugGenerator.isDebug() && debugGenerator.drawRectangle(board, resultPoints, { stroke: 'blue' });
|
|
4436
|
-
resultPoints = resultPoints.map(p => {
|
|
4437
|
-
return movePointByZoomAndOriginPoint(p, resizeOriginPoint, xZoom, yZoom);
|
|
4438
|
-
});
|
|
4439
|
-
debugGenerator.isDebug() && debugGenerator.drawRectangle(board, resultPoints);
|
|
4440
|
-
const newRectangle = RectangleClient.getRectangleByPoints(resultPoints);
|
|
4441
|
-
return rotatePoints(resultPoints, RectangleClient.getCenterPoint(newRectangle), -(1 / 2) * Math.PI);
|
|
4493
|
+
lineShapeG?.remove();
|
|
4494
|
+
lineShapeG = null;
|
|
4495
|
+
sourceElement = null;
|
|
4496
|
+
start = null;
|
|
4497
|
+
temporaryElement = null;
|
|
4498
|
+
preventTouchMove(board, event, false);
|
|
4499
|
+
globalPointerUp(event);
|
|
4500
|
+
};
|
|
4501
|
+
return board;
|
|
4442
4502
|
};
|
|
4443
4503
|
|
|
4444
4504
|
const withGeometryResize = (board) => {
|
|
4445
|
-
let
|
|
4505
|
+
let snapG;
|
|
4446
4506
|
const options = {
|
|
4447
4507
|
key: 'draw-geometry',
|
|
4448
4508
|
canResize: () => {
|
|
@@ -4470,20 +4530,21 @@ const withGeometryResize = (board) => {
|
|
|
4470
4530
|
return null;
|
|
4471
4531
|
},
|
|
4472
4532
|
onResize: (resizeRef, resizeState) => {
|
|
4473
|
-
const centerPoint = RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(resizeRef.element.points));
|
|
4474
4533
|
resizeState.startPoint = rotateAntiPointsByElement(resizeState.startPoint, resizeRef.element) || resizeState.startPoint;
|
|
4475
4534
|
resizeState.endPoint = rotateAntiPointsByElement(resizeState.endPoint, resizeRef.element) || resizeState.endPoint;
|
|
4476
|
-
|
|
4535
|
+
snapG?.remove();
|
|
4477
4536
|
const isFromCorner = isCornerHandle(board, resizeRef.handle);
|
|
4478
4537
|
const isAspectRatio = resizeState.isShift || PlaitDrawElement.isImage(resizeRef.element);
|
|
4479
|
-
const
|
|
4480
|
-
const
|
|
4538
|
+
const handleIndex = getIndexByResizeHandle(resizeRef.handle);
|
|
4539
|
+
const { originPoint, handlePoint } = getResizeOriginPointAndHandlePoint(board, handleIndex, resizeRef.rectangle);
|
|
4540
|
+
const resizeSnapRefOptions = getSnapResizingRefOptions(board, resizeRef, resizeState, {
|
|
4481
4541
|
originPoint,
|
|
4482
4542
|
handlePoint
|
|
4483
4543
|
}, isAspectRatio, isFromCorner);
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4544
|
+
const resizeSnapRef = getSnapResizingRef(board, [resizeRef.element], resizeSnapRefOptions);
|
|
4545
|
+
snapG = resizeSnapRef.snapG;
|
|
4546
|
+
PlaitBoard.getElementActiveHost(board).append(snapG);
|
|
4547
|
+
let points = resizeSnapRef.activePoints;
|
|
4487
4548
|
if (PlaitDrawElement.isGeometry(resizeRef.element)) {
|
|
4488
4549
|
const { height: textHeight } = getFirstTextManage(resizeRef.element).getSize();
|
|
4489
4550
|
DrawTransforms.resizeGeometry(board, points, textHeight, resizeRef.path);
|
|
@@ -4494,8 +4555,8 @@ const withGeometryResize = (board) => {
|
|
|
4494
4555
|
}
|
|
4495
4556
|
},
|
|
4496
4557
|
afterResize: (resizeRef) => {
|
|
4497
|
-
|
|
4498
|
-
|
|
4558
|
+
snapG?.remove();
|
|
4559
|
+
snapG = null;
|
|
4499
4560
|
}
|
|
4500
4561
|
};
|
|
4501
4562
|
withResize(board, options);
|
|
@@ -4751,9 +4812,8 @@ class ImageComponent extends CommonPluginElement {
|
|
|
4751
4812
|
get activeGenerator() {
|
|
4752
4813
|
return this.imageGenerator.componentRef.instance.activeGenerator;
|
|
4753
4814
|
}
|
|
4754
|
-
constructor(
|
|
4815
|
+
constructor(cdr) {
|
|
4755
4816
|
super(cdr);
|
|
4756
|
-
this.viewContainerRef = viewContainerRef;
|
|
4757
4817
|
this.cdr = cdr;
|
|
4758
4818
|
this.destroy$ = new Subject();
|
|
4759
4819
|
}
|
|
@@ -4780,14 +4840,14 @@ class ImageComponent extends CommonPluginElement {
|
|
|
4780
4840
|
ngOnInit() {
|
|
4781
4841
|
super.ngOnInit();
|
|
4782
4842
|
this.initializeGenerator();
|
|
4783
|
-
this.imageGenerator.processDrawing(this.element, this.
|
|
4843
|
+
this.imageGenerator.processDrawing(this.element, this.getElementG(), this.viewContainerRef);
|
|
4784
4844
|
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
|
|
4785
4845
|
selected: this.selected
|
|
4786
4846
|
});
|
|
4787
4847
|
}
|
|
4788
4848
|
onContextChanged(value, previous) {
|
|
4789
4849
|
if (value.element !== previous.element) {
|
|
4790
|
-
this.imageGenerator.updateImage(this.
|
|
4850
|
+
this.imageGenerator.updateImage(this.getElementG(), previous.element, value.element);
|
|
4791
4851
|
this.imageGenerator.componentRef.instance.isFocus = this.selected;
|
|
4792
4852
|
this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
|
|
4793
4853
|
selected: this.selected
|
|
@@ -4811,7 +4871,7 @@ class ImageComponent extends CommonPluginElement {
|
|
|
4811
4871
|
this.imageGenerator.destroy();
|
|
4812
4872
|
this.lineAutoCompleteGenerator.destroy();
|
|
4813
4873
|
}
|
|
4814
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: ImageComponent, deps: [{ token: i0.
|
|
4874
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: ImageComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4815
4875
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.4", type: ImageComponent, isStandalone: true, selector: "plait-draw-geometry", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4816
4876
|
}
|
|
4817
4877
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: ImageComponent, decorators: [{
|
|
@@ -4822,7 +4882,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImpor
|
|
|
4822
4882
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
4823
4883
|
standalone: true
|
|
4824
4884
|
}]
|
|
4825
|
-
}], ctorParameters: () => [{ type: i0.
|
|
4885
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
4826
4886
|
|
|
4827
4887
|
const withLineAutoCompleteReaction = (board) => {
|
|
4828
4888
|
const { pointerMove } = board;
|
|
@@ -4892,12 +4952,13 @@ const withLineAutoComplete = (board) => {
|
|
|
4892
4952
|
const rectangle = RectangleClient.getRectangleByPoints(sourceElement.points);
|
|
4893
4953
|
const shape = getElementShape(sourceElement);
|
|
4894
4954
|
const engine = getEngine(shape);
|
|
4955
|
+
let sourcePoint = autoCompletePoint;
|
|
4895
4956
|
if (engine.getNearestCrossingPoint) {
|
|
4896
4957
|
const crossingPoint = engine.getNearestCrossingPoint(rectangle, autoCompletePoint);
|
|
4897
|
-
|
|
4958
|
+
sourcePoint = crossingPoint;
|
|
4898
4959
|
}
|
|
4899
4960
|
// source point must be click point
|
|
4900
|
-
const rotatedSourcePoint = rotatePointsByElement(
|
|
4961
|
+
const rotatedSourcePoint = rotatePointsByElement(sourcePoint, sourceElement) || sourcePoint;
|
|
4901
4962
|
temporaryElement = handleLineCreating(board, LineShape.elbow, rotatedSourcePoint, movingPoint, sourceElement, lineShapeG);
|
|
4902
4963
|
}
|
|
4903
4964
|
}
|
|
@@ -4972,6 +5033,129 @@ const withLineTextMove = (board) => {
|
|
|
4972
5033
|
return board;
|
|
4973
5034
|
};
|
|
4974
5035
|
|
|
5036
|
+
const withDrawRotate = (board) => {
|
|
5037
|
+
const { pointerDown, pointerMove, globalPointerUp, afterChange, drawActiveRectangle } = board;
|
|
5038
|
+
let rotateRef = null;
|
|
5039
|
+
let rotateHandleG;
|
|
5040
|
+
let needCustomActiveRectangle = false;
|
|
5041
|
+
const canRotate = () => {
|
|
5042
|
+
const elements = getSelectedElements(board);
|
|
5043
|
+
return elements.length > 0 && elements.every(el => PlaitDrawElement.isGeometry(el) || PlaitDrawElement.isImage(el));
|
|
5044
|
+
};
|
|
5045
|
+
board.pointerDown = (event) => {
|
|
5046
|
+
if (!canRotate() || PlaitBoard.isReadonly(board) || PlaitBoard.hasBeenTextEditing(board) || !isMainPointer(event)) {
|
|
5047
|
+
pointerDown(event);
|
|
5048
|
+
return;
|
|
5049
|
+
}
|
|
5050
|
+
const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
5051
|
+
const elements = getSelectedElements(board);
|
|
5052
|
+
const boundingRectangle = getRectangleByElements(board, elements, false);
|
|
5053
|
+
const handleRectangle = getRotateHandleRectangle(boundingRectangle);
|
|
5054
|
+
const angle = getSelectionAngle(elements);
|
|
5055
|
+
const rotatedPoint = angle ? rotatePoints(point, RectangleClient.getCenterPoint(boundingRectangle), -angle) : point;
|
|
5056
|
+
if (handleRectangle && RectangleClient.isHit(RectangleClient.getRectangleByPoints([rotatedPoint, rotatedPoint]), handleRectangle)) {
|
|
5057
|
+
rotateRef = {
|
|
5058
|
+
elements: elements,
|
|
5059
|
+
startPoint: point
|
|
5060
|
+
};
|
|
5061
|
+
}
|
|
5062
|
+
pointerDown(event);
|
|
5063
|
+
};
|
|
5064
|
+
board.pointerMove = (event) => {
|
|
5065
|
+
if (rotateRef) {
|
|
5066
|
+
event.preventDefault();
|
|
5067
|
+
const isShift = !!event.shiftKey;
|
|
5068
|
+
addRotating(board, rotateRef);
|
|
5069
|
+
const endPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
|
|
5070
|
+
const selectionRectangle = getRectangleByElements(board, rotateRef.elements, false);
|
|
5071
|
+
const selectionCenterPoint = RectangleClient.getCenterPoint(selectionRectangle);
|
|
5072
|
+
if (!getSelectionAngle(rotateRef.elements) && rotateRef.elements.length > 1) {
|
|
5073
|
+
needCustomActiveRectangle = true;
|
|
5074
|
+
}
|
|
5075
|
+
throttleRAF(board, 'with-common-rotate', () => {
|
|
5076
|
+
if (rotateRef && rotateRef.startPoint) {
|
|
5077
|
+
let angle = getAngleBetweenPoints(rotateRef.startPoint, endPoint, selectionCenterPoint);
|
|
5078
|
+
if (isShift) {
|
|
5079
|
+
angle += Math.PI / 12 / 2;
|
|
5080
|
+
angle -= angle % (Math.PI / 12);
|
|
5081
|
+
}
|
|
5082
|
+
const selectionAngle = getSelectionAngle(rotateRef.elements);
|
|
5083
|
+
let remainder = (selectionAngle + angle) % (Math.PI / 2);
|
|
5084
|
+
if (Math.PI / 2 - remainder <= degreesToRadians(5)) {
|
|
5085
|
+
const snapAngle = Math.PI / 2 - remainder;
|
|
5086
|
+
angle += snapAngle;
|
|
5087
|
+
}
|
|
5088
|
+
if (remainder <= degreesToRadians(5)) {
|
|
5089
|
+
const snapAngle = -remainder;
|
|
5090
|
+
angle += snapAngle;
|
|
5091
|
+
}
|
|
5092
|
+
rotateRef.angle = normalizeAngle(angle);
|
|
5093
|
+
if (rotateRef.angle) {
|
|
5094
|
+
rotateElements(board, rotateRef.elements, rotateRef.angle);
|
|
5095
|
+
}
|
|
5096
|
+
PlaitBoard.getBoardContainer(board).classList.add('element-rotating');
|
|
5097
|
+
}
|
|
5098
|
+
});
|
|
5099
|
+
return;
|
|
5100
|
+
}
|
|
5101
|
+
pointerMove(event);
|
|
5102
|
+
};
|
|
5103
|
+
board.globalPointerUp = (event) => {
|
|
5104
|
+
globalPointerUp(event);
|
|
5105
|
+
if (needCustomActiveRectangle) {
|
|
5106
|
+
needCustomActiveRectangle = false;
|
|
5107
|
+
const selectedElements = getSelectedElements(board);
|
|
5108
|
+
Transforms.addSelectionWithTemporaryElements(board, selectedElements);
|
|
5109
|
+
}
|
|
5110
|
+
PlaitBoard.getBoardContainer(board).classList.remove('element-rotating');
|
|
5111
|
+
removeRotating(board);
|
|
5112
|
+
rotateRef = null;
|
|
5113
|
+
MERGING.set(board, false);
|
|
5114
|
+
preventTouchMove(board, event, false);
|
|
5115
|
+
};
|
|
5116
|
+
board.afterChange = () => {
|
|
5117
|
+
afterChange();
|
|
5118
|
+
if (rotateHandleG) {
|
|
5119
|
+
rotateHandleG.remove();
|
|
5120
|
+
rotateHandleG = null;
|
|
5121
|
+
}
|
|
5122
|
+
if (canRotate() && !isSelectionMoving(board)) {
|
|
5123
|
+
if (needCustomActiveRectangle && rotateRef) {
|
|
5124
|
+
const boundingRectangle = getRectangleByElements(board, rotateRef.elements, false);
|
|
5125
|
+
rotateHandleG = drawRotateHandle(board, boundingRectangle);
|
|
5126
|
+
rotateHandleG.classList.add(ROTATE_HANDLE_CLASS_NAME);
|
|
5127
|
+
if (rotateRef.angle) {
|
|
5128
|
+
setAngleForG(rotateHandleG, RectangleClient.getCenterPoint(boundingRectangle), rotateRef.angle);
|
|
5129
|
+
}
|
|
5130
|
+
}
|
|
5131
|
+
else {
|
|
5132
|
+
const elements = getSelectedElements(board);
|
|
5133
|
+
const boundingRectangle = getRectangleByElements(board, elements, false);
|
|
5134
|
+
rotateHandleG = drawRotateHandle(board, boundingRectangle);
|
|
5135
|
+
rotateHandleG.classList.add(ROTATE_HANDLE_CLASS_NAME);
|
|
5136
|
+
setAngleForG(rotateHandleG, RectangleClient.getCenterPoint(boundingRectangle), getSelectionAngle(elements));
|
|
5137
|
+
}
|
|
5138
|
+
PlaitBoard.getElementActiveHost(board).append(rotateHandleG);
|
|
5139
|
+
}
|
|
5140
|
+
};
|
|
5141
|
+
board.drawActiveRectangle = () => {
|
|
5142
|
+
if (needCustomActiveRectangle && rotateRef) {
|
|
5143
|
+
const rectangle = getRectangleByElements(board, rotateRef.elements, false);
|
|
5144
|
+
const rectangleG = drawRectangle(board, RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH), {
|
|
5145
|
+
stroke: SELECTION_BORDER_COLOR,
|
|
5146
|
+
strokeWidth: ACTIVE_STROKE_WIDTH
|
|
5147
|
+
});
|
|
5148
|
+
rectangleG.classList.add(SELECTION_RECTANGLE_CLASS_NAME);
|
|
5149
|
+
if (rotateRef.angle) {
|
|
5150
|
+
setAngleForG(rectangleG, RectangleClient.getCenterPoint(rectangle), rotateRef.angle);
|
|
5151
|
+
}
|
|
5152
|
+
return rectangleG;
|
|
5153
|
+
}
|
|
5154
|
+
return drawActiveRectangle();
|
|
5155
|
+
};
|
|
5156
|
+
return board;
|
|
5157
|
+
};
|
|
5158
|
+
|
|
4975
5159
|
const withDraw = (board) => {
|
|
4976
5160
|
const { drawElement, getRectangle, isRectangleHit, isHit, isInsidePoint, isMovable, isAlign, getRelatedFragment } = board;
|
|
4977
5161
|
board.drawElement = (context) => {
|
|
@@ -5067,12 +5251,12 @@ const withDraw = (board) => {
|
|
|
5067
5251
|
});
|
|
5068
5252
|
return getRelatedFragment([...elements, ...activeLines], originData);
|
|
5069
5253
|
};
|
|
5070
|
-
return withDrawResize(withLineTextMove(withLineAutoCompleteReaction(withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withLineAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))))))));
|
|
5254
|
+
return withDrawResize(withLineTextMove(withLineAutoCompleteReaction(withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withDrawRotate(withLineCreateByDraw(withLineAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board))))))))))))));
|
|
5071
5255
|
};
|
|
5072
5256
|
|
|
5073
5257
|
/**
|
|
5074
5258
|
* Generated bundle index. Do not edit.
|
|
5075
5259
|
*/
|
|
5076
5260
|
|
|
5077
|
-
export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultBasicShapeProperty, DefaultConnectorProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultGeometryActiveStyle, DefaultGeometryStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultTextProperty, DrawThemeColors, DrawTransforms, FlowchartSymbols, GeometryComponent, GeometryThreshold, LINE_HIT_GEOMETRY_BUFFER, LINE_SNAPPING_BUFFER, LINE_SNAPPING_CONNECTOR_BUFFER, LineComponent, LineHandleKey, LineMarkerType, LineShape, MemorizeKey, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, ShapeDefaultSpace, StrokeStyle, WithLineAutoCompletePluginKey, alignElbowSegment, alignPoints, createDefaultFlowchart, createDefaultGeometry, createGeometryElement, createLineElement, createTextElement, drawBoundReaction, drawGeometry, drawLine, drawLineArrow, getAutoCompletePoints, getBasicPointers, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultTextPoints, getDrawDefaultStrokeColor, getElbowLineRouteOptions, getElbowPoints, getFillByElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryPointers, getHitConnection, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getIndexAndDeleteCountByKeyPoint, getLineDashByElement, getLineHandleRefPair, getLineMemorizedLatest, getLinePointers, getLinePoints, getLineTextRectangle, getLines, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getMidKeyPoints, getMiddlePoints, getMirrorDataPoints, getNearestPoint, getNextRenderPoints, getNextSourceAndTargetPoints, getResizedPreviousAndNextPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getSourceAndTargetRectangle, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getTextShapeProperty, getVectorByConnection, handleLineCreating, hasIllegalElbowPoint, insertElement, isHitDrawElement, isHitEdgeOfShape, isHitElementInside, isHitLine, isHitLineText, isHitPolyLine, isInsideOfShape, isRectangleHitDrawElement, isSelfLoop, isTextExceedingBounds, isUpdatedHandleIndex, isUseDefaultOrthogonalRoute, memorizeLatestShape, memorizeLatestText, withDraw, withLineAutoComplete };
|
|
5261
|
+
export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultBasicShapeProperty, DefaultCloudShapeProperty, DefaultConnectorProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultGeometryActiveStyle, DefaultGeometryStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultTextProperty, DrawThemeColors, DrawTransforms, FlowchartSymbols, GeometryComponent, GeometryThreshold, LINE_HIT_GEOMETRY_BUFFER, LINE_SNAPPING_BUFFER, LINE_SNAPPING_CONNECTOR_BUFFER, LineComponent, LineHandleKey, LineMarkerType, LineShape, MemorizeKey, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, ShapeDefaultSpace, StrokeStyle, WithLineAutoCompletePluginKey, alignElbowSegment, alignPoints, createDefaultFlowchart, createDefaultGeometry, createGeometryElement, createLineElement, createTextElement, drawBoundReaction, drawGeometry, drawLine, drawLineArrow, getAutoCompletePoints, getBasicPointers, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultTextPoints, getDrawDefaultStrokeColor, getElbowLineRouteOptions, getElbowPoints, getFillByElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryPointers, getHitConnection, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getIndexAndDeleteCountByKeyPoint, getLineDashByElement, getLineHandleRefPair, getLineMemorizedLatest, getLinePointers, getLinePoints, getLineTextRectangle, getLines, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getMidKeyPoints, getMiddlePoints, getMirrorDataPoints, getNearestPoint, getNextRenderPoints, getNextSourceAndTargetPoints, getResizedPreviousAndNextPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getSourceAndTargetRectangle, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getTextShapeProperty, getVectorByConnection, handleLineCreating, hasIllegalElbowPoint, insertElement, isHitDrawElement, isHitEdgeOfShape, isHitElementInside, isHitLine, isHitLineText, isHitPolyLine, isInsideOfShape, isRectangleHitDrawElement, isSelfLoop, isTextExceedingBounds, isUpdatedHandleIndex, isUseDefaultOrthogonalRoute, memorizeLatestShape, memorizeLatestText, withDraw, withLineAutoComplete };
|
|
5078
5262
|
//# sourceMappingURL=plait-draw.mjs.map
|