@plait/draw 0.1.0-next.8 → 0.28.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/image.d.ts +1 -0
- package/constants/index.d.ts +1 -0
- package/constants/pointer.d.ts +4 -10
- package/engines/comment.d.ts +4 -0
- package/engines/cross.d.ts +4 -0
- package/{utils/engine → engines}/diamond.d.ts +1 -1
- package/{utils/engine → engines}/ellipse.d.ts +1 -1
- package/engines/hexagon.d.ts +4 -0
- package/{utils/engine → engines}/index.d.ts +1 -1
- package/engines/left-arrow.d.ts +4 -0
- package/engines/octagon.d.ts +4 -0
- package/engines/parallelogram.d.ts +4 -0
- package/engines/pentagon-arrow.d.ts +4 -0
- package/engines/pentagon.d.ts +4 -0
- package/engines/process-arrow.d.ts +4 -0
- package/{utils/engine → engines}/rectangle.d.ts +1 -1
- package/engines/right-arrow.d.ts +4 -0
- package/engines/round-comment.d.ts +4 -0
- package/{utils/engine → engines}/round-rectangle.d.ts +1 -1
- package/engines/star.d.ts +4 -0
- package/engines/trapezoid.d.ts +4 -0
- package/engines/triangle.d.ts +4 -0
- package/engines/two-way-arrow.d.ts +4 -0
- package/esm2022/constants/geometry.mjs +3 -3
- package/esm2022/constants/image.mjs +2 -0
- package/esm2022/constants/index.mjs +2 -1
- package/esm2022/constants/pointer.mjs +8 -19
- package/esm2022/engines/comment.mjs +57 -0
- package/esm2022/engines/cross.mjs +46 -0
- package/esm2022/engines/diamond.mjs +30 -0
- package/esm2022/engines/ellipse.mjs +92 -0
- package/esm2022/engines/hexagon.mjs +40 -0
- package/esm2022/engines/index.mjs +46 -0
- package/esm2022/engines/left-arrow.mjs +45 -0
- package/esm2022/engines/octagon.mjs +42 -0
- package/esm2022/engines/parallelogram.mjs +39 -0
- package/esm2022/engines/pentagon-arrow.mjs +39 -0
- package/esm2022/engines/pentagon.mjs +39 -0
- package/esm2022/engines/process-arrow.mjs +41 -0
- package/esm2022/engines/rectangle.mjs +26 -0
- package/esm2022/engines/right-arrow.mjs +45 -0
- package/esm2022/engines/round-comment.mjs +81 -0
- package/esm2022/engines/round-rectangle.mjs +59 -0
- package/esm2022/engines/star.mjs +45 -0
- package/esm2022/engines/trapezoid.mjs +40 -0
- package/esm2022/engines/triangle.mjs +40 -0
- package/esm2022/engines/two-way-arrow.mjs +48 -0
- package/esm2022/generators/geometry-shape.generator.mjs +7 -2
- package/esm2022/generators/line-active.generator.mjs +71 -22
- package/esm2022/generators/line.generator.mjs +2 -11
- package/esm2022/geometry.component.mjs +22 -7
- package/esm2022/image.component.mjs +70 -0
- package/esm2022/interfaces/geometry.mjs +15 -1
- package/esm2022/interfaces/image.mjs +2 -0
- package/esm2022/interfaces/index.mjs +8 -2
- package/esm2022/interfaces/line.mjs +27 -4
- package/esm2022/line.component.mjs +15 -6
- package/esm2022/plugins/with-draw-fragment.mjs +37 -7
- package/esm2022/plugins/with-draw.mjs +38 -10
- package/esm2022/plugins/with-geometry-create.mjs +15 -12
- package/esm2022/plugins/with-geometry-resize.mjs +28 -20
- package/esm2022/plugins/with-line-bound-reaction.mjs +10 -5
- package/esm2022/plugins/with-line-create.mjs +7 -5
- package/esm2022/plugins/with-line-resize.mjs +12 -4
- package/esm2022/transforms/geometry-text.mjs +1 -1
- package/esm2022/transforms/image.mjs +23 -0
- package/esm2022/transforms/index.mjs +4 -2
- package/esm2022/utils/clipboard.mjs +4 -3
- package/esm2022/utils/geometry.mjs +20 -6
- package/esm2022/utils/index.mjs +1 -1
- package/esm2022/utils/line-arrow.mjs +43 -18
- package/esm2022/utils/line.mjs +203 -52
- package/esm2022/utils/position/geometry.mjs +5 -4
- package/esm2022/utils/position/line.mjs +32 -22
- package/esm2022/utils/selected.mjs +5 -1
- package/esm2022/utils/shape.mjs +8 -0
- package/esm2022/utils/style/stroke.mjs +5 -2
- package/fesm2022/plait-draw.mjs +1450 -279
- package/fesm2022/plait-draw.mjs.map +1 -1
- package/generators/line-active.generator.d.ts +3 -0
- package/generators/line.generator.d.ts +1 -1
- package/geometry.component.d.ts +1 -1
- package/image.component.d.ts +20 -0
- package/interfaces/geometry.d.ts +20 -2
- package/interfaces/image.d.ts +7 -0
- package/interfaces/index.d.ts +5 -1
- package/interfaces/line.d.ts +19 -5
- package/line.component.d.ts +2 -1
- package/package.json +3 -2
- package/plugins/with-draw-fragment.d.ts +2 -0
- package/plugins/with-geometry-create.d.ts +1 -1
- package/styles/styles.scss +2 -2
- package/transforms/image.d.ts +3 -0
- package/transforms/index.d.ts +1 -0
- package/utils/geometry.d.ts +1 -0
- package/utils/line.d.ts +14 -6
- package/utils/position/geometry.d.ts +2 -1
- package/utils/position/line.d.ts +7 -3
- package/utils/selected.d.ts +2 -0
- package/utils/shape.d.ts +2 -0
- package/esm2022/utils/engine/diamond.mjs +0 -22
- package/esm2022/utils/engine/ellipse.mjs +0 -55
- package/esm2022/utils/engine/index.mjs +0 -18
- package/esm2022/utils/engine/parallelogram.mjs +0 -32
- package/esm2022/utils/engine/rectangle.mjs +0 -18
- package/esm2022/utils/engine/round-rectangle.mjs +0 -49
- package/utils/engine/parallelogram.d.ts +0 -4
package/fesm2022/plait-draw.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { PlaitElement, ACTIVE_STROKE_WIDTH,
|
|
1
|
+
import { PlaitElement, ACTIVE_STROKE_WIDTH, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, idCreator, createG, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, arrowPoints, createPath, drawLinearPath, rotate, getElementById, distanceBetweenPointAndPoint, distanceBetweenPointAndSegments, createMask, createRect, findElements, getSelectedElements, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Point, BOARD_TO_HOST, transformPoint, toPoint, isSelectionMoving, PlaitPluginElementComponent, BoardTransforms, PlaitPointerType, preventTouchMove, createForeignObject, setClipboardData, getDataFromClipboard, depthFirstRecursion, getIsRecursionFunc, getHitElements, isPolylineHitRectangle } from '@plait/core';
|
|
2
|
+
import { getRectangleByPoints, getFactorByPoints, getDirectionByVector, getOppositeDirection, getDirectionFactor, getPoints, getPointByVector, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90, Generator, normalizeShapePoints, CommonPluginElement, ActiveGenerator, WithTextPluginKey, RESIZE_HANDLE_DIAMETER, PRIMARY_COLOR, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, acceptImageTypes, buildImage, getRectangleResizeHandleRefs, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint, ImageGenerator } from '@plait/common';
|
|
3
|
+
import { Alignment, buildText, AlignEditor, TextManage, DEFAULT_FONT_SIZE, getTextFromClipboard, getTextSize } from '@plait/text';
|
|
4
|
+
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
2
5
|
import * as i0 from '@angular/core';
|
|
3
6
|
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
|
4
7
|
import { Subject } from 'rxjs';
|
|
5
|
-
import { getRectangleByPoints, getFactorByPoints, Direction, getDirectionByPoint, getPoints, getPointOnPolyline, getDirectionFactor, Generator, normalizeShapePoints, CommonPluginElement, ActiveGenerator, WithTextPluginKey, RESIZE_HANDLE_DIAMETER, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, getRectangleResizeHandleRefs, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint } from '@plait/common';
|
|
6
|
-
import { Alignment, buildText, AlignEditor, TextManage, DEFAULT_FONT_SIZE, getTextFromClipboard, getTextSize } from '@plait/text';
|
|
7
8
|
import { isKeyHotkey } from 'is-hotkey';
|
|
8
9
|
import { Node } from 'slate';
|
|
9
10
|
|
|
@@ -15,6 +16,20 @@ var GeometryShape;
|
|
|
15
16
|
GeometryShape["roundRectangle"] = "roundRectangle";
|
|
16
17
|
GeometryShape["parallelogram"] = "parallelogram";
|
|
17
18
|
GeometryShape["text"] = "text";
|
|
19
|
+
GeometryShape["triangle"] = "triangle";
|
|
20
|
+
GeometryShape["leftArrow"] = "leftArrow";
|
|
21
|
+
GeometryShape["trapezoid"] = "trapezoid";
|
|
22
|
+
GeometryShape["rightArrow"] = "rightArrow";
|
|
23
|
+
GeometryShape["cross"] = "cross";
|
|
24
|
+
GeometryShape["star"] = "star";
|
|
25
|
+
GeometryShape["pentagon"] = "pentagon";
|
|
26
|
+
GeometryShape["hexagon"] = "hexagon";
|
|
27
|
+
GeometryShape["octagon"] = "octagon";
|
|
28
|
+
GeometryShape["pentagonArrow"] = "pentagonArrow";
|
|
29
|
+
GeometryShape["processArrow"] = "processArrow";
|
|
30
|
+
GeometryShape["twoWayArrow"] = "twoWayArrow";
|
|
31
|
+
GeometryShape["comment"] = "comment";
|
|
32
|
+
GeometryShape["roundComment"] = "roundComment";
|
|
18
33
|
})(GeometryShape || (GeometryShape = {}));
|
|
19
34
|
const PlaitGeometry = {
|
|
20
35
|
getTextEditor(element) {
|
|
@@ -29,79 +44,6 @@ const PlaitGeometry = {
|
|
|
29
44
|
}
|
|
30
45
|
};
|
|
31
46
|
|
|
32
|
-
var LineMarkerType;
|
|
33
|
-
(function (LineMarkerType) {
|
|
34
|
-
LineMarkerType["arrow"] = "arrow";
|
|
35
|
-
LineMarkerType["none"] = "none";
|
|
36
|
-
LineMarkerType["openTriangle"] = "open-triangle";
|
|
37
|
-
LineMarkerType["solidTriangle"] = "solid-triangle";
|
|
38
|
-
LineMarkerType["sharpArrow"] = "sharp-arrow";
|
|
39
|
-
})(LineMarkerType || (LineMarkerType = {}));
|
|
40
|
-
var LineShape;
|
|
41
|
-
(function (LineShape) {
|
|
42
|
-
LineShape["straight"] = "straight";
|
|
43
|
-
LineShape["curve"] = "curve";
|
|
44
|
-
LineShape["elbow"] = "elbow";
|
|
45
|
-
})(LineShape || (LineShape = {}));
|
|
46
|
-
var LineHandleKey;
|
|
47
|
-
(function (LineHandleKey) {
|
|
48
|
-
LineHandleKey["source"] = "source";
|
|
49
|
-
LineHandleKey["target"] = "target";
|
|
50
|
-
})(LineHandleKey || (LineHandleKey = {}));
|
|
51
|
-
const PlaitLine = {
|
|
52
|
-
getTextEditors(element) {
|
|
53
|
-
const component = PlaitElement.getComponent(element);
|
|
54
|
-
if (component) {
|
|
55
|
-
const manage = component.textManages.find(manage => manage.isEditing);
|
|
56
|
-
if (manage) {
|
|
57
|
-
return [manage.componentRef.instance.editor];
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
return component.textManages.map(manage => manage.componentRef.instance.editor);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
throw new Error('can not get correctly component in get text editor');
|
|
64
|
-
},
|
|
65
|
-
isSourceMark(line, markType) {
|
|
66
|
-
return line.source.marker === markType;
|
|
67
|
-
},
|
|
68
|
-
isTargetMark(line, markType) {
|
|
69
|
-
return line.target.marker === markType;
|
|
70
|
-
},
|
|
71
|
-
isBoundElementOfSource(line, element) {
|
|
72
|
-
return line.source.boundId === element.id;
|
|
73
|
-
},
|
|
74
|
-
isBoundElementOfTarget(line, element) {
|
|
75
|
-
return line.target.boundId === element.id;
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
var StrokeStyle;
|
|
80
|
-
(function (StrokeStyle) {
|
|
81
|
-
StrokeStyle["solid"] = "solid";
|
|
82
|
-
StrokeStyle["dashed"] = "dashed";
|
|
83
|
-
})(StrokeStyle || (StrokeStyle = {}));
|
|
84
|
-
|
|
85
|
-
const PlaitDrawElement = {
|
|
86
|
-
isGeometry: (value) => {
|
|
87
|
-
return value.type === 'geometry';
|
|
88
|
-
},
|
|
89
|
-
isLine: (value) => {
|
|
90
|
-
return value.type === 'line';
|
|
91
|
-
},
|
|
92
|
-
isText: (value) => {
|
|
93
|
-
return value.type === 'geometry' && value.shape === GeometryShape.text;
|
|
94
|
-
},
|
|
95
|
-
isDrawElement: (value) => {
|
|
96
|
-
if (PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isLine(value)) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
|
|
105
47
|
const ShapeDefaultSpace = {
|
|
106
48
|
rectangleAndText: 4
|
|
107
49
|
};
|
|
@@ -127,29 +69,22 @@ const DefaultTextProperty = {
|
|
|
127
69
|
text: '文本'
|
|
128
70
|
};
|
|
129
71
|
const GeometryThreshold = {
|
|
130
|
-
defaultTextMaxWidth: 34 * 14
|
|
72
|
+
defaultTextMaxWidth: 34 * 14
|
|
131
73
|
};
|
|
132
74
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
DrawPointerType["ellipse"] = "ellipse";
|
|
142
|
-
})(DrawPointerType || (DrawPointerType = {}));
|
|
143
|
-
const GeometryPointer = [
|
|
144
|
-
DrawPointerType.rectangle,
|
|
145
|
-
DrawPointerType.text,
|
|
146
|
-
DrawPointerType.diamond,
|
|
147
|
-
DrawPointerType.ellipse,
|
|
148
|
-
DrawPointerType.parallelogram,
|
|
149
|
-
DrawPointerType.roundRectangle
|
|
150
|
-
];
|
|
75
|
+
const getGeometryPointers = () => {
|
|
76
|
+
return Object.keys(GeometryShape);
|
|
77
|
+
};
|
|
78
|
+
const getLinePointers = () => {
|
|
79
|
+
return Object.keys(LineShape);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const DEFAULT_IMAGE_WIDTH = 1000;
|
|
151
83
|
|
|
152
84
|
const getStrokeWidthByElement = (element) => {
|
|
85
|
+
if (PlaitDrawElement.isText(element)) {
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
153
88
|
const strokeWidth = element.strokeWidth || DefaultGeometryStyle.strokeWidth;
|
|
154
89
|
return strokeWidth;
|
|
155
90
|
};
|
|
@@ -168,6 +103,102 @@ const getStrokeStyleByElement = (element) => {
|
|
|
168
103
|
return element.strokeStyle || StrokeStyle.solid;
|
|
169
104
|
};
|
|
170
105
|
|
|
106
|
+
const heightRatio$1 = 3 / 4;
|
|
107
|
+
const CommentEngine = {
|
|
108
|
+
draw(board, rectangle, options) {
|
|
109
|
+
const points = getCommentPoints(rectangle);
|
|
110
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
111
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
112
|
+
setStrokeLinecap(polygon, 'round');
|
|
113
|
+
return polygon;
|
|
114
|
+
},
|
|
115
|
+
isHit(rectangle, point) {
|
|
116
|
+
const parallelogramPoints = getCommentPoints(rectangle);
|
|
117
|
+
return isPointInPolygon(point, parallelogramPoints);
|
|
118
|
+
},
|
|
119
|
+
getCornerPoints(rectangle) {
|
|
120
|
+
return getCommentPoints(rectangle);
|
|
121
|
+
},
|
|
122
|
+
getNearestPoint(rectangle, point) {
|
|
123
|
+
return getNearestPointBetweenPointAndSegments(point, getCommentPoints(rectangle));
|
|
124
|
+
},
|
|
125
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
126
|
+
const corners = getCommentPoints(rectangle);
|
|
127
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
128
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
129
|
+
},
|
|
130
|
+
getConnectorPoints(rectangle) {
|
|
131
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
132
|
+
},
|
|
133
|
+
getTextRectangle(element) {
|
|
134
|
+
const elementRectangle = getRectangleByPoints(element.points);
|
|
135
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
136
|
+
const height = element.textHeight;
|
|
137
|
+
const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
|
|
138
|
+
return {
|
|
139
|
+
height,
|
|
140
|
+
width: width > 0 ? width : 0,
|
|
141
|
+
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
|
|
142
|
+
y: elementRectangle.y + (elementRectangle.height * heightRatio$1 - height) / 2
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const getCommentPoints = (rectangle) => {
|
|
147
|
+
return [
|
|
148
|
+
[rectangle.x, rectangle.y],
|
|
149
|
+
[rectangle.x + rectangle.width, rectangle.y],
|
|
150
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height * heightRatio$1],
|
|
151
|
+
[rectangle.x + (rectangle.width * 3) / 5, rectangle.y + rectangle.height * heightRatio$1],
|
|
152
|
+
[rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height],
|
|
153
|
+
[rectangle.x + (rectangle.width * 2) / 5, rectangle.y + rectangle.height * heightRatio$1],
|
|
154
|
+
[rectangle.x, rectangle.y + rectangle.height * heightRatio$1]
|
|
155
|
+
];
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const CrossEngine = {
|
|
159
|
+
draw(board, rectangle, options) {
|
|
160
|
+
const points = getCrossPoints(rectangle);
|
|
161
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
162
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
163
|
+
setStrokeLinecap(polygon, 'round');
|
|
164
|
+
return polygon;
|
|
165
|
+
},
|
|
166
|
+
isHit(rectangle, point) {
|
|
167
|
+
const parallelogramPoints = getCrossPoints(rectangle);
|
|
168
|
+
return isPointInPolygon(point, parallelogramPoints);
|
|
169
|
+
},
|
|
170
|
+
getCornerPoints(rectangle) {
|
|
171
|
+
return getCrossPoints(rectangle);
|
|
172
|
+
},
|
|
173
|
+
getNearestPoint(rectangle, point) {
|
|
174
|
+
return getNearestPointBetweenPointAndSegments(point, getCrossPoints(rectangle));
|
|
175
|
+
},
|
|
176
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
177
|
+
const corners = getCrossPoints(rectangle);
|
|
178
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
179
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
180
|
+
},
|
|
181
|
+
getConnectorPoints(rectangle) {
|
|
182
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
const getCrossPoints = (rectangle) => {
|
|
186
|
+
return [
|
|
187
|
+
[rectangle.x + rectangle.width / 4, rectangle.y],
|
|
188
|
+
[rectangle.x + (rectangle.width * 3) / 4, rectangle.y],
|
|
189
|
+
[rectangle.x + (rectangle.width * 3) / 4, rectangle.y + rectangle.height / 4],
|
|
190
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 4],
|
|
191
|
+
[rectangle.x + rectangle.width, rectangle.y + (rectangle.height * 3) / 4],
|
|
192
|
+
[rectangle.x + (rectangle.width * 3) / 4, rectangle.y + (rectangle.height * 3) / 4],
|
|
193
|
+
[rectangle.x + (rectangle.width * 3) / 4, rectangle.y + rectangle.height],
|
|
194
|
+
[rectangle.x + rectangle.width / 4, rectangle.y + rectangle.height],
|
|
195
|
+
[rectangle.x + rectangle.width / 4, rectangle.y + (rectangle.height * 3) / 4],
|
|
196
|
+
[rectangle.x, rectangle.y + (rectangle.height * 3) / 4],
|
|
197
|
+
[rectangle.x, rectangle.y + rectangle.height / 4],
|
|
198
|
+
[rectangle.x + rectangle.width / 4, rectangle.y + rectangle.height / 4]
|
|
199
|
+
];
|
|
200
|
+
};
|
|
201
|
+
|
|
171
202
|
const DiamondEngine = {
|
|
172
203
|
draw(board, rectangle, options) {
|
|
173
204
|
const points = RectangleClient.getEdgeCenterPoints(rectangle);
|
|
@@ -180,9 +211,16 @@ const DiamondEngine = {
|
|
|
180
211
|
const controlPoints = RectangleClient.getEdgeCenterPoints(rectangle);
|
|
181
212
|
return isPointInPolygon(point, controlPoints);
|
|
182
213
|
},
|
|
214
|
+
getCornerPoints(rectangle) {
|
|
215
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
216
|
+
},
|
|
183
217
|
getNearestPoint(rectangle, point) {
|
|
184
|
-
|
|
185
|
-
|
|
218
|
+
return getNearestPointBetweenPointAndSegments(point, DiamondEngine.getCornerPoints(rectangle));
|
|
219
|
+
},
|
|
220
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
221
|
+
const corners = DiamondEngine.getCornerPoints(rectangle);
|
|
222
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
223
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
186
224
|
},
|
|
187
225
|
getConnectorPoints(rectangle) {
|
|
188
226
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
@@ -199,10 +237,22 @@ const EllipseEngine = {
|
|
|
199
237
|
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
200
238
|
return isPointInEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
|
|
201
239
|
},
|
|
240
|
+
getCornerPoints(rectangle) {
|
|
241
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
242
|
+
},
|
|
202
243
|
getNearestPoint(rectangle, point) {
|
|
203
244
|
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
204
245
|
return getNearestPointBetweenPointAndEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
|
|
205
246
|
},
|
|
247
|
+
getTangentVectorByConnectionPoint(rectangle, pointOfRectangle) {
|
|
248
|
+
const connectionPoint = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
249
|
+
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
250
|
+
const point = [connectionPoint[0] - centerPoint[0], -(connectionPoint[1] - centerPoint[1])];
|
|
251
|
+
const a = rectangle.width / 2;
|
|
252
|
+
const b = rectangle.height / 2;
|
|
253
|
+
const slope = getTangentSlope(point[0], point[1], a, b);
|
|
254
|
+
return getVectorBySlope(point[0], point[1], slope);
|
|
255
|
+
},
|
|
206
256
|
getConnectorPoints(rectangle) {
|
|
207
257
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
208
258
|
}
|
|
@@ -242,29 +292,182 @@ function getNearestPointBetweenPointAndEllipse(point, center, rx, ry, rotation =
|
|
|
242
292
|
const signY = point[1] > center[1] ? 1 : -1;
|
|
243
293
|
return [center[0] + a * tx * signX, center[1] + b * ty * signY];
|
|
244
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* the result of slope is based on Cartesian coordinate system
|
|
297
|
+
* x, y are based on the position in the Cartesian coordinate system
|
|
298
|
+
*/
|
|
299
|
+
function getTangentSlope(x, y, a, b) {
|
|
300
|
+
const k = (-b * b * x) / (a * a * y);
|
|
301
|
+
return k;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* x, y are based on the position in the Cartesian coordinate system
|
|
305
|
+
*/
|
|
306
|
+
function getVectorBySlope(x, y, slope) {
|
|
307
|
+
const deltaX = 30;
|
|
308
|
+
const deltaY = -slope * deltaX;
|
|
309
|
+
let start = [0 - deltaX, 0 - deltaY];
|
|
310
|
+
let end = [0 + deltaX, 0 + deltaY];
|
|
311
|
+
// y < 0 acts on the lower half of the x-axis, with the starting point at the top and the end point at the bottom.
|
|
312
|
+
if (y < 0) {
|
|
313
|
+
const temp = start;
|
|
314
|
+
start = end;
|
|
315
|
+
end = temp;
|
|
316
|
+
}
|
|
317
|
+
const vector = [end[0] - start[0], end[1] - start[1]];
|
|
318
|
+
return vector;
|
|
319
|
+
}
|
|
245
320
|
|
|
246
|
-
const
|
|
321
|
+
const HexagonEngine = {
|
|
247
322
|
draw(board, rectangle, options) {
|
|
248
|
-
const points =
|
|
323
|
+
const points = getHexagonPoints(rectangle);
|
|
249
324
|
const rs = PlaitBoard.getRoughSVG(board);
|
|
250
325
|
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
251
326
|
setStrokeLinecap(polygon, 'round');
|
|
252
327
|
return polygon;
|
|
253
328
|
},
|
|
254
329
|
isHit(rectangle, point) {
|
|
255
|
-
const parallelogramPoints =
|
|
330
|
+
const parallelogramPoints = getHexagonPoints(rectangle);
|
|
256
331
|
return isPointInPolygon(point, parallelogramPoints);
|
|
257
332
|
},
|
|
333
|
+
getCornerPoints(rectangle) {
|
|
334
|
+
return getHexagonPoints(rectangle);
|
|
335
|
+
},
|
|
258
336
|
getNearestPoint(rectangle, point) {
|
|
259
|
-
|
|
337
|
+
return getNearestPointBetweenPointAndSegments(point, getHexagonPoints(rectangle));
|
|
338
|
+
},
|
|
339
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
340
|
+
const corners = getHexagonPoints(rectangle);
|
|
341
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
342
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
343
|
+
},
|
|
344
|
+
getConnectorPoints(rectangle) {
|
|
345
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
const getHexagonPoints = (rectangle) => {
|
|
349
|
+
return [
|
|
350
|
+
[rectangle.x + rectangle.width / 4, rectangle.y],
|
|
351
|
+
[rectangle.x + (rectangle.width * 3) / 4, rectangle.y],
|
|
352
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2],
|
|
353
|
+
[rectangle.x + (rectangle.width * 3) / 4, rectangle.y + rectangle.height],
|
|
354
|
+
[rectangle.x + rectangle.width / 4, rectangle.y + rectangle.height],
|
|
355
|
+
[rectangle.x, rectangle.y + rectangle.height / 2]
|
|
356
|
+
];
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const LeftArrowEngine = {
|
|
360
|
+
draw(board, rectangle, options) {
|
|
361
|
+
const points = getLeftArrowPoints(rectangle);
|
|
362
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
363
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
364
|
+
setStrokeLinecap(polygon, 'round');
|
|
365
|
+
return polygon;
|
|
366
|
+
},
|
|
367
|
+
getCornerPoints(rectangle) {
|
|
368
|
+
return getLeftArrowPoints(rectangle);
|
|
369
|
+
},
|
|
370
|
+
isHit(rectangle, point) {
|
|
371
|
+
const points = getLeftArrowPoints(rectangle);
|
|
372
|
+
return isPointInPolygon(point, points);
|
|
373
|
+
},
|
|
374
|
+
getNearestPoint(rectangle, point) {
|
|
375
|
+
const cornerPoints = getLeftArrowPoints(rectangle);
|
|
260
376
|
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
261
377
|
},
|
|
378
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
379
|
+
const corners = getLeftArrowPoints(rectangle);
|
|
380
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
381
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
382
|
+
},
|
|
262
383
|
getConnectorPoints(rectangle) {
|
|
263
|
-
|
|
384
|
+
return [
|
|
385
|
+
[rectangle.x, rectangle.y + rectangle.height / 2],
|
|
386
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2]
|
|
387
|
+
];
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
const getLeftArrowPoints = (rectangle) => {
|
|
391
|
+
return [
|
|
392
|
+
[rectangle.x, rectangle.y + rectangle.height / 2],
|
|
393
|
+
[rectangle.x + rectangle.width * 0.32, rectangle.y],
|
|
394
|
+
[rectangle.x + rectangle.width * 0.32, rectangle.y + rectangle.height * 0.2],
|
|
395
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height * 0.2],
|
|
396
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height * 0.8],
|
|
397
|
+
[rectangle.x + rectangle.width * 0.32, rectangle.y + rectangle.height * 0.8],
|
|
398
|
+
[rectangle.x + rectangle.width * 0.32, rectangle.y + rectangle.height]
|
|
399
|
+
];
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const OctagonEngine = {
|
|
403
|
+
draw(board, rectangle, options) {
|
|
404
|
+
const points = getOctagonPoints(rectangle);
|
|
405
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
406
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
407
|
+
setStrokeLinecap(polygon, 'round');
|
|
408
|
+
return polygon;
|
|
409
|
+
},
|
|
410
|
+
isHit(rectangle, point) {
|
|
411
|
+
const parallelogramPoints = getOctagonPoints(rectangle);
|
|
412
|
+
return isPointInPolygon(point, parallelogramPoints);
|
|
413
|
+
},
|
|
414
|
+
getCornerPoints(rectangle) {
|
|
415
|
+
return getOctagonPoints(rectangle);
|
|
416
|
+
},
|
|
417
|
+
getNearestPoint(rectangle, point) {
|
|
418
|
+
return getNearestPointBetweenPointAndSegments(point, getOctagonPoints(rectangle));
|
|
419
|
+
},
|
|
420
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
421
|
+
const corners = getOctagonPoints(rectangle);
|
|
422
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
423
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
424
|
+
},
|
|
425
|
+
getConnectorPoints(rectangle) {
|
|
426
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
const getOctagonPoints = (rectangle) => {
|
|
430
|
+
return [
|
|
431
|
+
[rectangle.x + (rectangle.width * 3) / 10, rectangle.y],
|
|
432
|
+
[rectangle.x + (rectangle.width * 7) / 10, rectangle.y],
|
|
433
|
+
[rectangle.x + rectangle.width, rectangle.y + (rectangle.height * 3) / 10],
|
|
434
|
+
[rectangle.x + rectangle.width, rectangle.y + (rectangle.height * 7) / 10],
|
|
435
|
+
[rectangle.x + (rectangle.width * 7) / 10, rectangle.y + rectangle.height],
|
|
436
|
+
[rectangle.x + (rectangle.width * 3) / 10, rectangle.y + rectangle.height],
|
|
437
|
+
[rectangle.x, rectangle.y + (rectangle.height * 7) / 10],
|
|
438
|
+
[rectangle.x, rectangle.y + (rectangle.height * 3) / 10]
|
|
439
|
+
];
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
const ParallelogramEngine = {
|
|
443
|
+
draw(board, rectangle, options) {
|
|
444
|
+
const points = getParallelogramCornerPoints(rectangle);
|
|
445
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
446
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
447
|
+
setStrokeLinecap(polygon, 'round');
|
|
448
|
+
return polygon;
|
|
449
|
+
},
|
|
450
|
+
isHit(rectangle, point) {
|
|
451
|
+
const parallelogramPoints = getParallelogramCornerPoints(rectangle);
|
|
452
|
+
return isPointInPolygon(point, parallelogramPoints);
|
|
453
|
+
},
|
|
454
|
+
getCornerPoints(rectangle) {
|
|
455
|
+
return getParallelogramCornerPoints(rectangle);
|
|
456
|
+
},
|
|
457
|
+
getNearestPoint(rectangle, point) {
|
|
458
|
+
return getNearestPointBetweenPointAndSegments(point, ParallelogramEngine.getCornerPoints(rectangle));
|
|
459
|
+
},
|
|
460
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
461
|
+
const corners = getParallelogramCornerPoints(rectangle);
|
|
462
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
463
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
464
|
+
},
|
|
465
|
+
getConnectorPoints(rectangle) {
|
|
466
|
+
const cornerPoints = getParallelogramCornerPoints(rectangle);
|
|
264
467
|
return getCenterPointsOnPolygon(cornerPoints);
|
|
265
468
|
}
|
|
266
469
|
};
|
|
267
|
-
const
|
|
470
|
+
const getParallelogramCornerPoints = (rectangle) => {
|
|
268
471
|
return [
|
|
269
472
|
[rectangle.x + rectangle.width / 4, rectangle.y],
|
|
270
473
|
[rectangle.x + rectangle.width, rectangle.y],
|
|
@@ -273,6 +476,119 @@ const getParallelogramPoints = (rectangle) => {
|
|
|
273
476
|
];
|
|
274
477
|
};
|
|
275
478
|
|
|
479
|
+
const PentagonEngine = {
|
|
480
|
+
draw(board, rectangle, options) {
|
|
481
|
+
const points = getPentagonPoints(rectangle);
|
|
482
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
483
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
484
|
+
setStrokeLinecap(polygon, 'round');
|
|
485
|
+
return polygon;
|
|
486
|
+
},
|
|
487
|
+
isHit(rectangle, point) {
|
|
488
|
+
const parallelogramPoints = getPentagonPoints(rectangle);
|
|
489
|
+
return isPointInPolygon(point, parallelogramPoints);
|
|
490
|
+
},
|
|
491
|
+
getCornerPoints(rectangle) {
|
|
492
|
+
return getPentagonPoints(rectangle);
|
|
493
|
+
},
|
|
494
|
+
getNearestPoint(rectangle, point) {
|
|
495
|
+
return getNearestPointBetweenPointAndSegments(point, getPentagonPoints(rectangle));
|
|
496
|
+
},
|
|
497
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
498
|
+
const corners = getPentagonPoints(rectangle);
|
|
499
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
500
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
501
|
+
},
|
|
502
|
+
getConnectorPoints(rectangle) {
|
|
503
|
+
return getPentagonPoints(rectangle);
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
const getPentagonPoints = (rectangle) => {
|
|
507
|
+
return [
|
|
508
|
+
[rectangle.x + rectangle.width / 2, rectangle.y],
|
|
509
|
+
[rectangle.x + rectangle.width, rectangle.y + (rectangle.height * 2) / 5],
|
|
510
|
+
[rectangle.x + (rectangle.width * 4) / 5, rectangle.y + rectangle.height],
|
|
511
|
+
[rectangle.x + rectangle.width / 5, rectangle.y + rectangle.height],
|
|
512
|
+
[rectangle.x, rectangle.y + (rectangle.height * 2) / 5]
|
|
513
|
+
];
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
const PentagonArrowEngine = {
|
|
517
|
+
draw(board, rectangle, options) {
|
|
518
|
+
const points = getPentagonArrowPoints(rectangle);
|
|
519
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
520
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
521
|
+
setStrokeLinecap(polygon, 'round');
|
|
522
|
+
return polygon;
|
|
523
|
+
},
|
|
524
|
+
isHit(rectangle, point) {
|
|
525
|
+
const parallelogramPoints = getPentagonArrowPoints(rectangle);
|
|
526
|
+
return isPointInPolygon(point, parallelogramPoints);
|
|
527
|
+
},
|
|
528
|
+
getCornerPoints(rectangle) {
|
|
529
|
+
return getPentagonArrowPoints(rectangle);
|
|
530
|
+
},
|
|
531
|
+
getNearestPoint(rectangle, point) {
|
|
532
|
+
return getNearestPointBetweenPointAndSegments(point, getPentagonArrowPoints(rectangle));
|
|
533
|
+
},
|
|
534
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
535
|
+
const corners = getPentagonArrowPoints(rectangle);
|
|
536
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
537
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
538
|
+
},
|
|
539
|
+
getConnectorPoints(rectangle) {
|
|
540
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
const getPentagonArrowPoints = (rectangle) => {
|
|
544
|
+
return [
|
|
545
|
+
[rectangle.x, rectangle.y],
|
|
546
|
+
[rectangle.x + (rectangle.width * 3) / 5, rectangle.y],
|
|
547
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2],
|
|
548
|
+
[rectangle.x + (rectangle.width * 3) / 5, rectangle.y + rectangle.height],
|
|
549
|
+
[rectangle.x, rectangle.y + rectangle.height]
|
|
550
|
+
];
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
const ProcessArrowEngine = {
|
|
554
|
+
draw(board, rectangle, options) {
|
|
555
|
+
const points = getProcessArrowPoints(rectangle);
|
|
556
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
557
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
558
|
+
setStrokeLinecap(polygon, 'round');
|
|
559
|
+
return polygon;
|
|
560
|
+
},
|
|
561
|
+
isHit(rectangle, point) {
|
|
562
|
+
const parallelogramPoints = getProcessArrowPoints(rectangle);
|
|
563
|
+
return isPointInPolygon(point, parallelogramPoints);
|
|
564
|
+
},
|
|
565
|
+
getCornerPoints(rectangle) {
|
|
566
|
+
return getProcessArrowPoints(rectangle);
|
|
567
|
+
},
|
|
568
|
+
getNearestPoint(rectangle, point) {
|
|
569
|
+
return getNearestPointBetweenPointAndSegments(point, getProcessArrowPoints(rectangle));
|
|
570
|
+
},
|
|
571
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
572
|
+
const corners = getProcessArrowPoints(rectangle);
|
|
573
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
574
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
575
|
+
},
|
|
576
|
+
getConnectorPoints(rectangle) {
|
|
577
|
+
return getProcessArrowPoints(rectangle);
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
const getProcessArrowPoints = (rectangle) => {
|
|
581
|
+
const wider = rectangle.width > rectangle.height / 2;
|
|
582
|
+
return [
|
|
583
|
+
[rectangle.x, rectangle.y],
|
|
584
|
+
[rectangle.x + (wider ? rectangle.width - rectangle.height / 2 : 0), rectangle.y],
|
|
585
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2],
|
|
586
|
+
[rectangle.x + (wider ? rectangle.width - rectangle.height / 2 : 0), rectangle.y + rectangle.height],
|
|
587
|
+
[rectangle.x, rectangle.y + rectangle.height],
|
|
588
|
+
[rectangle.x + (wider ? rectangle.height / 2 : rectangle.width), rectangle.y + rectangle.height / 2]
|
|
589
|
+
];
|
|
590
|
+
};
|
|
591
|
+
|
|
276
592
|
const RectangleEngine = {
|
|
277
593
|
draw(board, rectangle, options) {
|
|
278
594
|
return drawRectangle(board, rectangle, { ...options, fillStyle: 'solid' });
|
|
@@ -281,15 +597,65 @@ const RectangleEngine = {
|
|
|
281
597
|
const rangeRectangle = RectangleClient.toRectangleClient([point, point]);
|
|
282
598
|
return RectangleClient.isHit(rectangle, rangeRectangle);
|
|
283
599
|
},
|
|
600
|
+
getCornerPoints(rectangle) {
|
|
601
|
+
return RectangleClient.getCornerPoints(rectangle);
|
|
602
|
+
},
|
|
284
603
|
getNearestPoint(rectangle, point) {
|
|
285
|
-
|
|
286
|
-
|
|
604
|
+
return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
|
|
605
|
+
},
|
|
606
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
607
|
+
const corners = RectangleEngine.getCornerPoints(rectangle);
|
|
608
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
609
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
287
610
|
},
|
|
288
611
|
getConnectorPoints(rectangle) {
|
|
289
612
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
290
613
|
}
|
|
291
614
|
};
|
|
292
615
|
|
|
616
|
+
const RightArrowEngine = {
|
|
617
|
+
draw(board, rectangle, options) {
|
|
618
|
+
const points = getRightArrowPoints(rectangle);
|
|
619
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
620
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
621
|
+
setStrokeLinecap(polygon, 'round');
|
|
622
|
+
return polygon;
|
|
623
|
+
},
|
|
624
|
+
getCornerPoints(rectangle) {
|
|
625
|
+
return getRightArrowPoints(rectangle);
|
|
626
|
+
},
|
|
627
|
+
isHit(rectangle, point) {
|
|
628
|
+
const points = getRightArrowPoints(rectangle);
|
|
629
|
+
return isPointInPolygon(point, points);
|
|
630
|
+
},
|
|
631
|
+
getNearestPoint(rectangle, point) {
|
|
632
|
+
const cornerPoints = getRightArrowPoints(rectangle);
|
|
633
|
+
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
634
|
+
},
|
|
635
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
636
|
+
const corners = getRightArrowPoints(rectangle);
|
|
637
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
638
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
639
|
+
},
|
|
640
|
+
getConnectorPoints(rectangle) {
|
|
641
|
+
return [
|
|
642
|
+
[rectangle.x, rectangle.y + rectangle.height / 2],
|
|
643
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2]
|
|
644
|
+
];
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
const getRightArrowPoints = (rectangle) => {
|
|
648
|
+
return [
|
|
649
|
+
[rectangle.x, rectangle.y + rectangle.height * 0.2],
|
|
650
|
+
[rectangle.x + rectangle.width * 0.68, rectangle.y + rectangle.height * 0.2],
|
|
651
|
+
[rectangle.x + rectangle.width * 0.68, rectangle.y],
|
|
652
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2],
|
|
653
|
+
[rectangle.x + rectangle.width * 0.68, rectangle.y + rectangle.height],
|
|
654
|
+
[rectangle.x + rectangle.width * 0.68, rectangle.y + rectangle.height * 0.8],
|
|
655
|
+
[rectangle.x, rectangle.y + rectangle.height * 0.8]
|
|
656
|
+
];
|
|
657
|
+
};
|
|
658
|
+
|
|
293
659
|
const RoundRectangleEngine = {
|
|
294
660
|
draw(board, rectangle, options) {
|
|
295
661
|
return drawRoundRectangle(PlaitBoard.getRoughSVG(board), rectangle.x, rectangle.y, rectangle.x + rectangle.width, rectangle.y + rectangle.height, { ...options, fillStyle: 'solid' }, false, getRoundRectangleRadius(rectangle));
|
|
@@ -297,9 +663,17 @@ const RoundRectangleEngine = {
|
|
|
297
663
|
isHit(rectangle, point) {
|
|
298
664
|
return isPointInRoundRectangle(point, rectangle, getRoundRectangleRadius(rectangle));
|
|
299
665
|
},
|
|
666
|
+
getCornerPoints(rectangle) {
|
|
667
|
+
return RectangleClient.getCornerPoints(rectangle);
|
|
668
|
+
},
|
|
300
669
|
getNearestPoint(rectangle, point) {
|
|
301
670
|
return getNearestPointBetweenPointAndRoundRectangle(point, rectangle, getRoundRectangleRadius(rectangle));
|
|
302
671
|
},
|
|
672
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
673
|
+
const corners = RectangleEngine.getCornerPoints(rectangle);
|
|
674
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
675
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
676
|
+
},
|
|
303
677
|
getConnectorPoints(rectangle) {
|
|
304
678
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
305
679
|
}
|
|
@@ -337,18 +711,279 @@ function getNearestPointBetweenPointAndRoundRectangle(point, rectangle, radius)
|
|
|
337
711
|
return result;
|
|
338
712
|
}
|
|
339
713
|
|
|
714
|
+
const heightRatio = 3 / 4;
|
|
715
|
+
const RoundCommentEngine = {
|
|
716
|
+
draw(board, rectangle, options) {
|
|
717
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
718
|
+
const x1 = rectangle.x;
|
|
719
|
+
const y1 = rectangle.y;
|
|
720
|
+
const x2 = rectangle.x + rectangle.width;
|
|
721
|
+
const y2 = rectangle.y + rectangle.height * heightRatio;
|
|
722
|
+
const radius = getRoundRectangleRadius(rectangle);
|
|
723
|
+
const point1 = [x1 + radius, y1];
|
|
724
|
+
const point2 = [x2 - radius, y1];
|
|
725
|
+
const point3 = [x2, y1 + radius];
|
|
726
|
+
const point4 = [x2, y2 - radius];
|
|
727
|
+
const point5 = [x2 - radius, y2];
|
|
728
|
+
const point6 = [x1 + radius, y2];
|
|
729
|
+
const point7 = [x1, y2 - radius];
|
|
730
|
+
const point8 = [x1, y1 + radius];
|
|
731
|
+
const point9 = [x1 + rectangle.width / 4, y2];
|
|
732
|
+
const point10 = [x1 + rectangle.width / 4, rectangle.y + rectangle.height];
|
|
733
|
+
const point11 = [x1 + rectangle.width / 2, y2];
|
|
734
|
+
return rs.path(`M${point2[0]} ${point2[1]} A ${radius} ${radius}, 0, 0, 1, ${point3[0]} ${point3[1]} L ${point4[0]} ${point4[1]} A ${radius} ${radius}, 0, 0, 1, ${point5[0]} ${point5[1]} L ${point11[0]} ${point11[1]} ${point10[0]} ${point10[1]} ${point9[0]} ${point9[1]} ${point6[0]} ${point6[1]} A ${radius} ${radius}, 0, 0, 1, ${point7[0]} ${point7[1]} L ${point8[0]} ${point8[1]} A ${radius} ${radius}, 0, 0, 1, ${point1[0]} ${point1[1]} Z`, options);
|
|
735
|
+
},
|
|
736
|
+
isHit(rectangle, point) {
|
|
737
|
+
const points = [
|
|
738
|
+
[rectangle.x + rectangle.width / 4, rectangle.y + (rectangle.height * 3) / 4],
|
|
739
|
+
[rectangle.x + rectangle.width / 4, rectangle.y + rectangle.height],
|
|
740
|
+
[rectangle.x + rectangle.width / 2, rectangle.y + (rectangle.height * 3) / 4]
|
|
741
|
+
];
|
|
742
|
+
rectangle.height = (rectangle.height * 3) / 4;
|
|
743
|
+
return isPointInPolygon(point, points) || isPointInRoundRectangle(point, rectangle, getRoundRectangleRadius(rectangle));
|
|
744
|
+
},
|
|
745
|
+
getCornerPoints(rectangle) {
|
|
746
|
+
return getRoundCommentPoints(rectangle);
|
|
747
|
+
},
|
|
748
|
+
getNearestPoint(rectangle, point) {
|
|
749
|
+
return getNearestPointBetweenPointAndSegments(point, getRoundCommentPoints(rectangle));
|
|
750
|
+
},
|
|
751
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
752
|
+
const corners = getRoundCommentPoints(rectangle);
|
|
753
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
754
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
755
|
+
},
|
|
756
|
+
getConnectorPoints(rectangle) {
|
|
757
|
+
return [
|
|
758
|
+
[rectangle.x + rectangle.width / 2, rectangle.y],
|
|
759
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2],
|
|
760
|
+
[rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height * heightRatio],
|
|
761
|
+
[rectangle.x, rectangle.y + rectangle.height / 2]
|
|
762
|
+
];
|
|
763
|
+
},
|
|
764
|
+
getTextRectangle(element) {
|
|
765
|
+
const elementRectangle = getRectangleByPoints(element.points);
|
|
766
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
767
|
+
const height = element.textHeight;
|
|
768
|
+
const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
|
|
769
|
+
return {
|
|
770
|
+
height,
|
|
771
|
+
width: width > 0 ? width : 0,
|
|
772
|
+
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
|
|
773
|
+
y: elementRectangle.y + (elementRectangle.height * heightRatio - height) / 2
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
const getRoundCommentPoints = (rectangle) => {
|
|
778
|
+
return [
|
|
779
|
+
[rectangle.x, rectangle.y],
|
|
780
|
+
[rectangle.x + rectangle.width, rectangle.y],
|
|
781
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height * heightRatio],
|
|
782
|
+
[rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height * heightRatio],
|
|
783
|
+
[rectangle.x + rectangle.width / 4, rectangle.y + rectangle.height],
|
|
784
|
+
[rectangle.x + rectangle.width / 4, rectangle.y + rectangle.height * heightRatio],
|
|
785
|
+
[rectangle.x, rectangle.y + rectangle.height * heightRatio]
|
|
786
|
+
];
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
const StarEngine = {
|
|
790
|
+
draw(board, rectangle, options) {
|
|
791
|
+
const points = getStarPoints(rectangle);
|
|
792
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
793
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
794
|
+
setStrokeLinecap(polygon, 'round');
|
|
795
|
+
return polygon;
|
|
796
|
+
},
|
|
797
|
+
isHit(rectangle, point) {
|
|
798
|
+
const parallelogramPoints = getStarPoints(rectangle);
|
|
799
|
+
return isPointInPolygon(point, parallelogramPoints);
|
|
800
|
+
},
|
|
801
|
+
getCornerPoints(rectangle) {
|
|
802
|
+
return getStarPoints(rectangle);
|
|
803
|
+
},
|
|
804
|
+
getNearestPoint(rectangle, point) {
|
|
805
|
+
return getNearestPointBetweenPointAndSegments(point, getStarPoints(rectangle));
|
|
806
|
+
},
|
|
807
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
808
|
+
const corners = getStarPoints(rectangle);
|
|
809
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
810
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
811
|
+
},
|
|
812
|
+
getConnectorPoints(rectangle) {
|
|
813
|
+
const points = getStarPoints(rectangle);
|
|
814
|
+
return [points[1], points[3], points[5], points[7], points[9]];
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
const getStarPoints = (rectangle) => {
|
|
818
|
+
return [
|
|
819
|
+
[rectangle.x + rectangle.width / 2, rectangle.y + (rectangle.height * 75) / 91],
|
|
820
|
+
[rectangle.x + (rectangle.width * 18.61) / 96, rectangle.y + rectangle.height],
|
|
821
|
+
[rectangle.x + (rectangle.width * 24.2235871) / 96, rectangle.y + (rectangle.height * 57.7254249) / 91],
|
|
822
|
+
[rectangle.x, rectangle.y + (rectangle.height * 34.5491503) / 91],
|
|
823
|
+
[rectangle.x + (rectangle.width * 33.3053687) / 96, rectangle.y + (rectangle.height * 29.7745751) / 91],
|
|
824
|
+
[rectangle.x + rectangle.width / 2, rectangle.y],
|
|
825
|
+
[rectangle.x + (rectangle.width * 62.6946313) / 96, rectangle.y + (rectangle.height * 29.7745751) / 91],
|
|
826
|
+
[rectangle.x + rectangle.width, rectangle.y + (rectangle.height * 34.5491503) / 91],
|
|
827
|
+
[rectangle.x + (rectangle.width * 71.7764129) / 96, rectangle.y + (rectangle.height * 57.7254249) / 91],
|
|
828
|
+
[rectangle.x + (rectangle.width * 77.3892626) / 96, rectangle.y + rectangle.height]
|
|
829
|
+
];
|
|
830
|
+
};
|
|
831
|
+
|
|
832
|
+
const TrapezoidEngine = {
|
|
833
|
+
draw(board, rectangle, options) {
|
|
834
|
+
const points = getTrapezoidPoints(rectangle);
|
|
835
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
836
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
837
|
+
setStrokeLinecap(polygon, 'round');
|
|
838
|
+
return polygon;
|
|
839
|
+
},
|
|
840
|
+
isHit(rectangle, point) {
|
|
841
|
+
const points = getTrapezoidPoints(rectangle);
|
|
842
|
+
return isPointInPolygon(point, points);
|
|
843
|
+
},
|
|
844
|
+
getNearestPoint(rectangle, point) {
|
|
845
|
+
const cornerPoints = getTrapezoidPoints(rectangle);
|
|
846
|
+
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
847
|
+
},
|
|
848
|
+
getConnectorPoints(rectangle) {
|
|
849
|
+
const points = getTrapezoidPoints(rectangle);
|
|
850
|
+
return getCenterPointsOnPolygon(points);
|
|
851
|
+
},
|
|
852
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
853
|
+
const corners = getTrapezoidPoints(rectangle);
|
|
854
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
855
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
856
|
+
},
|
|
857
|
+
getCornerPoints(rectangle) {
|
|
858
|
+
return getTrapezoidPoints(rectangle);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
const getTrapezoidPoints = (rectangle) => {
|
|
862
|
+
return [
|
|
863
|
+
[rectangle.x + rectangle.width * 0.15, rectangle.y],
|
|
864
|
+
[rectangle.x + rectangle.width * 0.85, rectangle.y],
|
|
865
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height],
|
|
866
|
+
[rectangle.x, rectangle.y + rectangle.height]
|
|
867
|
+
];
|
|
868
|
+
};
|
|
869
|
+
|
|
870
|
+
const TriangleEngine = {
|
|
871
|
+
draw(board, rectangle, options) {
|
|
872
|
+
const points = getTrianglePoints(rectangle);
|
|
873
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
874
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
875
|
+
setStrokeLinecap(polygon, 'round');
|
|
876
|
+
return polygon;
|
|
877
|
+
},
|
|
878
|
+
isHit(rectangle, point) {
|
|
879
|
+
const points = getTrianglePoints(rectangle);
|
|
880
|
+
return isPointInPolygon(point, points);
|
|
881
|
+
},
|
|
882
|
+
getNearestPoint(rectangle, point) {
|
|
883
|
+
const cornerPoints = getTrianglePoints(rectangle);
|
|
884
|
+
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
885
|
+
},
|
|
886
|
+
getConnectorPoints(rectangle) {
|
|
887
|
+
const cornerPoints = getTrianglePoints(rectangle);
|
|
888
|
+
const lineCenterPoints = getCenterPointsOnPolygon(cornerPoints);
|
|
889
|
+
return [...lineCenterPoints, ...cornerPoints];
|
|
890
|
+
},
|
|
891
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
892
|
+
const corners = getTrianglePoints(rectangle);
|
|
893
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
894
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
895
|
+
},
|
|
896
|
+
getCornerPoints(rectangle) {
|
|
897
|
+
return getTrianglePoints(rectangle);
|
|
898
|
+
}
|
|
899
|
+
};
|
|
900
|
+
const getTrianglePoints = (rectangle) => {
|
|
901
|
+
return [
|
|
902
|
+
[rectangle.x + rectangle.width / 2, rectangle.y],
|
|
903
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height],
|
|
904
|
+
[rectangle.x, rectangle.y + rectangle.height]
|
|
905
|
+
];
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
const TwoWayArrowEngine = {
|
|
909
|
+
draw(board, rectangle, options) {
|
|
910
|
+
const points = getTwoWayArrowPoints(rectangle);
|
|
911
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
912
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
913
|
+
setStrokeLinecap(polygon, 'round');
|
|
914
|
+
return polygon;
|
|
915
|
+
},
|
|
916
|
+
getCornerPoints(rectangle) {
|
|
917
|
+
return getTwoWayArrowPoints(rectangle);
|
|
918
|
+
},
|
|
919
|
+
isHit(rectangle, point) {
|
|
920
|
+
const points = getTwoWayArrowPoints(rectangle);
|
|
921
|
+
return isPointInPolygon(point, points);
|
|
922
|
+
},
|
|
923
|
+
getNearestPoint(rectangle, point) {
|
|
924
|
+
const cornerPoints = getTwoWayArrowPoints(rectangle);
|
|
925
|
+
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
926
|
+
},
|
|
927
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
928
|
+
const corners = getTwoWayArrowPoints(rectangle);
|
|
929
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
930
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
931
|
+
},
|
|
932
|
+
getConnectorPoints(rectangle) {
|
|
933
|
+
return [
|
|
934
|
+
[rectangle.x, rectangle.y + rectangle.height / 2],
|
|
935
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2]
|
|
936
|
+
];
|
|
937
|
+
}
|
|
938
|
+
};
|
|
939
|
+
const getTwoWayArrowPoints = (rectangle) => {
|
|
940
|
+
return [
|
|
941
|
+
[rectangle.x, rectangle.y + rectangle.height / 2],
|
|
942
|
+
[rectangle.x + (rectangle.width * 8) / 25, rectangle.y],
|
|
943
|
+
[rectangle.x + (rectangle.width * 8) / 25, rectangle.y + rectangle.height / 5],
|
|
944
|
+
[rectangle.x + (rectangle.width * 17) / 25, rectangle.y + rectangle.height / 5],
|
|
945
|
+
[rectangle.x + (rectangle.width * 17) / 25, rectangle.y],
|
|
946
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2],
|
|
947
|
+
[rectangle.x + (rectangle.width * 17) / 25, rectangle.y + rectangle.height],
|
|
948
|
+
[rectangle.x + (rectangle.width * 17) / 25, rectangle.y + (rectangle.height * 4) / 5],
|
|
949
|
+
[rectangle.x + (rectangle.width * 8) / 25, rectangle.y + (rectangle.height * 4) / 5],
|
|
950
|
+
[rectangle.x + (rectangle.width * 8) / 25, rectangle.y + rectangle.height]
|
|
951
|
+
];
|
|
952
|
+
};
|
|
953
|
+
|
|
340
954
|
const ShapeEngineMap = {
|
|
341
955
|
[GeometryShape.rectangle]: RectangleEngine,
|
|
342
956
|
[GeometryShape.diamond]: DiamondEngine,
|
|
343
957
|
[GeometryShape.ellipse]: EllipseEngine,
|
|
344
958
|
[GeometryShape.parallelogram]: ParallelogramEngine,
|
|
345
959
|
[GeometryShape.roundRectangle]: RoundRectangleEngine,
|
|
346
|
-
[GeometryShape.text]: RectangleEngine
|
|
960
|
+
[GeometryShape.text]: RectangleEngine,
|
|
961
|
+
[GeometryShape.triangle]: TriangleEngine,
|
|
962
|
+
[GeometryShape.leftArrow]: LeftArrowEngine,
|
|
963
|
+
[GeometryShape.trapezoid]: TrapezoidEngine,
|
|
964
|
+
[GeometryShape.rightArrow]: RightArrowEngine,
|
|
965
|
+
[GeometryShape.cross]: CrossEngine,
|
|
966
|
+
[GeometryShape.star]: StarEngine,
|
|
967
|
+
[GeometryShape.pentagon]: PentagonEngine,
|
|
968
|
+
[GeometryShape.hexagon]: HexagonEngine,
|
|
969
|
+
[GeometryShape.octagon]: OctagonEngine,
|
|
970
|
+
[GeometryShape.pentagonArrow]: PentagonArrowEngine,
|
|
971
|
+
[GeometryShape.processArrow]: ProcessArrowEngine,
|
|
972
|
+
[GeometryShape.twoWayArrow]: TwoWayArrowEngine,
|
|
973
|
+
[GeometryShape.comment]: CommentEngine,
|
|
974
|
+
[GeometryShape.roundComment]: RoundCommentEngine
|
|
347
975
|
};
|
|
348
976
|
const getEngine = (shape) => {
|
|
349
977
|
return ShapeEngineMap[shape];
|
|
350
978
|
};
|
|
351
979
|
|
|
980
|
+
const getShape = (value) => {
|
|
981
|
+
if (PlaitDrawElement.isImage(value)) {
|
|
982
|
+
return GeometryShape.rectangle;
|
|
983
|
+
}
|
|
984
|
+
return value.shape;
|
|
985
|
+
};
|
|
986
|
+
|
|
352
987
|
const createGeometryElement = (shape, points, text, options) => {
|
|
353
988
|
let textOptions = {};
|
|
354
989
|
let alignment = Alignment.center;
|
|
@@ -390,14 +1025,15 @@ const drawBoundMask = (board, element) => {
|
|
|
390
1025
|
const G = createG();
|
|
391
1026
|
const rectangle = getRectangleByPoints(element.points);
|
|
392
1027
|
const activeRectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
|
|
393
|
-
const
|
|
1028
|
+
const shape = getShape(element);
|
|
1029
|
+
const maskG = drawGeometry(board, activeRectangle, shape, {
|
|
394
1030
|
stroke: SELECTION_BORDER_COLOR,
|
|
395
1031
|
strokeWidth: 1,
|
|
396
1032
|
fill: SELECTION_FILL_COLOR,
|
|
397
1033
|
fillStyle: 'solid'
|
|
398
1034
|
});
|
|
399
1035
|
G.appendChild(maskG);
|
|
400
|
-
const connectorPoints = getEngine(
|
|
1036
|
+
const connectorPoints = getEngine(shape).getConnectorPoints(activeRectangle);
|
|
401
1037
|
connectorPoints.forEach(point => {
|
|
402
1038
|
const circleG = drawCircle(PlaitBoard.getRoughSVG(board), point, 6, {
|
|
403
1039
|
stroke: '#999999',
|
|
@@ -415,7 +1051,8 @@ const drawGeometry = (board, outerRectangle, shape, options) => {
|
|
|
415
1051
|
const getNearestPoint = (element, point, inflateDelta = 0) => {
|
|
416
1052
|
const rectangle = getRectangleByPoints(element.points);
|
|
417
1053
|
const activeRectangle = RectangleClient.inflate(rectangle, inflateDelta);
|
|
418
|
-
|
|
1054
|
+
const shape = getShape(element);
|
|
1055
|
+
return getEngine(shape).getNearestPoint(activeRectangle, point);
|
|
419
1056
|
};
|
|
420
1057
|
const getCenterPointsOnPolygon = (points) => {
|
|
421
1058
|
const centerPoint = [];
|
|
@@ -425,6 +1062,17 @@ const getCenterPointsOnPolygon = (points) => {
|
|
|
425
1062
|
}
|
|
426
1063
|
return centerPoint;
|
|
427
1064
|
};
|
|
1065
|
+
const getEdgeOnPolygonByPoint = (corners, point) => {
|
|
1066
|
+
for (let index = 1; index <= corners.length; index++) {
|
|
1067
|
+
let start = corners[index - 1];
|
|
1068
|
+
let end = index === corners.length ? corners[0] : corners[index];
|
|
1069
|
+
const distance = distanceBetweenPointAndSegment(point[0], point[1], start[0], start[1], end[0], end[1]);
|
|
1070
|
+
if (distance < 1) {
|
|
1071
|
+
return [start, end];
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
return null;
|
|
1075
|
+
};
|
|
428
1076
|
|
|
429
1077
|
const drawLineArrow = (element, points, options) => {
|
|
430
1078
|
const arrowG = createG();
|
|
@@ -432,16 +1080,19 @@ const drawLineArrow = (element, points, options) => {
|
|
|
432
1080
|
return null;
|
|
433
1081
|
}
|
|
434
1082
|
if (!PlaitLine.isSourceMark(element, LineMarkerType.none)) {
|
|
435
|
-
const
|
|
1083
|
+
const source = getExtendPoint(points[0], points[1], 24);
|
|
1084
|
+
const sourceArrow = getArrow(element, { marker: element.source.marker, source, target: points[0], isSource: true }, options);
|
|
436
1085
|
sourceArrow && arrowG.appendChild(sourceArrow);
|
|
437
1086
|
}
|
|
438
1087
|
if (!PlaitLine.isTargetMark(element, LineMarkerType.none)) {
|
|
439
|
-
const
|
|
1088
|
+
const source = getExtendPoint(points[points.length - 1], points[points.length - 2], 24);
|
|
1089
|
+
const arrow = getArrow(element, { marker: element.target.marker, source, target: points[points.length - 1], isSource: false }, options);
|
|
440
1090
|
arrow && arrowG.appendChild(arrow);
|
|
441
1091
|
}
|
|
442
1092
|
return arrowG;
|
|
443
1093
|
};
|
|
444
|
-
const getArrow = (element,
|
|
1094
|
+
const getArrow = (element, arrowOptions, options) => {
|
|
1095
|
+
const { marker, source, target, isSource } = arrowOptions;
|
|
445
1096
|
let targetArrow;
|
|
446
1097
|
switch (marker) {
|
|
447
1098
|
case LineMarkerType.openTriangle: {
|
|
@@ -460,16 +1111,27 @@ const getArrow = (element, marker, source, target, options) => {
|
|
|
460
1111
|
targetArrow = drawSharpArrow(source, target, options);
|
|
461
1112
|
break;
|
|
462
1113
|
}
|
|
1114
|
+
case LineMarkerType.oneSideUp: {
|
|
1115
|
+
targetArrow = drawOneSideArrow(source, target, 'up', options);
|
|
1116
|
+
break;
|
|
1117
|
+
}
|
|
1118
|
+
case LineMarkerType.oneSideDown: {
|
|
1119
|
+
targetArrow = drawOneSideArrow(source, target, 'down', options);
|
|
1120
|
+
break;
|
|
1121
|
+
}
|
|
1122
|
+
case LineMarkerType.hollowTriangle: {
|
|
1123
|
+
targetArrow = drawHollowTriangleArrow(source, target, options);
|
|
1124
|
+
break;
|
|
1125
|
+
}
|
|
1126
|
+
case LineMarkerType.singleSlash: {
|
|
1127
|
+
targetArrow = drawSingleSlash(source, target, isSource, options);
|
|
1128
|
+
break;
|
|
1129
|
+
}
|
|
463
1130
|
}
|
|
464
1131
|
return targetArrow;
|
|
465
1132
|
};
|
|
466
1133
|
const drawSharpArrow = (source, target, options) => {
|
|
467
|
-
const directionFactor = getFactorByPoints(source, target);
|
|
468
1134
|
const startPoint = target;
|
|
469
|
-
// const startPoint: Point = [
|
|
470
|
-
// target[0],
|
|
471
|
-
// target[1]
|
|
472
|
-
// ];
|
|
473
1135
|
const { pointLeft, pointRight } = arrowPoints(source, target, 12, 20);
|
|
474
1136
|
const g = createG();
|
|
475
1137
|
const path = createPath();
|
|
@@ -484,10 +1146,7 @@ const drawSharpArrow = (source, target, options) => {
|
|
|
484
1146
|
const drawArrow = (element, source, target, options) => {
|
|
485
1147
|
const directionFactor = getFactorByPoints(source, target);
|
|
486
1148
|
const strokeWidth = getStrokeWidthByElement(element);
|
|
487
|
-
const endPoint = [
|
|
488
|
-
target[0] + strokeWidth * directionFactor.x / 2,
|
|
489
|
-
target[1] + strokeWidth * directionFactor.y / 2
|
|
490
|
-
];
|
|
1149
|
+
const endPoint = [target[0] + (strokeWidth * directionFactor.x) / 2, target[1] + (strokeWidth * directionFactor.y) / 2];
|
|
491
1150
|
const middlePoint = [endPoint[0] - 8 * directionFactor.x, endPoint[1] - 8 * directionFactor.y];
|
|
492
1151
|
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 30);
|
|
493
1152
|
const arrowG = drawLinearPath([pointLeft, endPoint, pointRight, middlePoint], { ...options, fill: options.stroke }, true);
|
|
@@ -503,13 +1162,26 @@ const drawSolidTriangle = (source, target, options) => {
|
|
|
503
1162
|
const drawOpenTriangle = (element, source, target, options) => {
|
|
504
1163
|
const directionFactor = getFactorByPoints(source, target);
|
|
505
1164
|
const strokeWidth = getStrokeWidthByElement(element);
|
|
506
|
-
const endPoint = [
|
|
507
|
-
target[0] + strokeWidth * directionFactor.x / 2,
|
|
508
|
-
target[1] + strokeWidth * directionFactor.y / 2
|
|
509
|
-
];
|
|
1165
|
+
const endPoint = [target[0] + (strokeWidth * directionFactor.x) / 2, target[1] + (strokeWidth * directionFactor.y) / 2];
|
|
510
1166
|
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 40);
|
|
511
1167
|
return drawLinearPath([pointLeft, endPoint, pointRight], options);
|
|
512
1168
|
};
|
|
1169
|
+
const drawOneSideArrow = (source, target, side, options) => {
|
|
1170
|
+
const { pointLeft, pointRight } = arrowPoints(source, target, 12, 40);
|
|
1171
|
+
return drawLinearPath([side === 'up' ? pointRight : pointLeft, target], options);
|
|
1172
|
+
};
|
|
1173
|
+
const drawSingleSlash = (source, target, isSource, options) => {
|
|
1174
|
+
source = getExtendPoint(target, source, 12);
|
|
1175
|
+
const middlePoint = getExtendPoint(target, source, 6);
|
|
1176
|
+
const angle = isSource ? 120 : 60;
|
|
1177
|
+
const start = rotate(...source, ...middlePoint, (angle * Math.PI) / 180);
|
|
1178
|
+
const end = rotate(...target, ...middlePoint, (angle * Math.PI) / 180);
|
|
1179
|
+
return drawLinearPath([start, end], options);
|
|
1180
|
+
};
|
|
1181
|
+
const drawHollowTriangleArrow = (source, target, options) => {
|
|
1182
|
+
const { pointLeft, pointRight } = arrowPoints(source, target, 12, 30);
|
|
1183
|
+
return drawLinearPath([pointLeft, pointRight, target], { ...options, fill: 'white' }, true);
|
|
1184
|
+
};
|
|
513
1185
|
|
|
514
1186
|
const createLineElement = (shape, points, source, target, options) => {
|
|
515
1187
|
return {
|
|
@@ -525,28 +1197,127 @@ const createLineElement = (shape, points, source, target, options) => {
|
|
|
525
1197
|
};
|
|
526
1198
|
};
|
|
527
1199
|
const getLinePoints = (board, element) => {
|
|
528
|
-
|
|
1200
|
+
switch (element.shape) {
|
|
1201
|
+
case LineShape.elbow: {
|
|
1202
|
+
return getElbowPoints(board, element);
|
|
1203
|
+
}
|
|
1204
|
+
case LineShape.curve: {
|
|
1205
|
+
return getCurvePoints(board, element);
|
|
1206
|
+
}
|
|
1207
|
+
default: {
|
|
1208
|
+
return PlaitLine.getPoints(board, element);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
529
1211
|
};
|
|
530
|
-
const
|
|
531
|
-
|
|
1212
|
+
const getLineHandleRefPair = (board, element) => {
|
|
1213
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1214
|
+
const sourceBoundElement = element.source.boundId ? getElementById(board, element.source.boundId) : undefined;
|
|
1215
|
+
const targetBoundElement = element.target.boundId ? getElementById(board, element.target.boundId) : undefined;
|
|
1216
|
+
let sourcePoint = sourceBoundElement ? getConnectionPoint(sourceBoundElement, element.source.connection) : element.points[0];
|
|
1217
|
+
let targetPoint = targetBoundElement
|
|
1218
|
+
? getConnectionPoint(targetBoundElement, element.target.connection)
|
|
1219
|
+
: element.points[element.points.length - 1];
|
|
1220
|
+
let sourceDirection = getDirectionByVector([targetPoint[0] - sourcePoint[0], targetPoint[1] - sourcePoint[1]]);
|
|
1221
|
+
let targetDirection = getOppositeDirection(sourceDirection);
|
|
1222
|
+
const sourceFactor = getDirectionFactor(sourceDirection);
|
|
1223
|
+
const targetFactor = getDirectionFactor(targetDirection);
|
|
1224
|
+
const sourceHandleRef = {
|
|
1225
|
+
key: LineHandleKey.source,
|
|
1226
|
+
point: sourcePoint,
|
|
1227
|
+
direction: sourceDirection,
|
|
1228
|
+
vector: [sourceFactor.x, sourceFactor.y]
|
|
1229
|
+
};
|
|
1230
|
+
const targetHandleRef = {
|
|
1231
|
+
key: LineHandleKey.target,
|
|
1232
|
+
point: targetPoint,
|
|
1233
|
+
direction: targetDirection,
|
|
1234
|
+
vector: [targetFactor.x, targetFactor.y]
|
|
1235
|
+
};
|
|
1236
|
+
if (sourceBoundElement) {
|
|
1237
|
+
const connectionOffset = PlaitLine.isSourceMarkOrTargetMark(element, LineMarkerType.none, LineHandleKey.source) ? 0 : strokeWidth;
|
|
1238
|
+
const sourceVector = getVectorByConnection(sourceBoundElement, element.source.connection);
|
|
1239
|
+
const direction = getDirectionByVector(sourceVector);
|
|
1240
|
+
sourceDirection = direction ? direction : sourceDirection;
|
|
1241
|
+
sourcePoint = getConnectionPoint(sourceBoundElement, element.source.connection, sourceDirection, connectionOffset);
|
|
1242
|
+
sourceHandleRef.boundElement = sourceBoundElement;
|
|
1243
|
+
sourceHandleRef.direction = sourceDirection;
|
|
1244
|
+
sourceHandleRef.point = sourcePoint;
|
|
1245
|
+
sourceHandleRef.vector = sourceVector;
|
|
1246
|
+
}
|
|
1247
|
+
if (targetBoundElement) {
|
|
1248
|
+
const connectionOffset = PlaitLine.isSourceMarkOrTargetMark(element, LineMarkerType.none, LineHandleKey.target) ? 0 : strokeWidth;
|
|
1249
|
+
const targetVector = getVectorByConnection(targetBoundElement, element.target.connection);
|
|
1250
|
+
const direction = getDirectionByVector(targetVector);
|
|
1251
|
+
targetDirection = direction ? direction : targetDirection;
|
|
1252
|
+
targetPoint = getConnectionPoint(targetBoundElement, element.target.connection, targetDirection, connectionOffset);
|
|
1253
|
+
targetHandleRef.boundElement = targetBoundElement;
|
|
1254
|
+
targetHandleRef.direction = targetDirection;
|
|
1255
|
+
targetHandleRef.point = targetPoint;
|
|
1256
|
+
targetHandleRef.vector = targetVector;
|
|
1257
|
+
}
|
|
1258
|
+
return { source: sourceHandleRef, target: targetHandleRef };
|
|
532
1259
|
};
|
|
533
1260
|
const getElbowPoints = (board, element) => {
|
|
534
1261
|
if (element.points.length === 2) {
|
|
535
|
-
const
|
|
536
|
-
const
|
|
537
|
-
let
|
|
538
|
-
|
|
539
|
-
if (element.source.connection) {
|
|
540
|
-
sourceDirection = getDirectionByPoint(element.source.connection, sourceDirection);
|
|
541
|
-
}
|
|
542
|
-
if (element.target.connection) {
|
|
543
|
-
targetDirection = getDirectionByPoint(element.target.connection, targetDirection);
|
|
544
|
-
}
|
|
545
|
-
const points = getPoints(source, sourceDirection, target, targetDirection, 30);
|
|
1262
|
+
const handleRefPair = getLineHandleRefPair(board, element);
|
|
1263
|
+
const offset = element.source.boundId || element.target.boundId ? 30 : 0;
|
|
1264
|
+
let points = getPoints(handleRefPair.source.point, handleRefPair.source.direction, handleRefPair.target.point, handleRefPair.target.direction, offset);
|
|
1265
|
+
points = removeDuplicatePoints(points);
|
|
546
1266
|
return points;
|
|
547
1267
|
}
|
|
548
1268
|
return element.points;
|
|
549
1269
|
};
|
|
1270
|
+
const getCurvePoints = (board, element) => {
|
|
1271
|
+
if (element.points.length === 2) {
|
|
1272
|
+
const handleRefPair = getLineHandleRefPair(board, element);
|
|
1273
|
+
const { source, target } = handleRefPair;
|
|
1274
|
+
const sourceBoundElement = handleRefPair.source.boundElement;
|
|
1275
|
+
const targetBoundElement = handleRefPair.target.boundElement;
|
|
1276
|
+
let curvePoints = [source.point];
|
|
1277
|
+
const sumDistance = distanceBetweenPointAndPoint(...source.point, ...target.point);
|
|
1278
|
+
const offset = 12 + sumDistance / 3;
|
|
1279
|
+
if (sourceBoundElement) {
|
|
1280
|
+
curvePoints.push(getPointByVector(source.point, source.vector, offset));
|
|
1281
|
+
}
|
|
1282
|
+
if (targetBoundElement) {
|
|
1283
|
+
curvePoints.push(getPointByVector(target.point, target.vector, offset));
|
|
1284
|
+
}
|
|
1285
|
+
const isSingleBound = (sourceBoundElement && !targetBoundElement) || (!sourceBoundElement && targetBoundElement);
|
|
1286
|
+
if (isSingleBound) {
|
|
1287
|
+
curvePoints.push(target.point);
|
|
1288
|
+
const points = Q2C(curvePoints);
|
|
1289
|
+
return pointsOnBezierCurves(points);
|
|
1290
|
+
}
|
|
1291
|
+
if (!sourceBoundElement && !targetBoundElement) {
|
|
1292
|
+
curvePoints.push(getPointByVector(source.point, source.vector, offset));
|
|
1293
|
+
curvePoints.push(getPointByVector(target.point, target.vector, offset));
|
|
1294
|
+
}
|
|
1295
|
+
curvePoints.push(target.point);
|
|
1296
|
+
return pointsOnBezierCurves(curvePoints);
|
|
1297
|
+
}
|
|
1298
|
+
else {
|
|
1299
|
+
//TODO 直接获取贝塞尔曲线上高密度点
|
|
1300
|
+
const points = PlaitLine.getPoints(board, element);
|
|
1301
|
+
const draw = PlaitBoard.getRoughSVG(board).generator.curve(points);
|
|
1302
|
+
let bezierPoints = transformOpsToPoints(draw.sets[0].ops);
|
|
1303
|
+
bezierPoints = removeDuplicatePoints(bezierPoints);
|
|
1304
|
+
return pointsOnBezierCurves(bezierPoints);
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
const transformOpsToPoints = (ops) => {
|
|
1308
|
+
const result = [];
|
|
1309
|
+
for (let item of ops) {
|
|
1310
|
+
if (item.op === 'move') {
|
|
1311
|
+
result.push([item.data[0], item.data[1]]);
|
|
1312
|
+
}
|
|
1313
|
+
else {
|
|
1314
|
+
result.push([item.data[0], item.data[1]]);
|
|
1315
|
+
result.push([item.data[2], item.data[3]]);
|
|
1316
|
+
result.push([item.data[4], item.data[5]]);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
return result;
|
|
1320
|
+
};
|
|
550
1321
|
const isHitPolyLine = (pathPoints, point, strokeWidth, expand = 0) => {
|
|
551
1322
|
const distance = distanceBetweenPointAndSegments(pathPoints, point);
|
|
552
1323
|
return distance <= strokeWidth + expand;
|
|
@@ -576,20 +1347,28 @@ const drawLine = (board, element) => {
|
|
|
576
1347
|
const strokeLineDash = getLineDashByElement(element);
|
|
577
1348
|
const options = { stroke: strokeColor, strokeWidth, strokeLineDash };
|
|
578
1349
|
const lineG = createG();
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
1350
|
+
let points = getLinePoints(board, element);
|
|
1351
|
+
let line;
|
|
1352
|
+
if (element.shape === LineShape.curve) {
|
|
1353
|
+
//TODO element.points 应为曲线拐点
|
|
1354
|
+
line = PlaitBoard.getRoughSVG(board).curve(points, options);
|
|
1355
|
+
}
|
|
1356
|
+
else {
|
|
1357
|
+
line = drawLinearPath(points, options);
|
|
1358
|
+
}
|
|
1359
|
+
const id = idCreator();
|
|
1360
|
+
line.setAttribute('mask', `url(#${id})`);
|
|
582
1361
|
lineG.appendChild(line);
|
|
583
|
-
const { mask, maskTargetFillRect } = drawMask(board, element);
|
|
1362
|
+
const { mask, maskTargetFillRect } = drawMask(board, element, id);
|
|
584
1363
|
lineG.appendChild(mask);
|
|
585
1364
|
line.appendChild(maskTargetFillRect);
|
|
586
|
-
const arrow = drawLineArrow(element, points,
|
|
1365
|
+
const arrow = drawLineArrow(element, points, { stroke: strokeColor, strokeWidth });
|
|
587
1366
|
arrow && lineG.appendChild(arrow);
|
|
588
1367
|
return lineG;
|
|
589
1368
|
};
|
|
590
|
-
function drawMask(board, element) {
|
|
1369
|
+
function drawMask(board, element, id) {
|
|
591
1370
|
const mask = createMask();
|
|
592
|
-
mask.setAttribute('id',
|
|
1371
|
+
mask.setAttribute('id', id);
|
|
593
1372
|
const points = getLinePoints(board, element);
|
|
594
1373
|
let rectangle = getRectangleByPoints(points);
|
|
595
1374
|
rectangle = RectangleClient.getOutlineRectangle(rectangle, -30);
|
|
@@ -610,33 +1389,16 @@ function drawMask(board, element) {
|
|
|
610
1389
|
maskTargetFillRect.setAttribute('opacity', '0');
|
|
611
1390
|
return { mask, maskTargetFillRect };
|
|
612
1391
|
}
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const
|
|
617
|
-
const
|
|
618
|
-
return
|
|
1392
|
+
const getConnectionPoint = (geometry, connection, direction, delta) => {
|
|
1393
|
+
const rectangle = getRectangleByPoints(geometry.points);
|
|
1394
|
+
if (direction && delta) {
|
|
1395
|
+
const directionFactor = getDirectionFactor(direction);
|
|
1396
|
+
const point = RectangleClient.getConnectionPoint(rectangle, connection);
|
|
1397
|
+
return [point[0] + directionFactor.x * delta, point[1] + directionFactor.y * delta];
|
|
619
1398
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
const getTargetPoint = (board, element) => {
|
|
623
|
-
if (element.target.boundId) {
|
|
624
|
-
const strokeWidth = getStrokeWidthByElement(element);
|
|
625
|
-
const connectionOffset = PlaitLine.isTargetMark(element, LineMarkerType.none) ? 0 : strokeWidth;
|
|
626
|
-
const boundElement = getElementById(board, element.target.boundId);
|
|
627
|
-
return boundElement
|
|
628
|
-
? getConnectionPoint(boundElement, element.target.connection, connectionOffset)
|
|
629
|
-
: element.points[element.points.length - 1];
|
|
1399
|
+
else {
|
|
1400
|
+
return RectangleClient.getConnectionPoint(rectangle, connection);
|
|
630
1401
|
}
|
|
631
|
-
return element.points[element.points.length - 1];
|
|
632
|
-
};
|
|
633
|
-
const getConnectionPoint = (geometry, connection, offset) => {
|
|
634
|
-
const rectangle = getRectangleByPoints(geometry.points);
|
|
635
|
-
const directionFactor = getDirectionFactor(getDirectionByPoint(connection, Direction.bottom));
|
|
636
|
-
return [
|
|
637
|
-
rectangle.x + rectangle.width * connection[0] + directionFactor.x * offset,
|
|
638
|
-
rectangle.y + rectangle.height * connection[1] + directionFactor.y * offset
|
|
639
|
-
];
|
|
640
1402
|
};
|
|
641
1403
|
const transformPointToConnection = (board, point, hitElement) => {
|
|
642
1404
|
let rectangle = getRectangleByPoints(hitElement.points);
|
|
@@ -647,7 +1409,8 @@ const transformPointToConnection = (board, point, hitElement) => {
|
|
|
647
1409
|
return [(nearestPoint[0] - rectangle.x) / rectangle.width, (nearestPoint[1] - rectangle.y) / rectangle.height];
|
|
648
1410
|
};
|
|
649
1411
|
const getHitConnectorPoint = (movingPoint, hitElement, rectangle) => {
|
|
650
|
-
const
|
|
1412
|
+
const shape = getShape(hitElement);
|
|
1413
|
+
const connector = getEngine(shape).getConnectorPoints(rectangle);
|
|
651
1414
|
const points = getPointsByCenterPoint(movingPoint, 5, 5);
|
|
652
1415
|
const pointRectangle = getRectangleByPoints(points);
|
|
653
1416
|
return connector.find(point => {
|
|
@@ -671,6 +1434,64 @@ const getBoardLines = (board) => {
|
|
|
671
1434
|
recursion: (element) => PlaitDrawElement.isDrawElement(element)
|
|
672
1435
|
});
|
|
673
1436
|
};
|
|
1437
|
+
const removeDuplicatePoints = (points) => {
|
|
1438
|
+
const newArray = [];
|
|
1439
|
+
points.forEach(point => {
|
|
1440
|
+
const index = newArray.findIndex(otherPoint => {
|
|
1441
|
+
return point[0] === otherPoint[0] && point[1] === otherPoint[1];
|
|
1442
|
+
});
|
|
1443
|
+
if (index === -1)
|
|
1444
|
+
newArray.push(point);
|
|
1445
|
+
});
|
|
1446
|
+
return newArray;
|
|
1447
|
+
};
|
|
1448
|
+
const getExtendPoint = (source, target, extendDistance) => {
|
|
1449
|
+
const distance = distanceBetweenPointAndPoint(...source, ...target);
|
|
1450
|
+
const sin = (target[1] - source[1]) / distance;
|
|
1451
|
+
const cos = (target[0] - source[0]) / distance;
|
|
1452
|
+
return [source[0] + extendDistance * cos, source[1] + extendDistance * sin];
|
|
1453
|
+
};
|
|
1454
|
+
// quadratic Bezier to cubic Bezier
|
|
1455
|
+
const Q2C = (points) => {
|
|
1456
|
+
const result = [];
|
|
1457
|
+
const numSegments = points.length / 3;
|
|
1458
|
+
for (let i = 0; i < numSegments; i++) {
|
|
1459
|
+
const start = points[i];
|
|
1460
|
+
const qControl = points[i + 1];
|
|
1461
|
+
const end = points[i + 2];
|
|
1462
|
+
const startDistance = distanceBetweenPointAndPoint(...start, ...qControl);
|
|
1463
|
+
const endDistance = distanceBetweenPointAndPoint(...end, ...qControl);
|
|
1464
|
+
const cControl1 = getExtendPoint(start, qControl, (startDistance * 2) / 3);
|
|
1465
|
+
const cControl2 = getExtendPoint(end, qControl, (endDistance * 2) / 3);
|
|
1466
|
+
result.push(start, cControl1, cControl2, end);
|
|
1467
|
+
}
|
|
1468
|
+
return result;
|
|
1469
|
+
};
|
|
1470
|
+
const getVectorByConnection = (boundElement, connection) => {
|
|
1471
|
+
const rectangle = getRectangleByPoints(boundElement.points);
|
|
1472
|
+
const shape = getShape(boundElement);
|
|
1473
|
+
const engine = getEngine(shape);
|
|
1474
|
+
let vector = [0, 0];
|
|
1475
|
+
const direction = getDirectionByPointOfRectangle(connection);
|
|
1476
|
+
if (direction) {
|
|
1477
|
+
const factor = getDirectionFactor(direction);
|
|
1478
|
+
return [factor.x, factor.y];
|
|
1479
|
+
}
|
|
1480
|
+
if (engine.getEdgeByConnectionPoint) {
|
|
1481
|
+
const edge = engine.getEdgeByConnectionPoint(rectangle, connection);
|
|
1482
|
+
if (edge) {
|
|
1483
|
+
const lineVector = [edge[1][0] - edge[0][0], edge[1][1] - edge[0][1]];
|
|
1484
|
+
return rotateVectorAnti90(lineVector);
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
if (engine.getTangentVectorByConnectionPoint) {
|
|
1488
|
+
const lineVector = engine.getTangentVectorByConnectionPoint(rectangle, connection);
|
|
1489
|
+
if (lineVector) {
|
|
1490
|
+
return rotateVectorAnti90(lineVector);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
return vector;
|
|
1494
|
+
};
|
|
674
1495
|
|
|
675
1496
|
const getSelectedDrawElements = (board) => {
|
|
676
1497
|
const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isDrawElement(value));
|
|
@@ -684,6 +1505,111 @@ const getSelectedLineElements = (board) => {
|
|
|
684
1505
|
const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isLine(value));
|
|
685
1506
|
return selectedElements;
|
|
686
1507
|
};
|
|
1508
|
+
const getSelectedImageElements = (board) => {
|
|
1509
|
+
const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isImage(value));
|
|
1510
|
+
return selectedElements;
|
|
1511
|
+
};
|
|
1512
|
+
|
|
1513
|
+
var LineMarkerType;
|
|
1514
|
+
(function (LineMarkerType) {
|
|
1515
|
+
LineMarkerType["arrow"] = "arrow";
|
|
1516
|
+
LineMarkerType["none"] = "none";
|
|
1517
|
+
LineMarkerType["openTriangle"] = "open-triangle";
|
|
1518
|
+
LineMarkerType["solidTriangle"] = "solid-triangle";
|
|
1519
|
+
LineMarkerType["sharpArrow"] = "sharp-arrow";
|
|
1520
|
+
LineMarkerType["oneSideUp"] = "one-side-up";
|
|
1521
|
+
LineMarkerType["oneSideDown"] = "one-side-down";
|
|
1522
|
+
LineMarkerType["hollowTriangle"] = "hollow-triangle";
|
|
1523
|
+
LineMarkerType["singleSlash"] = "single-slash";
|
|
1524
|
+
})(LineMarkerType || (LineMarkerType = {}));
|
|
1525
|
+
var LineShape;
|
|
1526
|
+
(function (LineShape) {
|
|
1527
|
+
LineShape["straight"] = "straight";
|
|
1528
|
+
LineShape["curve"] = "curve";
|
|
1529
|
+
LineShape["elbow"] = "elbow";
|
|
1530
|
+
})(LineShape || (LineShape = {}));
|
|
1531
|
+
var LineHandleKey;
|
|
1532
|
+
(function (LineHandleKey) {
|
|
1533
|
+
LineHandleKey["source"] = "source";
|
|
1534
|
+
LineHandleKey["target"] = "target";
|
|
1535
|
+
})(LineHandleKey || (LineHandleKey = {}));
|
|
1536
|
+
const PlaitLine = {
|
|
1537
|
+
getTextEditors(element) {
|
|
1538
|
+
const component = PlaitElement.getComponent(element);
|
|
1539
|
+
if (component) {
|
|
1540
|
+
const manage = component.textManages.find(manage => manage.isEditing);
|
|
1541
|
+
if (manage) {
|
|
1542
|
+
return [manage.componentRef.instance.editor];
|
|
1543
|
+
}
|
|
1544
|
+
else {
|
|
1545
|
+
return component.textManages.map(manage => manage.componentRef.instance.editor);
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
throw new Error('can not get correctly component in get text editor');
|
|
1549
|
+
},
|
|
1550
|
+
isSourceMarkOrTargetMark(line, markType, handleKey) {
|
|
1551
|
+
if (handleKey === LineHandleKey.source) {
|
|
1552
|
+
return line.source.marker === markType;
|
|
1553
|
+
}
|
|
1554
|
+
else {
|
|
1555
|
+
return line.target.marker === markType;
|
|
1556
|
+
}
|
|
1557
|
+
},
|
|
1558
|
+
isSourceMark(line, markType) {
|
|
1559
|
+
return PlaitLine.isSourceMarkOrTargetMark(line, markType, LineHandleKey.source);
|
|
1560
|
+
},
|
|
1561
|
+
isTargetMark(line, markType) {
|
|
1562
|
+
return PlaitLine.isSourceMarkOrTargetMark(line, markType, LineHandleKey.target);
|
|
1563
|
+
},
|
|
1564
|
+
isBoundElementOfSource(line, element) {
|
|
1565
|
+
return line.source.boundId === element.id;
|
|
1566
|
+
},
|
|
1567
|
+
isBoundElementOfTarget(line, element) {
|
|
1568
|
+
return line.target.boundId === element.id;
|
|
1569
|
+
},
|
|
1570
|
+
getPoints(board, line) {
|
|
1571
|
+
let sourcePoint = line.source.boundId
|
|
1572
|
+
? getConnectionPoint(getElementById(board, line.source.boundId), line.source.connection)
|
|
1573
|
+
: line.points[0];
|
|
1574
|
+
let targetPoint = line.target.boundId
|
|
1575
|
+
? getConnectionPoint(getElementById(board, line.target.boundId), line.target.connection)
|
|
1576
|
+
: line.points[line.points.length - 1];
|
|
1577
|
+
const restPoints = line.points.length > 2 ? line.points.slice(1, line.points.length - 1) : [];
|
|
1578
|
+
return [sourcePoint, ...restPoints, targetPoint];
|
|
1579
|
+
}
|
|
1580
|
+
};
|
|
1581
|
+
|
|
1582
|
+
var StrokeStyle;
|
|
1583
|
+
(function (StrokeStyle) {
|
|
1584
|
+
StrokeStyle["solid"] = "solid";
|
|
1585
|
+
StrokeStyle["dashed"] = "dashed";
|
|
1586
|
+
})(StrokeStyle || (StrokeStyle = {}));
|
|
1587
|
+
|
|
1588
|
+
const PlaitDrawElement = {
|
|
1589
|
+
isGeometry: (value) => {
|
|
1590
|
+
return value.type === 'geometry';
|
|
1591
|
+
},
|
|
1592
|
+
isLine: (value) => {
|
|
1593
|
+
return value.type === 'line';
|
|
1594
|
+
},
|
|
1595
|
+
isText: (value) => {
|
|
1596
|
+
return value.type === 'geometry' && value.shape === GeometryShape.text;
|
|
1597
|
+
},
|
|
1598
|
+
isImage: (value) => {
|
|
1599
|
+
return value.type === 'image';
|
|
1600
|
+
},
|
|
1601
|
+
isDrawElement: (value) => {
|
|
1602
|
+
if (PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isLine(value) || PlaitDrawElement.isImage(value)) {
|
|
1603
|
+
return true;
|
|
1604
|
+
}
|
|
1605
|
+
else {
|
|
1606
|
+
return false;
|
|
1607
|
+
}
|
|
1608
|
+
},
|
|
1609
|
+
isShape: (value) => {
|
|
1610
|
+
return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value);
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
687
1613
|
|
|
688
1614
|
class GeometryShapeGenerator extends Generator {
|
|
689
1615
|
canDraw(element, data) {
|
|
@@ -699,7 +1625,12 @@ class GeometryShapeGenerator extends Generator {
|
|
|
699
1625
|
const strokeColor = getStrokeColorByElement(element);
|
|
700
1626
|
const fill = getFillByElement(element);
|
|
701
1627
|
const strokeLineDash = getLineDashByElement(element);
|
|
702
|
-
return drawGeometry(this.board, RectangleClient.inflate(rectangle, -strokeWidth), shape, {
|
|
1628
|
+
return drawGeometry(this.board, RectangleClient.inflate(rectangle, -strokeWidth), shape, {
|
|
1629
|
+
stroke: strokeColor,
|
|
1630
|
+
strokeWidth,
|
|
1631
|
+
fill,
|
|
1632
|
+
strokeLineDash
|
|
1633
|
+
});
|
|
703
1634
|
}
|
|
704
1635
|
}
|
|
705
1636
|
|
|
@@ -779,6 +1710,28 @@ const setTextSize = (board, element, textWidth, textHeight) => {
|
|
|
779
1710
|
}
|
|
780
1711
|
};
|
|
781
1712
|
|
|
1713
|
+
const insertImage = (board, imageItem, startPoint) => {
|
|
1714
|
+
const { width, height, url } = imageItem;
|
|
1715
|
+
const host = BOARD_TO_HOST.get(board);
|
|
1716
|
+
const viewportWidth = PlaitBoard.getComponent(board).nativeElement.clientWidth;
|
|
1717
|
+
const viewportHeight = PlaitBoard.getComponent(board).nativeElement.clientHeight;
|
|
1718
|
+
const point = transformPoint(board, toPoint(viewportWidth / 2, viewportHeight / 2, host));
|
|
1719
|
+
const points = startPoint
|
|
1720
|
+
? [startPoint, [startPoint[0] + width, startPoint[1] + height]]
|
|
1721
|
+
: [
|
|
1722
|
+
[point[0] - width / 2, point[1] - height / 2],
|
|
1723
|
+
[point[0] + width / 2, point[1] + height / 2]
|
|
1724
|
+
];
|
|
1725
|
+
const imageElement = {
|
|
1726
|
+
id: idCreator(),
|
|
1727
|
+
type: 'image',
|
|
1728
|
+
points,
|
|
1729
|
+
url
|
|
1730
|
+
};
|
|
1731
|
+
Transforms.insertNode(board, imageElement, [board.children.length]);
|
|
1732
|
+
Transforms.addSelectionWithTemporaryElements(board, [imageElement]);
|
|
1733
|
+
};
|
|
1734
|
+
|
|
782
1735
|
const resizeLine = (board, options, path) => {
|
|
783
1736
|
Transforms.setNode(board, options, path);
|
|
784
1737
|
};
|
|
@@ -809,7 +1762,8 @@ const DrawTransforms = {
|
|
|
809
1762
|
resizeLine,
|
|
810
1763
|
setLineTexts,
|
|
811
1764
|
removeLineText,
|
|
812
|
-
setLineMark
|
|
1765
|
+
setLineMark,
|
|
1766
|
+
insertImage
|
|
813
1767
|
};
|
|
814
1768
|
|
|
815
1769
|
class GeometryComponent extends CommonPluginElement {
|
|
@@ -827,10 +1781,19 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
827
1781
|
getStrokeWidth: () => {
|
|
828
1782
|
const selectedElements = getSelectedElements(this.board);
|
|
829
1783
|
if (selectedElements.length === 1 && !isSelectionMoving(this.board)) {
|
|
830
|
-
return
|
|
1784
|
+
return ACTIVE_STROKE_WIDTH;
|
|
1785
|
+
}
|
|
1786
|
+
else {
|
|
1787
|
+
return ACTIVE_STROKE_WIDTH;
|
|
1788
|
+
}
|
|
1789
|
+
},
|
|
1790
|
+
getStrokeOpacity: () => {
|
|
1791
|
+
const selectedElements = getSelectedElements(this.board);
|
|
1792
|
+
if (selectedElements.length === 1 && !isSelectionMoving(this.board)) {
|
|
1793
|
+
return 1;
|
|
831
1794
|
}
|
|
832
1795
|
else {
|
|
833
|
-
return
|
|
1796
|
+
return 0.5;
|
|
834
1797
|
}
|
|
835
1798
|
},
|
|
836
1799
|
getRectangle: (element) => {
|
|
@@ -884,6 +1847,10 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
884
1847
|
const plugins = this.board.getPluginOptions(WithTextPluginKey).textPlugins;
|
|
885
1848
|
const manage = new TextManage(this.board, this.viewContainerRef, {
|
|
886
1849
|
getRectangle: () => {
|
|
1850
|
+
const getRectangle = getEngine(this.element.shape).getTextRectangle;
|
|
1851
|
+
if (getRectangle) {
|
|
1852
|
+
return getRectangle(this.element);
|
|
1853
|
+
}
|
|
887
1854
|
return getTextRectangle(this.element);
|
|
888
1855
|
},
|
|
889
1856
|
onValueChangeHandle: (textManageRef) => {
|
|
@@ -911,14 +1878,15 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
911
1878
|
this.destroy$.complete();
|
|
912
1879
|
}
|
|
913
1880
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: GeometryComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
914
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: GeometryComponent, selector: "plait-draw-geometry", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1881
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: GeometryComponent, isStandalone: true, selector: "plait-draw-geometry", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
915
1882
|
}
|
|
916
1883
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: GeometryComponent, decorators: [{
|
|
917
1884
|
type: Component,
|
|
918
1885
|
args: [{
|
|
919
1886
|
selector: 'plait-draw-geometry',
|
|
920
1887
|
template: ``,
|
|
921
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
1888
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1889
|
+
standalone: true
|
|
922
1890
|
}]
|
|
923
1891
|
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
|
|
924
1892
|
|
|
@@ -927,21 +1895,17 @@ class LineShapeGenerator extends Generator {
|
|
|
927
1895
|
return true;
|
|
928
1896
|
}
|
|
929
1897
|
baseDraw(element, data) {
|
|
930
|
-
const shape = element.shape;
|
|
931
1898
|
let lineG;
|
|
932
|
-
|
|
933
|
-
case LineShape.elbow:
|
|
934
|
-
case LineShape.straight:
|
|
935
|
-
lineG = drawLine(this.board, element);
|
|
936
|
-
break;
|
|
937
|
-
default:
|
|
938
|
-
break;
|
|
939
|
-
}
|
|
1899
|
+
lineG = drawLine(this.board, element);
|
|
940
1900
|
return lineG;
|
|
941
1901
|
}
|
|
942
1902
|
}
|
|
943
1903
|
|
|
944
1904
|
class LineActiveGenerator extends Generator {
|
|
1905
|
+
constructor() {
|
|
1906
|
+
super(...arguments);
|
|
1907
|
+
this.hasResizeHandle = false;
|
|
1908
|
+
}
|
|
945
1909
|
canDraw(element, data) {
|
|
946
1910
|
if (data.selected) {
|
|
947
1911
|
return true;
|
|
@@ -952,27 +1916,70 @@ class LineActiveGenerator extends Generator {
|
|
|
952
1916
|
}
|
|
953
1917
|
baseDraw(element, data) {
|
|
954
1918
|
const activeG = createG();
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1919
|
+
if (this.hasResizeHandle) {
|
|
1920
|
+
activeG.classList.add('active');
|
|
1921
|
+
activeG.classList.add('line-handle');
|
|
1922
|
+
const points = PlaitLine.getPoints(this.board, element);
|
|
1923
|
+
points.forEach(point => {
|
|
1924
|
+
const circle = drawCircle(PlaitBoard.getRoughSVG(this.board), point, RESIZE_HANDLE_DIAMETER, {
|
|
1925
|
+
stroke: '#999999',
|
|
1926
|
+
strokeWidth: 1,
|
|
1927
|
+
fill: '#FFF',
|
|
1928
|
+
fillStyle: 'solid'
|
|
1929
|
+
});
|
|
1930
|
+
activeG.appendChild(circle);
|
|
1931
|
+
});
|
|
1932
|
+
getMiddlePoints(this.board, element).forEach(point => {
|
|
1933
|
+
const circle = drawCircle(PlaitBoard.getRoughSVG(this.board), point, RESIZE_HANDLE_DIAMETER, {
|
|
1934
|
+
stroke: '#FFFFFF80',
|
|
1935
|
+
strokeWidth: 1,
|
|
1936
|
+
fill: `${PRIMARY_COLOR}80`,
|
|
1937
|
+
fillStyle: 'solid'
|
|
1938
|
+
});
|
|
1939
|
+
activeG.appendChild(circle);
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1942
|
+
else {
|
|
1943
|
+
const points = getLinePoints(this.board, element);
|
|
1944
|
+
const activeRectangle = getRectangleByPoints(points);
|
|
1945
|
+
const strokeG = drawRectangle(this.board, activeRectangle, {
|
|
1946
|
+
stroke: PRIMARY_COLOR,
|
|
1947
|
+
strokeWidth: DefaultGeometryActiveStyle.selectionStrokeWidth
|
|
1948
|
+
});
|
|
1949
|
+
activeG.appendChild(strokeG);
|
|
1950
|
+
}
|
|
973
1951
|
return activeG;
|
|
974
1952
|
}
|
|
975
1953
|
}
|
|
1954
|
+
function getMiddlePoints(board, element) {
|
|
1955
|
+
const result = [];
|
|
1956
|
+
const shape = element.shape;
|
|
1957
|
+
if (shape === LineShape.straight) {
|
|
1958
|
+
const points = PlaitLine.getPoints(board, element);
|
|
1959
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
1960
|
+
result.push([(points[i][0] + points[i + 1][0]) / 2, (points[i][1] + points[i + 1][1]) / 2]);
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
if (shape === LineShape.curve) {
|
|
1964
|
+
const points = PlaitLine.getPoints(board, element);
|
|
1965
|
+
const pointsOnBezier = getCurvePoints(board, element);
|
|
1966
|
+
if (points.length === 2) {
|
|
1967
|
+
const start = 0;
|
|
1968
|
+
const endIndex = pointsOnBezier.length - 1;
|
|
1969
|
+
const middleIndex = Math.round((start + endIndex) / 2);
|
|
1970
|
+
result.push(pointsOnBezier[middleIndex]);
|
|
1971
|
+
}
|
|
1972
|
+
else {
|
|
1973
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
1974
|
+
const startIndex = pointsOnBezier.findIndex(point => point[0] === points[i][0] && point[1] === points[i][1]);
|
|
1975
|
+
const endIndex = pointsOnBezier.findIndex(point => point[0] === points[i + 1][0] && point[1] === points[i + 1][1]);
|
|
1976
|
+
const middleIndex = Math.round((startIndex + endIndex) / 2);
|
|
1977
|
+
result.push(pointsOnBezier[middleIndex]);
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
return result;
|
|
1982
|
+
}
|
|
976
1983
|
|
|
977
1984
|
class LineComponent extends PlaitPluginElementComponent {
|
|
978
1985
|
constructor(viewContainerRef, cdr) {
|
|
@@ -1028,11 +2035,18 @@ class LineComponent extends PlaitPluginElementComponent {
|
|
|
1028
2035
|
this.updateTextRectangle();
|
|
1029
2036
|
return;
|
|
1030
2037
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
2038
|
+
if (!isSelectionMoving(this.board)) {
|
|
2039
|
+
this.activeGenerator.hasResizeHandle = this.hasResizeHandle();
|
|
1033
2040
|
this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
|
|
1034
2041
|
}
|
|
1035
2042
|
}
|
|
2043
|
+
hasResizeHandle() {
|
|
2044
|
+
const selectedElements = getSelectedElements(this.board);
|
|
2045
|
+
if (PlaitBoard.hasBeenTextEditing(this.board) && PlaitDrawElement.isText(this.element)) {
|
|
2046
|
+
return false;
|
|
2047
|
+
}
|
|
2048
|
+
return selectedElements.length === 1 && !isSelectionMoving(this.board);
|
|
2049
|
+
}
|
|
1036
2050
|
initializeTextManages() {
|
|
1037
2051
|
if (this.element.texts?.length) {
|
|
1038
2052
|
this.element.texts.forEach((text, index) => {
|
|
@@ -1105,14 +2119,15 @@ class LineComponent extends PlaitPluginElementComponent {
|
|
|
1105
2119
|
this.destroy$.complete();
|
|
1106
2120
|
}
|
|
1107
2121
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: LineComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1108
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: LineComponent, selector: "plait-draw-line", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2122
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: LineComponent, isStandalone: true, selector: "plait-draw-line", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1109
2123
|
}
|
|
1110
2124
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: LineComponent, decorators: [{
|
|
1111
2125
|
type: Component,
|
|
1112
2126
|
args: [{
|
|
1113
2127
|
selector: 'plait-draw-line',
|
|
1114
2128
|
template: ``,
|
|
1115
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
2129
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2130
|
+
standalone: true
|
|
1116
2131
|
}]
|
|
1117
2132
|
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
|
|
1118
2133
|
|
|
@@ -1152,13 +2167,14 @@ const withGeometryCreateByDrag = (board) => {
|
|
|
1152
2167
|
geometryShapeG?.remove();
|
|
1153
2168
|
geometryShapeG = createG();
|
|
1154
2169
|
const geometryGenerator = new GeometryShapeGenerator(board);
|
|
1155
|
-
const
|
|
2170
|
+
const geometryPointers = getGeometryPointers();
|
|
2171
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
1156
2172
|
const dragMode = isGeometryPointer && isDndMode(board);
|
|
1157
2173
|
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1158
2174
|
const pointer = PlaitBoard.getPointer(board);
|
|
1159
2175
|
if (dragMode) {
|
|
1160
2176
|
const points = getDefaultGeometryPoints(pointer, movingPoint);
|
|
1161
|
-
if (pointer ===
|
|
2177
|
+
if (pointer === GeometryShape.text) {
|
|
1162
2178
|
const textG = getTemporaryTextG(movingPoint);
|
|
1163
2179
|
geometryShapeG.appendChild(textG);
|
|
1164
2180
|
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
@@ -1176,12 +2192,13 @@ const withGeometryCreateByDrag = (board) => {
|
|
|
1176
2192
|
};
|
|
1177
2193
|
board.pointerUp = (event) => {
|
|
1178
2194
|
const pointer = PlaitBoard.getPointer(board);
|
|
1179
|
-
const
|
|
2195
|
+
const geometryPointers = getGeometryPointers();
|
|
2196
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
1180
2197
|
const dragMode = isGeometryPointer && isDndMode(board);
|
|
1181
2198
|
if (dragMode) {
|
|
1182
2199
|
const targetPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1183
2200
|
const points = getDefaultGeometryPoints(pointer, targetPoint);
|
|
1184
|
-
if (pointer ===
|
|
2201
|
+
if (pointer === GeometryShape.text) {
|
|
1185
2202
|
DrawTransforms.insertText(board, points);
|
|
1186
2203
|
}
|
|
1187
2204
|
else {
|
|
@@ -1196,7 +2213,7 @@ const withGeometryCreateByDrag = (board) => {
|
|
|
1196
2213
|
};
|
|
1197
2214
|
return board;
|
|
1198
2215
|
};
|
|
1199
|
-
const
|
|
2216
|
+
const withGeometryCreateByDrawing = (board) => {
|
|
1200
2217
|
const { pointerDown, pointerMove, pointerUp, keydown, keyup } = board;
|
|
1201
2218
|
let start = null;
|
|
1202
2219
|
let geometryShapeG = null;
|
|
@@ -1211,13 +2228,14 @@ const withGeometryCreateByDraw = (board) => {
|
|
|
1211
2228
|
keyup(event);
|
|
1212
2229
|
};
|
|
1213
2230
|
board.pointerDown = (event) => {
|
|
1214
|
-
const
|
|
2231
|
+
const geometryPointers = getGeometryPointers();
|
|
2232
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
1215
2233
|
if (isGeometryPointer && isDrawingMode(board)) {
|
|
1216
2234
|
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1217
2235
|
start = point;
|
|
1218
2236
|
const pointer = PlaitBoard.getPointer(board);
|
|
1219
2237
|
preventTouchMove(board, event, true);
|
|
1220
|
-
if (pointer ===
|
|
2238
|
+
if (pointer === GeometryShape.text) {
|
|
1221
2239
|
const points = getDefaultGeometryPoints(pointer, point);
|
|
1222
2240
|
const textElement = createGeometryElement(GeometryShape.text, points, DefaultTextProperty.text);
|
|
1223
2241
|
Transforms.insertNode(board, textElement, [board.children.length]);
|
|
@@ -1236,7 +2254,7 @@ const withGeometryCreateByDraw = (board) => {
|
|
|
1236
2254
|
const drawMode = !!start;
|
|
1237
2255
|
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1238
2256
|
const pointer = PlaitBoard.getPointer(board);
|
|
1239
|
-
if (drawMode && pointer !==
|
|
2257
|
+
if (drawMode && pointer !== GeometryShape.text) {
|
|
1240
2258
|
const points = normalizeShapePoints([start, movingPoint], isShift);
|
|
1241
2259
|
temporaryElement = createGeometryElement(pointer, points, '', {
|
|
1242
2260
|
strokeColor: DefaultGeometryProperty.strokeColor,
|
|
@@ -1255,7 +2273,7 @@ const withGeometryCreateByDraw = (board) => {
|
|
|
1255
2273
|
if (Math.hypot(width, height) === 0) {
|
|
1256
2274
|
const pointer = PlaitBoard.getPointer(board);
|
|
1257
2275
|
const points = getDefaultGeometryPoints(pointer, targetPoint);
|
|
1258
|
-
if (pointer !==
|
|
2276
|
+
if (pointer !== GeometryShape.text) {
|
|
1259
2277
|
temporaryElement = createGeometryElement(pointer, points, '', {
|
|
1260
2278
|
strokeColor: DefaultGeometryProperty.strokeColor,
|
|
1261
2279
|
strokeWidth: DefaultGeometryProperty.strokeWidth
|
|
@@ -1279,7 +2297,7 @@ const withGeometryCreateByDraw = (board) => {
|
|
|
1279
2297
|
return board;
|
|
1280
2298
|
};
|
|
1281
2299
|
const getDefaultGeometryPoints = (pointer, targetPoint) => {
|
|
1282
|
-
return pointer ===
|
|
2300
|
+
return pointer === GeometryShape.text
|
|
1283
2301
|
? getPointsByCenterPoint(targetPoint, DefaultTextProperty.width, DefaultTextProperty.height)
|
|
1284
2302
|
: getPointsByCenterPoint(targetPoint, DefaultGeometryProperty.width, DefaultGeometryProperty.height);
|
|
1285
2303
|
};
|
|
@@ -1298,7 +2316,7 @@ const getTemporaryTextG = (movingPoint) => {
|
|
|
1298
2316
|
|
|
1299
2317
|
const buildClipboardData = (board, elements, startPoint) => {
|
|
1300
2318
|
return elements.map(element => {
|
|
1301
|
-
if (PlaitDrawElement.isGeometry(element)) {
|
|
2319
|
+
if (PlaitDrawElement.isGeometry(element) || PlaitDrawElement.isImage(element)) {
|
|
1302
2320
|
const points = element.points.map(point => [point[0] - startPoint[0], point[1] - startPoint[1]]);
|
|
1303
2321
|
return { ...element, points };
|
|
1304
2322
|
}
|
|
@@ -1321,7 +2339,7 @@ const buildClipboardData = (board, elements, startPoint) => {
|
|
|
1321
2339
|
};
|
|
1322
2340
|
const insertClipboardData = (board, elements, startPoint) => {
|
|
1323
2341
|
const lines = elements.filter(value => PlaitDrawElement.isLine(value));
|
|
1324
|
-
const geometries = elements.filter(value => PlaitDrawElement.isGeometry(value));
|
|
2342
|
+
const geometries = elements.filter(value => PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isImage(value));
|
|
1325
2343
|
geometries.forEach(element => {
|
|
1326
2344
|
const sourceLines = [];
|
|
1327
2345
|
const targetLines = [];
|
|
@@ -1345,6 +2363,7 @@ const insertClipboardData = (board, elements, startPoint) => {
|
|
|
1345
2363
|
element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
|
|
1346
2364
|
Transforms.insertNode(board, element, [board.children.length]);
|
|
1347
2365
|
});
|
|
2366
|
+
Transforms.addSelectionWithTemporaryElements(board, elements);
|
|
1348
2367
|
};
|
|
1349
2368
|
|
|
1350
2369
|
const withDrawFragment = (baseBoard) => {
|
|
@@ -1353,21 +2372,35 @@ const withDrawFragment = (baseBoard) => {
|
|
|
1353
2372
|
board.getDeletedFragment = (data) => {
|
|
1354
2373
|
const drawElements = getSelectedDrawElements(board);
|
|
1355
2374
|
if (drawElements.length) {
|
|
1356
|
-
const lines = getBoardLines(board);
|
|
1357
2375
|
const geometryElements = drawElements.filter(value => PlaitDrawElement.isGeometry(value));
|
|
1358
2376
|
const lineElements = drawElements.filter(value => PlaitDrawElement.isLine(value));
|
|
1359
|
-
const
|
|
1360
|
-
|
|
2377
|
+
const imageElements = drawElements.filter(value => PlaitDrawElement.isImage(value));
|
|
2378
|
+
const boundLineElements = [
|
|
2379
|
+
...getBoundedLineElements(board, geometryElements),
|
|
2380
|
+
...getBoundedLineElements(board, imageElements)
|
|
2381
|
+
].filter(line => !lineElements.includes(line));
|
|
2382
|
+
data.push(...[
|
|
2383
|
+
...geometryElements,
|
|
2384
|
+
...lineElements,
|
|
2385
|
+
...imageElements,
|
|
2386
|
+
...boundLineElements.filter(line => !lineElements.includes(line))
|
|
2387
|
+
]);
|
|
1361
2388
|
}
|
|
1362
2389
|
return getDeletedFragment(data);
|
|
1363
2390
|
};
|
|
1364
|
-
board.setFragment = (data, rectangle) => {
|
|
2391
|
+
board.setFragment = (data, rectangle, type) => {
|
|
1365
2392
|
const targetDrawElements = getSelectedDrawElements(board);
|
|
2393
|
+
let boundLineElements = [];
|
|
1366
2394
|
if (targetDrawElements.length) {
|
|
1367
|
-
|
|
2395
|
+
if (type === 'cut') {
|
|
2396
|
+
const geometryElements = targetDrawElements.filter(value => PlaitDrawElement.isGeometry(value));
|
|
2397
|
+
const lineElements = targetDrawElements.filter(value => PlaitDrawElement.isLine(value));
|
|
2398
|
+
boundLineElements = getBoundedLineElements(board, geometryElements).filter(line => !lineElements.includes(line));
|
|
2399
|
+
}
|
|
2400
|
+
const elements = buildClipboardData(board, [...targetDrawElements, ...boundLineElements], rectangle ? [rectangle.x, rectangle.y] : [0, 0]);
|
|
1368
2401
|
setClipboardData(data, elements);
|
|
1369
2402
|
}
|
|
1370
|
-
setFragment(data, rectangle);
|
|
2403
|
+
setFragment(data, rectangle, type);
|
|
1371
2404
|
};
|
|
1372
2405
|
board.insertFragment = (data, targetPoint) => {
|
|
1373
2406
|
const elements = getDataFromClipboard(data);
|
|
@@ -1387,10 +2420,24 @@ const withDrawFragment = (baseBoard) => {
|
|
|
1387
2420
|
return;
|
|
1388
2421
|
}
|
|
1389
2422
|
}
|
|
2423
|
+
if (data?.files.length) {
|
|
2424
|
+
const acceptImageArray = acceptImageTypes.map(type => 'image/' + type);
|
|
2425
|
+
if (acceptImageArray.includes(data?.files[0].type)) {
|
|
2426
|
+
const imageFile = data.files[0];
|
|
2427
|
+
buildImage(board, imageFile, DEFAULT_IMAGE_WIDTH, imageItem => {
|
|
2428
|
+
DrawTransforms.insertImage(board, imageItem, targetPoint);
|
|
2429
|
+
});
|
|
2430
|
+
return;
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
1390
2433
|
insertFragment(data, targetPoint);
|
|
1391
2434
|
};
|
|
1392
2435
|
return board;
|
|
1393
2436
|
};
|
|
2437
|
+
const getBoundedLineElements = (board, plaitShapes) => {
|
|
2438
|
+
const lines = getBoardLines(board);
|
|
2439
|
+
return lines.filter(line => plaitShapes.find(shape => PlaitLine.isBoundElementOfSource(line, shape) || PlaitLine.isBoundElementOfTarget(line, shape)));
|
|
2440
|
+
};
|
|
1394
2441
|
|
|
1395
2442
|
const DefaultLineStyle = {
|
|
1396
2443
|
strokeWidth: 2,
|
|
@@ -1408,10 +2455,10 @@ const getHitGeometryResizeHandleRef = (board, element, point) => {
|
|
|
1408
2455
|
const getHitOutlineGeometry = (board, point, offset = 0) => {
|
|
1409
2456
|
let geometry = null;
|
|
1410
2457
|
depthFirstRecursion(board, node => {
|
|
1411
|
-
if (PlaitDrawElement.isGeometry(node)) {
|
|
1412
|
-
const shape = node.shape;
|
|
2458
|
+
if (PlaitDrawElement.isGeometry(node) || PlaitDrawElement.isImage(node)) {
|
|
1413
2459
|
let client = getRectangleByPoints(node.points);
|
|
1414
2460
|
client = RectangleClient.getOutlineRectangle(client, offset);
|
|
2461
|
+
const shape = getShape(node);
|
|
1415
2462
|
const isHit = getEngine(shape).isHit(client, point);
|
|
1416
2463
|
if (isHit) {
|
|
1417
2464
|
geometry = node;
|
|
@@ -1429,7 +2476,8 @@ const withLineCreateByDraw = (board) => {
|
|
|
1429
2476
|
let lineShapeG = null;
|
|
1430
2477
|
let temporaryElement = null;
|
|
1431
2478
|
board.pointerDown = (event) => {
|
|
1432
|
-
const
|
|
2479
|
+
const linePointers = getLinePointers();
|
|
2480
|
+
const isLinePointer = PlaitBoard.isInPointer(board, linePointers);
|
|
1433
2481
|
if (isLinePointer && isDrawingMode(board)) {
|
|
1434
2482
|
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1435
2483
|
start = point;
|
|
@@ -1451,7 +2499,8 @@ const withLineCreateByDraw = (board) => {
|
|
|
1451
2499
|
targetRef.connection = hitElement ? transformPointToConnection(board, movingPoint, hitElement) : undefined;
|
|
1452
2500
|
targetRef.boundId = hitElement ? hitElement.id : undefined;
|
|
1453
2501
|
const lineGenerator = new LineShapeGenerator(board);
|
|
1454
|
-
|
|
2502
|
+
const lineShape = PlaitBoard.getPointer(board);
|
|
2503
|
+
temporaryElement = createLineElement(lineShape, [start, movingPoint], { marker: LineMarkerType.none, connection: sourceRef.connection, boundId: sourceRef?.boundId }, { marker: LineMarkerType.arrow, connection: targetRef.connection, boundId: targetRef?.boundId }, {
|
|
1455
2504
|
strokeColor: DefaultLineStyle.strokeColor,
|
|
1456
2505
|
strokeWidth: DefaultLineStyle.strokeWidth
|
|
1457
2506
|
});
|
|
@@ -1496,12 +2545,12 @@ const withGeometryResize = (board) => {
|
|
|
1496
2545
|
return true;
|
|
1497
2546
|
},
|
|
1498
2547
|
detect: (point) => {
|
|
1499
|
-
const
|
|
1500
|
-
if (
|
|
2548
|
+
const selectedElements = [...getSelectedGeometryElements(board), ...getSelectedImageElements(board)];
|
|
2549
|
+
if (selectedElements.length !== 1 || getSelectedElements(board).length !== 1) {
|
|
1501
2550
|
return null;
|
|
1502
2551
|
}
|
|
1503
|
-
const target =
|
|
1504
|
-
const targetComponent = PlaitElement.getComponent(
|
|
2552
|
+
const target = selectedElements[0];
|
|
2553
|
+
const targetComponent = PlaitElement.getComponent(selectedElements[0]);
|
|
1505
2554
|
if (targetComponent.activeGenerator.hasResizeHandle) {
|
|
1506
2555
|
const handleRef = getHitGeometryResizeHandleRef(board, target, point);
|
|
1507
2556
|
if (handleRef) {
|
|
@@ -1516,27 +2565,34 @@ const withGeometryResize = (board) => {
|
|
|
1516
2565
|
},
|
|
1517
2566
|
onResize: (resizeRef, resizeState) => {
|
|
1518
2567
|
let points = [...resizeRef.element.points];
|
|
2568
|
+
const rectangle = getRectangleByPoints(resizeRef.element.points);
|
|
2569
|
+
const ratio = rectangle.height / rectangle.width;
|
|
1519
2570
|
if (resizeRef.handle === ResizeHandle.nw) {
|
|
1520
2571
|
points = [resizeState.endTransformPoint, resizeRef.element.points[1]];
|
|
1521
2572
|
}
|
|
1522
2573
|
if (resizeRef.handle === ResizeHandle.ne) {
|
|
1523
|
-
points = [
|
|
1524
|
-
[resizeRef.element.points[0][0], resizeState.endTransformPoint[1]],
|
|
1525
|
-
[resizeState.endTransformPoint[0], resizeRef.element.points[1][1]]
|
|
1526
|
-
];
|
|
2574
|
+
points = [resizeState.endTransformPoint, [resizeRef.element.points[0][0], resizeRef.element.points[1][1]]];
|
|
1527
2575
|
}
|
|
1528
2576
|
if (resizeRef.handle === ResizeHandle.se) {
|
|
1529
|
-
points = [resizeRef.element.points[0]
|
|
2577
|
+
points = [resizeState.endTransformPoint, resizeRef.element.points[0]];
|
|
1530
2578
|
}
|
|
1531
2579
|
if (resizeRef.handle === ResizeHandle.sw) {
|
|
1532
|
-
points = [
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
2580
|
+
points = [resizeState.endTransformPoint, [resizeRef.element.points[1][0], resizeRef.element.points[0][1]]];
|
|
2581
|
+
}
|
|
2582
|
+
if (isShift || PlaitDrawElement.isImage(resizeRef.element)) {
|
|
2583
|
+
const rectangle = getRectangleByPoints(points);
|
|
2584
|
+
const factor = points[0][1] > points[1][1] ? 1 : -1;
|
|
2585
|
+
const height = rectangle.width * ratio * factor;
|
|
2586
|
+
points = [[resizeState.endTransformPoint[0], points[1][1] + height], points[1]];
|
|
2587
|
+
}
|
|
2588
|
+
if (PlaitDrawElement.isGeometry(resizeRef.element)) {
|
|
2589
|
+
const { height: textHeight } = PlaitGeometry.getTextManage(resizeRef.element).getSize();
|
|
2590
|
+
DrawTransforms.resizeGeometry(board, points, textHeight, resizeRef.path);
|
|
2591
|
+
}
|
|
2592
|
+
else {
|
|
2593
|
+
points = normalizeShapePoints(points);
|
|
2594
|
+
Transforms.setNode(board, { points }, resizeRef.path);
|
|
1536
2595
|
}
|
|
1537
|
-
points = normalizeShapePoints(points, isShift);
|
|
1538
|
-
const { height: textHeight } = PlaitGeometry.getTextManage(resizeRef.element).getSize();
|
|
1539
|
-
DrawTransforms.resizeGeometry(board, points, textHeight, resizeRef.path);
|
|
1540
2596
|
}
|
|
1541
2597
|
};
|
|
1542
2598
|
withResize(board, options);
|
|
@@ -1547,34 +2603,44 @@ var LineResizeHandle;
|
|
|
1547
2603
|
(function (LineResizeHandle) {
|
|
1548
2604
|
LineResizeHandle["source"] = "source";
|
|
1549
2605
|
LineResizeHandle["target"] = "target";
|
|
2606
|
+
LineResizeHandle["addHandle"] = "addHandle";
|
|
1550
2607
|
})(LineResizeHandle || (LineResizeHandle = {}));
|
|
1551
2608
|
const getHitLineResizeHandleRef = (board, element, point) => {
|
|
1552
|
-
const
|
|
1553
|
-
const
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
y: targetPoint[1] - RESIZE_HANDLE_DIAMETER / 2,
|
|
1563
|
-
width: RESIZE_HANDLE_DIAMETER,
|
|
1564
|
-
height: RESIZE_HANDLE_DIAMETER
|
|
1565
|
-
};
|
|
1566
|
-
const isHitSourceRectangle = RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), sourceRectangle);
|
|
1567
|
-
const isHitTargetRectangle = RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), targetRectangle);
|
|
1568
|
-
if (isHitSourceRectangle) {
|
|
1569
|
-
return { rectangle: sourceRectangle, handle: LineResizeHandle.source };
|
|
2609
|
+
const points = PlaitLine.getPoints(board, element);
|
|
2610
|
+
const index = getHitPointIndex(points, point);
|
|
2611
|
+
if (index !== -1) {
|
|
2612
|
+
if (index === 0) {
|
|
2613
|
+
return { handle: LineResizeHandle.source, index };
|
|
2614
|
+
}
|
|
2615
|
+
if (index === points.length - 1) {
|
|
2616
|
+
return { handle: LineResizeHandle.target, index };
|
|
2617
|
+
}
|
|
2618
|
+
return { index };
|
|
1570
2619
|
}
|
|
1571
|
-
|
|
1572
|
-
|
|
2620
|
+
const middlePoints = getMiddlePoints(board, element);
|
|
2621
|
+
const middleIndex = getHitPointIndex(middlePoints, point);
|
|
2622
|
+
if (middleIndex !== -1) {
|
|
2623
|
+
return { handle: LineResizeHandle.addHandle, index: middleIndex };
|
|
1573
2624
|
}
|
|
1574
2625
|
return undefined;
|
|
1575
2626
|
};
|
|
2627
|
+
function getHitPointIndex(points, movingPoint) {
|
|
2628
|
+
const rectangles = points.map(point => {
|
|
2629
|
+
return {
|
|
2630
|
+
x: point[0] - RESIZE_HANDLE_DIAMETER / 2,
|
|
2631
|
+
y: point[1] - RESIZE_HANDLE_DIAMETER / 2,
|
|
2632
|
+
width: RESIZE_HANDLE_DIAMETER,
|
|
2633
|
+
height: RESIZE_HANDLE_DIAMETER
|
|
2634
|
+
};
|
|
2635
|
+
});
|
|
2636
|
+
const rectangle = rectangles.find(rectangle => {
|
|
2637
|
+
return RectangleClient.isHit(RectangleClient.toRectangleClient([movingPoint, movingPoint]), rectangle);
|
|
2638
|
+
});
|
|
2639
|
+
return rectangle ? rectangles.indexOf(rectangle) : -1;
|
|
2640
|
+
}
|
|
1576
2641
|
|
|
1577
2642
|
const withLineResize = (board) => {
|
|
2643
|
+
let pointIndex = 0;
|
|
1578
2644
|
const options = {
|
|
1579
2645
|
key: 'draw-line',
|
|
1580
2646
|
canResize: () => {
|
|
@@ -1591,6 +2657,7 @@ const withLineResize = (board) => {
|
|
|
1591
2657
|
element: value,
|
|
1592
2658
|
handle: handleRef.handle
|
|
1593
2659
|
};
|
|
2660
|
+
pointIndex = handleRef.index;
|
|
1594
2661
|
}
|
|
1595
2662
|
});
|
|
1596
2663
|
return result;
|
|
@@ -1602,17 +2669,23 @@ const withLineResize = (board) => {
|
|
|
1602
2669
|
let source = { ...resizeRef.element.source };
|
|
1603
2670
|
let target = { ...resizeRef.element.target };
|
|
1604
2671
|
if (resizeRef.handle === LineResizeHandle.source) {
|
|
1605
|
-
points[
|
|
2672
|
+
points[pointIndex] = resizeState.endTransformPoint;
|
|
1606
2673
|
const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, -4);
|
|
1607
2674
|
source.connection = hitElement ? transformPointToConnection(board, resizeState.endTransformPoint, hitElement) : undefined;
|
|
1608
2675
|
source.boundId = hitElement ? hitElement.id : undefined;
|
|
1609
2676
|
}
|
|
1610
|
-
if (resizeRef.handle === LineResizeHandle.target) {
|
|
1611
|
-
points[
|
|
2677
|
+
else if (resizeRef.handle === LineResizeHandle.target) {
|
|
2678
|
+
points[pointIndex] = resizeState.endTransformPoint;
|
|
1612
2679
|
const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, -4);
|
|
1613
2680
|
target.connection = hitElement ? transformPointToConnection(board, resizeState.endTransformPoint, hitElement) : undefined;
|
|
1614
2681
|
target.boundId = hitElement ? hitElement.id : undefined;
|
|
1615
2682
|
}
|
|
2683
|
+
else if (resizeRef.handle === LineResizeHandle.addHandle) {
|
|
2684
|
+
points.splice(pointIndex + 1, 0, resizeState.endTransformPoint);
|
|
2685
|
+
}
|
|
2686
|
+
else {
|
|
2687
|
+
points[pointIndex] = resizeState.endTransformPoint;
|
|
2688
|
+
}
|
|
1616
2689
|
DrawTransforms.resizeLine(board, { points, source, target }, resizeRef.path);
|
|
1617
2690
|
}
|
|
1618
2691
|
};
|
|
@@ -1625,9 +2698,14 @@ const withLineBoundReaction = (board) => {
|
|
|
1625
2698
|
let boundShapeG = null;
|
|
1626
2699
|
board.pointerMove = (event) => {
|
|
1627
2700
|
boundShapeG?.remove();
|
|
1628
|
-
const
|
|
2701
|
+
const linePointers = Object.keys(LineShape);
|
|
2702
|
+
const isLinePointer = PlaitBoard.isInPointer(board, linePointers);
|
|
1629
2703
|
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1630
|
-
const isLineResizing = isResizingByCondition(board,
|
|
2704
|
+
const isLineResizing = isResizingByCondition(board, resizeRef => {
|
|
2705
|
+
const { element, handle } = resizeRef;
|
|
2706
|
+
const isSourceOrTarget = handle === LineResizeHandle.target || handle === LineResizeHandle.source;
|
|
2707
|
+
return PlaitDrawElement.isLine(element) && isSourceOrTarget;
|
|
2708
|
+
});
|
|
1631
2709
|
if (isLinePointer || isLineResizing) {
|
|
1632
2710
|
const hitElement = getHitOutlineGeometry(board, movingPoint, -4);
|
|
1633
2711
|
if (hitElement) {
|
|
@@ -1705,8 +2783,74 @@ function editHandle(board, element, manageIndex, isFirstEdit = false) {
|
|
|
1705
2783
|
});
|
|
1706
2784
|
}
|
|
1707
2785
|
|
|
2786
|
+
class ImageComponent extends CommonPluginElement {
|
|
2787
|
+
get activeGenerator() {
|
|
2788
|
+
return this.imageGenerator.componentRef.instance.activeGenerator;
|
|
2789
|
+
}
|
|
2790
|
+
constructor(viewContainerRef, cdr) {
|
|
2791
|
+
super(cdr);
|
|
2792
|
+
this.viewContainerRef = viewContainerRef;
|
|
2793
|
+
this.cdr = cdr;
|
|
2794
|
+
this.destroy$ = new Subject();
|
|
2795
|
+
}
|
|
2796
|
+
initializeGenerator() {
|
|
2797
|
+
this.imageGenerator = new ImageGenerator(this.board, {
|
|
2798
|
+
getRectangle: (element) => {
|
|
2799
|
+
return {
|
|
2800
|
+
x: element.points[0][0],
|
|
2801
|
+
y: element.points[0][1],
|
|
2802
|
+
width: element.points[1][0] - element.points[0][0],
|
|
2803
|
+
height: element.points[1][1] - element.points[0][1]
|
|
2804
|
+
};
|
|
2805
|
+
},
|
|
2806
|
+
getImageItem: element => {
|
|
2807
|
+
return {
|
|
2808
|
+
url: element.url,
|
|
2809
|
+
width: element.points[1][0] - element.points[0][0],
|
|
2810
|
+
height: element.points[1][1] - element.points[0][1]
|
|
2811
|
+
};
|
|
2812
|
+
}
|
|
2813
|
+
});
|
|
2814
|
+
}
|
|
2815
|
+
ngOnInit() {
|
|
2816
|
+
super.ngOnInit();
|
|
2817
|
+
this.initializeGenerator();
|
|
2818
|
+
this.imageGenerator.draw(this.element, this.g, this.viewContainerRef);
|
|
2819
|
+
}
|
|
2820
|
+
onContextChanged(value, previous) {
|
|
2821
|
+
if (value.element !== previous.element) {
|
|
2822
|
+
this.imageGenerator.updateImage(this.g, previous.element, value.element);
|
|
2823
|
+
this.imageGenerator.componentRef.instance.isFocus = this.selected;
|
|
2824
|
+
}
|
|
2825
|
+
else {
|
|
2826
|
+
const hasSameSelected = value.selected === previous.selected;
|
|
2827
|
+
const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
|
|
2828
|
+
if (!hasSameSelected || !hasSameHandleState) {
|
|
2829
|
+
this.imageGenerator.componentRef.instance.isFocus = this.selected;
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
ngOnDestroy() {
|
|
2834
|
+
super.ngOnDestroy();
|
|
2835
|
+
this.destroy$.next();
|
|
2836
|
+
this.destroy$.complete();
|
|
2837
|
+
this.imageGenerator.destroy();
|
|
2838
|
+
}
|
|
2839
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: ImageComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2840
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: ImageComponent, isStandalone: true, selector: "plait-draw-geometry", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2841
|
+
}
|
|
2842
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: ImageComponent, decorators: [{
|
|
2843
|
+
type: Component,
|
|
2844
|
+
args: [{
|
|
2845
|
+
selector: 'plait-draw-geometry',
|
|
2846
|
+
template: ``,
|
|
2847
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2848
|
+
standalone: true
|
|
2849
|
+
}]
|
|
2850
|
+
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
|
|
2851
|
+
|
|
1708
2852
|
const withDraw = (board) => {
|
|
1709
|
-
const { drawElement, getRectangle, isHitSelection, isMovable,
|
|
2853
|
+
const { drawElement, getRectangle, isHitSelection, isMovable, isAlign } = board;
|
|
1710
2854
|
board.drawElement = (context) => {
|
|
1711
2855
|
if (PlaitDrawElement.isGeometry(context.element)) {
|
|
1712
2856
|
return GeometryComponent;
|
|
@@ -1714,6 +2858,9 @@ const withDraw = (board) => {
|
|
|
1714
2858
|
else if (PlaitDrawElement.isLine(context.element)) {
|
|
1715
2859
|
return LineComponent;
|
|
1716
2860
|
}
|
|
2861
|
+
else if (PlaitDrawElement.isImage(context.element)) {
|
|
2862
|
+
return ImageComponent;
|
|
2863
|
+
}
|
|
1717
2864
|
return drawElement(context);
|
|
1718
2865
|
};
|
|
1719
2866
|
board.getRectangle = (element) => {
|
|
@@ -1721,9 +2868,11 @@ const withDraw = (board) => {
|
|
|
1721
2868
|
return getRectangleByPoints(element.points);
|
|
1722
2869
|
}
|
|
1723
2870
|
if (PlaitDrawElement.isLine(element)) {
|
|
1724
|
-
const
|
|
1725
|
-
|
|
1726
|
-
|
|
2871
|
+
const points = getLinePoints(board, element);
|
|
2872
|
+
return getRectangleByPoints(points);
|
|
2873
|
+
}
|
|
2874
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2875
|
+
return getRectangleByPoints(element.points);
|
|
1727
2876
|
}
|
|
1728
2877
|
return getRectangle(element);
|
|
1729
2878
|
};
|
|
@@ -1737,6 +2886,11 @@ const withDraw = (board) => {
|
|
|
1737
2886
|
}
|
|
1738
2887
|
return RectangleClient.isHit(rangeRectangle, client);
|
|
1739
2888
|
}
|
|
2889
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2890
|
+
const client = getRectangleByPoints(element.points);
|
|
2891
|
+
const rangeRectangle = RectangleClient.toRectangleClient([range.anchor, range.focus]);
|
|
2892
|
+
return RectangleClient.isHit(rangeRectangle, client);
|
|
2893
|
+
}
|
|
1740
2894
|
if (PlaitDrawElement.isLine(element)) {
|
|
1741
2895
|
const points = getLinePoints(board, element);
|
|
1742
2896
|
const strokeWidth = getStrokeWidthByElement(element);
|
|
@@ -1755,17 +2909,34 @@ const withDraw = (board) => {
|
|
|
1755
2909
|
if (PlaitDrawElement.isGeometry(element)) {
|
|
1756
2910
|
return true;
|
|
1757
2911
|
}
|
|
2912
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2913
|
+
return true;
|
|
2914
|
+
}
|
|
1758
2915
|
if (PlaitDrawElement.isLine(element)) {
|
|
1759
|
-
|
|
2916
|
+
const selectedElements = getSelectedElements(board);
|
|
2917
|
+
const isSelected = (boundId) => {
|
|
2918
|
+
return !!selectedElements.find(value => value.id === boundId);
|
|
2919
|
+
};
|
|
2920
|
+
if ((element.source.boundId && !isSelected(element.source.boundId)) ||
|
|
2921
|
+
(element.target.boundId && !isSelected(element.target.boundId))) {
|
|
2922
|
+
return false;
|
|
2923
|
+
}
|
|
2924
|
+
return true;
|
|
1760
2925
|
}
|
|
1761
2926
|
return isMovable(element);
|
|
1762
2927
|
};
|
|
1763
|
-
|
|
2928
|
+
board.isAlign = (element) => {
|
|
2929
|
+
if (PlaitDrawElement.isGeometry(element) || PlaitDrawElement.isImage(element)) {
|
|
2930
|
+
return true;
|
|
2931
|
+
}
|
|
2932
|
+
return isAlign(element);
|
|
2933
|
+
};
|
|
2934
|
+
return withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))));
|
|
1764
2935
|
};
|
|
1765
2936
|
|
|
1766
2937
|
/**
|
|
1767
2938
|
* Generated bundle index. Do not edit.
|
|
1768
2939
|
*/
|
|
1769
2940
|
|
|
1770
|
-
export { DefaultGeometryActiveStyle, DefaultGeometryProperty, DefaultGeometryStyle, DefaultTextProperty,
|
|
2941
|
+
export { DEFAULT_IMAGE_WIDTH, DefaultGeometryActiveStyle, DefaultGeometryProperty, DefaultGeometryStyle, DefaultTextProperty, DrawTransforms, GeometryComponent, GeometryShape, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, ShapeDefaultSpace, StrokeStyle, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getEdgeOnPolygonByPoint, getElbowPoints, getExtendPoint, getFillByElement, getGeometryPointers, getHitConnectorPoint, getHitLineTextIndex, getLineDashByElement, getLineHandleRefPair, getLinePointers, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getVectorByConnection, isHitLineText, isHitPolyLine, removeDuplicatePoints, transformOpsToPoints, transformPointToConnection, withDraw };
|
|
1771
2942
|
//# sourceMappingURL=plait-draw.mjs.map
|