@plait/draw 0.1.0-next.11 → 0.1.0-next.13
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 +49 -16
- package/esm2022/generators/line.generator.mjs +2 -11
- package/esm2022/geometry.component.mjs +13 -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 +4 -3
- package/esm2022/plugins/with-draw-fragment.mjs +20 -2
- package/esm2022/plugins/with-draw.mjs +25 -4
- package/esm2022/plugins/with-geometry-create.mjs +15 -12
- package/esm2022/plugins/with-geometry-resize.mjs +17 -11
- 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 +3 -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 +197 -47
- 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/fesm2022/plait-draw.mjs +1367 -253
- package/fesm2022/plait-draw.mjs.map +1 -1
- package/generators/line-active.generator.d.ts +2 -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 +1 -1
- package/package.json +3 -2
- package/plugins/with-geometry-create.d.ts +1 -1
- package/styles/styles.scss +1 -1
- 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, PRIMARY_COLOR, 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,27 +69,17 @@ 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) => {
|
|
153
85
|
if (PlaitDrawElement.isText(element)) {
|
|
@@ -171,6 +103,102 @@ const getStrokeStyleByElement = (element) => {
|
|
|
171
103
|
return element.strokeStyle || StrokeStyle.solid;
|
|
172
104
|
};
|
|
173
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
|
+
|
|
174
202
|
const DiamondEngine = {
|
|
175
203
|
draw(board, rectangle, options) {
|
|
176
204
|
const points = RectangleClient.getEdgeCenterPoints(rectangle);
|
|
@@ -183,9 +211,16 @@ const DiamondEngine = {
|
|
|
183
211
|
const controlPoints = RectangleClient.getEdgeCenterPoints(rectangle);
|
|
184
212
|
return isPointInPolygon(point, controlPoints);
|
|
185
213
|
},
|
|
214
|
+
getCornerPoints(rectangle) {
|
|
215
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
216
|
+
},
|
|
186
217
|
getNearestPoint(rectangle, point) {
|
|
187
|
-
|
|
188
|
-
|
|
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);
|
|
189
224
|
},
|
|
190
225
|
getConnectorPoints(rectangle) {
|
|
191
226
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
@@ -202,10 +237,22 @@ const EllipseEngine = {
|
|
|
202
237
|
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
203
238
|
return isPointInEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
|
|
204
239
|
},
|
|
240
|
+
getCornerPoints(rectangle) {
|
|
241
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
242
|
+
},
|
|
205
243
|
getNearestPoint(rectangle, point) {
|
|
206
244
|
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
207
245
|
return getNearestPointBetweenPointAndEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
|
|
208
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
|
+
},
|
|
209
256
|
getConnectorPoints(rectangle) {
|
|
210
257
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
211
258
|
}
|
|
@@ -245,29 +292,182 @@ function getNearestPointBetweenPointAndEllipse(point, center, rx, ry, rotation =
|
|
|
245
292
|
const signY = point[1] > center[1] ? 1 : -1;
|
|
246
293
|
return [center[0] + a * tx * signX, center[1] + b * ty * signY];
|
|
247
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
|
+
}
|
|
248
320
|
|
|
249
|
-
const
|
|
321
|
+
const HexagonEngine = {
|
|
250
322
|
draw(board, rectangle, options) {
|
|
251
|
-
const points =
|
|
323
|
+
const points = getHexagonPoints(rectangle);
|
|
252
324
|
const rs = PlaitBoard.getRoughSVG(board);
|
|
253
325
|
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
254
326
|
setStrokeLinecap(polygon, 'round');
|
|
255
327
|
return polygon;
|
|
256
328
|
},
|
|
257
329
|
isHit(rectangle, point) {
|
|
258
|
-
const parallelogramPoints =
|
|
330
|
+
const parallelogramPoints = getHexagonPoints(rectangle);
|
|
259
331
|
return isPointInPolygon(point, parallelogramPoints);
|
|
260
332
|
},
|
|
333
|
+
getCornerPoints(rectangle) {
|
|
334
|
+
return getHexagonPoints(rectangle);
|
|
335
|
+
},
|
|
261
336
|
getNearestPoint(rectangle, point) {
|
|
262
|
-
|
|
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);
|
|
263
376
|
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
264
377
|
},
|
|
378
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
379
|
+
const corners = getLeftArrowPoints(rectangle);
|
|
380
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
381
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
382
|
+
},
|
|
265
383
|
getConnectorPoints(rectangle) {
|
|
266
|
-
|
|
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);
|
|
267
467
|
return getCenterPointsOnPolygon(cornerPoints);
|
|
268
468
|
}
|
|
269
469
|
};
|
|
270
|
-
const
|
|
470
|
+
const getParallelogramCornerPoints = (rectangle) => {
|
|
271
471
|
return [
|
|
272
472
|
[rectangle.x + rectangle.width / 4, rectangle.y],
|
|
273
473
|
[rectangle.x + rectangle.width, rectangle.y],
|
|
@@ -276,6 +476,119 @@ const getParallelogramPoints = (rectangle) => {
|
|
|
276
476
|
];
|
|
277
477
|
};
|
|
278
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
|
+
|
|
279
592
|
const RectangleEngine = {
|
|
280
593
|
draw(board, rectangle, options) {
|
|
281
594
|
return drawRectangle(board, rectangle, { ...options, fillStyle: 'solid' });
|
|
@@ -284,15 +597,65 @@ const RectangleEngine = {
|
|
|
284
597
|
const rangeRectangle = RectangleClient.toRectangleClient([point, point]);
|
|
285
598
|
return RectangleClient.isHit(rectangle, rangeRectangle);
|
|
286
599
|
},
|
|
600
|
+
getCornerPoints(rectangle) {
|
|
601
|
+
return RectangleClient.getCornerPoints(rectangle);
|
|
602
|
+
},
|
|
287
603
|
getNearestPoint(rectangle, point) {
|
|
288
|
-
|
|
289
|
-
|
|
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);
|
|
290
610
|
},
|
|
291
611
|
getConnectorPoints(rectangle) {
|
|
292
612
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
293
613
|
}
|
|
294
614
|
};
|
|
295
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
|
+
|
|
296
659
|
const RoundRectangleEngine = {
|
|
297
660
|
draw(board, rectangle, options) {
|
|
298
661
|
return drawRoundRectangle(PlaitBoard.getRoughSVG(board), rectangle.x, rectangle.y, rectangle.x + rectangle.width, rectangle.y + rectangle.height, { ...options, fillStyle: 'solid' }, false, getRoundRectangleRadius(rectangle));
|
|
@@ -300,9 +663,17 @@ const RoundRectangleEngine = {
|
|
|
300
663
|
isHit(rectangle, point) {
|
|
301
664
|
return isPointInRoundRectangle(point, rectangle, getRoundRectangleRadius(rectangle));
|
|
302
665
|
},
|
|
666
|
+
getCornerPoints(rectangle) {
|
|
667
|
+
return RectangleClient.getCornerPoints(rectangle);
|
|
668
|
+
},
|
|
303
669
|
getNearestPoint(rectangle, point) {
|
|
304
670
|
return getNearestPointBetweenPointAndRoundRectangle(point, rectangle, getRoundRectangleRadius(rectangle));
|
|
305
671
|
},
|
|
672
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
673
|
+
const corners = RectangleEngine.getCornerPoints(rectangle);
|
|
674
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
675
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
676
|
+
},
|
|
306
677
|
getConnectorPoints(rectangle) {
|
|
307
678
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
308
679
|
}
|
|
@@ -337,8 +708,248 @@ function getNearestPointBetweenPointAndRoundRectangle(point, rectangle, radius)
|
|
|
337
708
|
if (circleCenter) {
|
|
338
709
|
result = getNearestPointBetweenPointAndEllipse(point, circleCenter, radius, radius);
|
|
339
710
|
}
|
|
340
|
-
return result;
|
|
341
|
-
}
|
|
711
|
+
return result;
|
|
712
|
+
}
|
|
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
|
+
};
|
|
342
953
|
|
|
343
954
|
const ShapeEngineMap = {
|
|
344
955
|
[GeometryShape.rectangle]: RectangleEngine,
|
|
@@ -346,12 +957,33 @@ const ShapeEngineMap = {
|
|
|
346
957
|
[GeometryShape.ellipse]: EllipseEngine,
|
|
347
958
|
[GeometryShape.parallelogram]: ParallelogramEngine,
|
|
348
959
|
[GeometryShape.roundRectangle]: RoundRectangleEngine,
|
|
349
|
-
[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
|
|
350
975
|
};
|
|
351
976
|
const getEngine = (shape) => {
|
|
352
977
|
return ShapeEngineMap[shape];
|
|
353
978
|
};
|
|
354
979
|
|
|
980
|
+
const getShape = (value) => {
|
|
981
|
+
if (PlaitDrawElement.isImage(value)) {
|
|
982
|
+
return GeometryShape.rectangle;
|
|
983
|
+
}
|
|
984
|
+
return value.shape;
|
|
985
|
+
};
|
|
986
|
+
|
|
355
987
|
const createGeometryElement = (shape, points, text, options) => {
|
|
356
988
|
let textOptions = {};
|
|
357
989
|
let alignment = Alignment.center;
|
|
@@ -393,14 +1025,15 @@ const drawBoundMask = (board, element) => {
|
|
|
393
1025
|
const G = createG();
|
|
394
1026
|
const rectangle = getRectangleByPoints(element.points);
|
|
395
1027
|
const activeRectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
|
|
396
|
-
const
|
|
1028
|
+
const shape = getShape(element);
|
|
1029
|
+
const maskG = drawGeometry(board, activeRectangle, shape, {
|
|
397
1030
|
stroke: SELECTION_BORDER_COLOR,
|
|
398
1031
|
strokeWidth: 1,
|
|
399
1032
|
fill: SELECTION_FILL_COLOR,
|
|
400
1033
|
fillStyle: 'solid'
|
|
401
1034
|
});
|
|
402
1035
|
G.appendChild(maskG);
|
|
403
|
-
const connectorPoints = getEngine(
|
|
1036
|
+
const connectorPoints = getEngine(shape).getConnectorPoints(activeRectangle);
|
|
404
1037
|
connectorPoints.forEach(point => {
|
|
405
1038
|
const circleG = drawCircle(PlaitBoard.getRoughSVG(board), point, 6, {
|
|
406
1039
|
stroke: '#999999',
|
|
@@ -418,7 +1051,8 @@ const drawGeometry = (board, outerRectangle, shape, options) => {
|
|
|
418
1051
|
const getNearestPoint = (element, point, inflateDelta = 0) => {
|
|
419
1052
|
const rectangle = getRectangleByPoints(element.points);
|
|
420
1053
|
const activeRectangle = RectangleClient.inflate(rectangle, inflateDelta);
|
|
421
|
-
|
|
1054
|
+
const shape = getShape(element);
|
|
1055
|
+
return getEngine(shape).getNearestPoint(activeRectangle, point);
|
|
422
1056
|
};
|
|
423
1057
|
const getCenterPointsOnPolygon = (points) => {
|
|
424
1058
|
const centerPoint = [];
|
|
@@ -428,6 +1062,17 @@ const getCenterPointsOnPolygon = (points) => {
|
|
|
428
1062
|
}
|
|
429
1063
|
return centerPoint;
|
|
430
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
|
+
};
|
|
431
1076
|
|
|
432
1077
|
const drawLineArrow = (element, points, options) => {
|
|
433
1078
|
const arrowG = createG();
|
|
@@ -435,16 +1080,19 @@ const drawLineArrow = (element, points, options) => {
|
|
|
435
1080
|
return null;
|
|
436
1081
|
}
|
|
437
1082
|
if (!PlaitLine.isSourceMark(element, LineMarkerType.none)) {
|
|
438
|
-
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);
|
|
439
1085
|
sourceArrow && arrowG.appendChild(sourceArrow);
|
|
440
1086
|
}
|
|
441
1087
|
if (!PlaitLine.isTargetMark(element, LineMarkerType.none)) {
|
|
442
|
-
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);
|
|
443
1090
|
arrow && arrowG.appendChild(arrow);
|
|
444
1091
|
}
|
|
445
1092
|
return arrowG;
|
|
446
1093
|
};
|
|
447
|
-
const getArrow = (element,
|
|
1094
|
+
const getArrow = (element, arrowOptions, options) => {
|
|
1095
|
+
const { marker, source, target, isSource } = arrowOptions;
|
|
448
1096
|
let targetArrow;
|
|
449
1097
|
switch (marker) {
|
|
450
1098
|
case LineMarkerType.openTriangle: {
|
|
@@ -463,16 +1111,27 @@ const getArrow = (element, marker, source, target, options) => {
|
|
|
463
1111
|
targetArrow = drawSharpArrow(source, target, options);
|
|
464
1112
|
break;
|
|
465
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
|
+
}
|
|
466
1130
|
}
|
|
467
1131
|
return targetArrow;
|
|
468
1132
|
};
|
|
469
1133
|
const drawSharpArrow = (source, target, options) => {
|
|
470
|
-
const directionFactor = getFactorByPoints(source, target);
|
|
471
1134
|
const startPoint = target;
|
|
472
|
-
// const startPoint: Point = [
|
|
473
|
-
// target[0],
|
|
474
|
-
// target[1]
|
|
475
|
-
// ];
|
|
476
1135
|
const { pointLeft, pointRight } = arrowPoints(source, target, 12, 20);
|
|
477
1136
|
const g = createG();
|
|
478
1137
|
const path = createPath();
|
|
@@ -487,10 +1146,7 @@ const drawSharpArrow = (source, target, options) => {
|
|
|
487
1146
|
const drawArrow = (element, source, target, options) => {
|
|
488
1147
|
const directionFactor = getFactorByPoints(source, target);
|
|
489
1148
|
const strokeWidth = getStrokeWidthByElement(element);
|
|
490
|
-
const endPoint = [
|
|
491
|
-
target[0] + strokeWidth * directionFactor.x / 2,
|
|
492
|
-
target[1] + strokeWidth * directionFactor.y / 2
|
|
493
|
-
];
|
|
1149
|
+
const endPoint = [target[0] + (strokeWidth * directionFactor.x) / 2, target[1] + (strokeWidth * directionFactor.y) / 2];
|
|
494
1150
|
const middlePoint = [endPoint[0] - 8 * directionFactor.x, endPoint[1] - 8 * directionFactor.y];
|
|
495
1151
|
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 30);
|
|
496
1152
|
const arrowG = drawLinearPath([pointLeft, endPoint, pointRight, middlePoint], { ...options, fill: options.stroke }, true);
|
|
@@ -506,13 +1162,26 @@ const drawSolidTriangle = (source, target, options) => {
|
|
|
506
1162
|
const drawOpenTriangle = (element, source, target, options) => {
|
|
507
1163
|
const directionFactor = getFactorByPoints(source, target);
|
|
508
1164
|
const strokeWidth = getStrokeWidthByElement(element);
|
|
509
|
-
const endPoint = [
|
|
510
|
-
target[0] + strokeWidth * directionFactor.x / 2,
|
|
511
|
-
target[1] + strokeWidth * directionFactor.y / 2
|
|
512
|
-
];
|
|
1165
|
+
const endPoint = [target[0] + (strokeWidth * directionFactor.x) / 2, target[1] + (strokeWidth * directionFactor.y) / 2];
|
|
513
1166
|
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 40);
|
|
514
1167
|
return drawLinearPath([pointLeft, endPoint, pointRight], options);
|
|
515
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
|
+
};
|
|
516
1185
|
|
|
517
1186
|
const createLineElement = (shape, points, source, target, options) => {
|
|
518
1187
|
return {
|
|
@@ -528,28 +1197,127 @@ const createLineElement = (shape, points, source, target, options) => {
|
|
|
528
1197
|
};
|
|
529
1198
|
};
|
|
530
1199
|
const getLinePoints = (board, element) => {
|
|
531
|
-
|
|
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
|
+
}
|
|
532
1211
|
};
|
|
533
|
-
const
|
|
534
|
-
|
|
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 };
|
|
535
1259
|
};
|
|
536
1260
|
const getElbowPoints = (board, element) => {
|
|
537
1261
|
if (element.points.length === 2) {
|
|
538
|
-
const
|
|
539
|
-
const
|
|
540
|
-
let
|
|
541
|
-
|
|
542
|
-
if (element.source.connection) {
|
|
543
|
-
sourceDirection = getDirectionByPoint(element.source.connection, sourceDirection);
|
|
544
|
-
}
|
|
545
|
-
if (element.target.connection) {
|
|
546
|
-
targetDirection = getDirectionByPoint(element.target.connection, targetDirection);
|
|
547
|
-
}
|
|
548
|
-
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);
|
|
549
1266
|
return points;
|
|
550
1267
|
}
|
|
551
1268
|
return element.points;
|
|
552
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
|
+
};
|
|
553
1321
|
const isHitPolyLine = (pathPoints, point, strokeWidth, expand = 0) => {
|
|
554
1322
|
const distance = distanceBetweenPointAndSegments(pathPoints, point);
|
|
555
1323
|
return distance <= strokeWidth + expand;
|
|
@@ -579,8 +1347,15 @@ const drawLine = (board, element) => {
|
|
|
579
1347
|
const strokeLineDash = getLineDashByElement(element);
|
|
580
1348
|
const options = { stroke: strokeColor, strokeWidth, strokeLineDash };
|
|
581
1349
|
const lineG = createG();
|
|
582
|
-
|
|
583
|
-
|
|
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
|
+
}
|
|
584
1359
|
const id = idCreator();
|
|
585
1360
|
line.setAttribute('mask', `url(#${id})`);
|
|
586
1361
|
lineG.appendChild(line);
|
|
@@ -614,33 +1389,16 @@ function drawMask(board, element, id) {
|
|
|
614
1389
|
maskTargetFillRect.setAttribute('opacity', '0');
|
|
615
1390
|
return { mask, maskTargetFillRect };
|
|
616
1391
|
}
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
const
|
|
621
|
-
const
|
|
622
|
-
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];
|
|
623
1398
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
const getTargetPoint = (board, element) => {
|
|
627
|
-
if (element.target.boundId) {
|
|
628
|
-
const strokeWidth = getStrokeWidthByElement(element);
|
|
629
|
-
const connectionOffset = PlaitLine.isTargetMark(element, LineMarkerType.none) ? 0 : strokeWidth;
|
|
630
|
-
const boundElement = getElementById(board, element.target.boundId);
|
|
631
|
-
return boundElement
|
|
632
|
-
? getConnectionPoint(boundElement, element.target.connection, connectionOffset)
|
|
633
|
-
: element.points[element.points.length - 1];
|
|
1399
|
+
else {
|
|
1400
|
+
return RectangleClient.getConnectionPoint(rectangle, connection);
|
|
634
1401
|
}
|
|
635
|
-
return element.points[element.points.length - 1];
|
|
636
|
-
};
|
|
637
|
-
const getConnectionPoint = (geometry, connection, offset) => {
|
|
638
|
-
const rectangle = getRectangleByPoints(geometry.points);
|
|
639
|
-
const directionFactor = getDirectionFactor(getDirectionByPoint(connection, Direction.bottom));
|
|
640
|
-
return [
|
|
641
|
-
rectangle.x + rectangle.width * connection[0] + directionFactor.x * offset,
|
|
642
|
-
rectangle.y + rectangle.height * connection[1] + directionFactor.y * offset
|
|
643
|
-
];
|
|
644
1402
|
};
|
|
645
1403
|
const transformPointToConnection = (board, point, hitElement) => {
|
|
646
1404
|
let rectangle = getRectangleByPoints(hitElement.points);
|
|
@@ -651,7 +1409,8 @@ const transformPointToConnection = (board, point, hitElement) => {
|
|
|
651
1409
|
return [(nearestPoint[0] - rectangle.x) / rectangle.width, (nearestPoint[1] - rectangle.y) / rectangle.height];
|
|
652
1410
|
};
|
|
653
1411
|
const getHitConnectorPoint = (movingPoint, hitElement, rectangle) => {
|
|
654
|
-
const
|
|
1412
|
+
const shape = getShape(hitElement);
|
|
1413
|
+
const connector = getEngine(shape).getConnectorPoints(rectangle);
|
|
655
1414
|
const points = getPointsByCenterPoint(movingPoint, 5, 5);
|
|
656
1415
|
const pointRectangle = getRectangleByPoints(points);
|
|
657
1416
|
return connector.find(point => {
|
|
@@ -675,6 +1434,64 @@ const getBoardLines = (board) => {
|
|
|
675
1434
|
recursion: (element) => PlaitDrawElement.isDrawElement(element)
|
|
676
1435
|
});
|
|
677
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
|
+
};
|
|
678
1495
|
|
|
679
1496
|
const getSelectedDrawElements = (board) => {
|
|
680
1497
|
const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isDrawElement(value));
|
|
@@ -688,6 +1505,111 @@ const getSelectedLineElements = (board) => {
|
|
|
688
1505
|
const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isLine(value));
|
|
689
1506
|
return selectedElements;
|
|
690
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
|
+
};
|
|
691
1613
|
|
|
692
1614
|
class GeometryShapeGenerator extends Generator {
|
|
693
1615
|
canDraw(element, data) {
|
|
@@ -703,7 +1625,12 @@ class GeometryShapeGenerator extends Generator {
|
|
|
703
1625
|
const strokeColor = getStrokeColorByElement(element);
|
|
704
1626
|
const fill = getFillByElement(element);
|
|
705
1627
|
const strokeLineDash = getLineDashByElement(element);
|
|
706
|
-
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
|
+
});
|
|
707
1634
|
}
|
|
708
1635
|
}
|
|
709
1636
|
|
|
@@ -783,6 +1710,28 @@ const setTextSize = (board, element, textWidth, textHeight) => {
|
|
|
783
1710
|
}
|
|
784
1711
|
};
|
|
785
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
|
+
|
|
786
1735
|
const resizeLine = (board, options, path) => {
|
|
787
1736
|
Transforms.setNode(board, options, path);
|
|
788
1737
|
};
|
|
@@ -813,7 +1762,8 @@ const DrawTransforms = {
|
|
|
813
1762
|
resizeLine,
|
|
814
1763
|
setLineTexts,
|
|
815
1764
|
removeLineText,
|
|
816
|
-
setLineMark
|
|
1765
|
+
setLineMark,
|
|
1766
|
+
insertImage
|
|
817
1767
|
};
|
|
818
1768
|
|
|
819
1769
|
class GeometryComponent extends CommonPluginElement {
|
|
@@ -831,10 +1781,10 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
831
1781
|
getStrokeWidth: () => {
|
|
832
1782
|
const selectedElements = getSelectedElements(this.board);
|
|
833
1783
|
if (selectedElements.length === 1 && !isSelectionMoving(this.board)) {
|
|
834
|
-
return
|
|
1784
|
+
return ACTIVE_STROKE_WIDTH;
|
|
835
1785
|
}
|
|
836
1786
|
else {
|
|
837
|
-
return
|
|
1787
|
+
return ACTIVE_STROKE_WIDTH;
|
|
838
1788
|
}
|
|
839
1789
|
},
|
|
840
1790
|
getStrokeOpacity: () => {
|
|
@@ -897,6 +1847,10 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
897
1847
|
const plugins = this.board.getPluginOptions(WithTextPluginKey).textPlugins;
|
|
898
1848
|
const manage = new TextManage(this.board, this.viewContainerRef, {
|
|
899
1849
|
getRectangle: () => {
|
|
1850
|
+
const getRectangle = getEngine(this.element.shape).getTextRectangle;
|
|
1851
|
+
if (getRectangle) {
|
|
1852
|
+
return getRectangle(this.element);
|
|
1853
|
+
}
|
|
900
1854
|
return getTextRectangle(this.element);
|
|
901
1855
|
},
|
|
902
1856
|
onValueChangeHandle: (textManageRef) => {
|
|
@@ -924,14 +1878,15 @@ class GeometryComponent extends CommonPluginElement {
|
|
|
924
1878
|
this.destroy$.complete();
|
|
925
1879
|
}
|
|
926
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 }); }
|
|
927
|
-
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 }); }
|
|
928
1882
|
}
|
|
929
1883
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: GeometryComponent, decorators: [{
|
|
930
1884
|
type: Component,
|
|
931
1885
|
args: [{
|
|
932
1886
|
selector: 'plait-draw-geometry',
|
|
933
1887
|
template: ``,
|
|
934
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
1888
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1889
|
+
standalone: true
|
|
935
1890
|
}]
|
|
936
1891
|
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
|
|
937
1892
|
|
|
@@ -940,16 +1895,8 @@ class LineShapeGenerator extends Generator {
|
|
|
940
1895
|
return true;
|
|
941
1896
|
}
|
|
942
1897
|
baseDraw(element, data) {
|
|
943
|
-
const shape = element.shape;
|
|
944
1898
|
let lineG;
|
|
945
|
-
|
|
946
|
-
case LineShape.elbow:
|
|
947
|
-
case LineShape.straight:
|
|
948
|
-
lineG = drawLine(this.board, element);
|
|
949
|
-
break;
|
|
950
|
-
default:
|
|
951
|
-
break;
|
|
952
|
-
}
|
|
1899
|
+
lineG = drawLine(this.board, element);
|
|
953
1900
|
return lineG;
|
|
954
1901
|
}
|
|
955
1902
|
}
|
|
@@ -972,22 +1919,25 @@ class LineActiveGenerator extends Generator {
|
|
|
972
1919
|
if (this.hasResizeHandle) {
|
|
973
1920
|
activeG.classList.add('active');
|
|
974
1921
|
activeG.classList.add('line-handle');
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
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);
|
|
982
1931
|
});
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
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);
|
|
988
1940
|
});
|
|
989
|
-
activeG.appendChild(targetCircle);
|
|
990
|
-
activeG.appendChild(sourceCircle);
|
|
991
1941
|
}
|
|
992
1942
|
else {
|
|
993
1943
|
const points = getLinePoints(this.board, element);
|
|
@@ -1001,6 +1951,35 @@ class LineActiveGenerator extends Generator {
|
|
|
1001
1951
|
return activeG;
|
|
1002
1952
|
}
|
|
1003
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
|
+
}
|
|
1004
1983
|
|
|
1005
1984
|
class LineComponent extends PlaitPluginElementComponent {
|
|
1006
1985
|
constructor(viewContainerRef, cdr) {
|
|
@@ -1140,14 +2119,15 @@ class LineComponent extends PlaitPluginElementComponent {
|
|
|
1140
2119
|
this.destroy$.complete();
|
|
1141
2120
|
}
|
|
1142
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 }); }
|
|
1143
|
-
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 }); }
|
|
1144
2123
|
}
|
|
1145
2124
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: LineComponent, decorators: [{
|
|
1146
2125
|
type: Component,
|
|
1147
2126
|
args: [{
|
|
1148
2127
|
selector: 'plait-draw-line',
|
|
1149
2128
|
template: ``,
|
|
1150
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
2129
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2130
|
+
standalone: true
|
|
1151
2131
|
}]
|
|
1152
2132
|
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
|
|
1153
2133
|
|
|
@@ -1187,13 +2167,14 @@ const withGeometryCreateByDrag = (board) => {
|
|
|
1187
2167
|
geometryShapeG?.remove();
|
|
1188
2168
|
geometryShapeG = createG();
|
|
1189
2169
|
const geometryGenerator = new GeometryShapeGenerator(board);
|
|
1190
|
-
const
|
|
2170
|
+
const geometryPointers = getGeometryPointers();
|
|
2171
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
1191
2172
|
const dragMode = isGeometryPointer && isDndMode(board);
|
|
1192
2173
|
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1193
2174
|
const pointer = PlaitBoard.getPointer(board);
|
|
1194
2175
|
if (dragMode) {
|
|
1195
2176
|
const points = getDefaultGeometryPoints(pointer, movingPoint);
|
|
1196
|
-
if (pointer ===
|
|
2177
|
+
if (pointer === GeometryShape.text) {
|
|
1197
2178
|
const textG = getTemporaryTextG(movingPoint);
|
|
1198
2179
|
geometryShapeG.appendChild(textG);
|
|
1199
2180
|
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
@@ -1211,12 +2192,13 @@ const withGeometryCreateByDrag = (board) => {
|
|
|
1211
2192
|
};
|
|
1212
2193
|
board.pointerUp = (event) => {
|
|
1213
2194
|
const pointer = PlaitBoard.getPointer(board);
|
|
1214
|
-
const
|
|
2195
|
+
const geometryPointers = getGeometryPointers();
|
|
2196
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
1215
2197
|
const dragMode = isGeometryPointer && isDndMode(board);
|
|
1216
2198
|
if (dragMode) {
|
|
1217
2199
|
const targetPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1218
2200
|
const points = getDefaultGeometryPoints(pointer, targetPoint);
|
|
1219
|
-
if (pointer ===
|
|
2201
|
+
if (pointer === GeometryShape.text) {
|
|
1220
2202
|
DrawTransforms.insertText(board, points);
|
|
1221
2203
|
}
|
|
1222
2204
|
else {
|
|
@@ -1231,7 +2213,7 @@ const withGeometryCreateByDrag = (board) => {
|
|
|
1231
2213
|
};
|
|
1232
2214
|
return board;
|
|
1233
2215
|
};
|
|
1234
|
-
const
|
|
2216
|
+
const withGeometryCreateByDrawing = (board) => {
|
|
1235
2217
|
const { pointerDown, pointerMove, pointerUp, keydown, keyup } = board;
|
|
1236
2218
|
let start = null;
|
|
1237
2219
|
let geometryShapeG = null;
|
|
@@ -1246,13 +2228,14 @@ const withGeometryCreateByDraw = (board) => {
|
|
|
1246
2228
|
keyup(event);
|
|
1247
2229
|
};
|
|
1248
2230
|
board.pointerDown = (event) => {
|
|
1249
|
-
const
|
|
2231
|
+
const geometryPointers = getGeometryPointers();
|
|
2232
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
1250
2233
|
if (isGeometryPointer && isDrawingMode(board)) {
|
|
1251
2234
|
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1252
2235
|
start = point;
|
|
1253
2236
|
const pointer = PlaitBoard.getPointer(board);
|
|
1254
2237
|
preventTouchMove(board, event, true);
|
|
1255
|
-
if (pointer ===
|
|
2238
|
+
if (pointer === GeometryShape.text) {
|
|
1256
2239
|
const points = getDefaultGeometryPoints(pointer, point);
|
|
1257
2240
|
const textElement = createGeometryElement(GeometryShape.text, points, DefaultTextProperty.text);
|
|
1258
2241
|
Transforms.insertNode(board, textElement, [board.children.length]);
|
|
@@ -1271,7 +2254,7 @@ const withGeometryCreateByDraw = (board) => {
|
|
|
1271
2254
|
const drawMode = !!start;
|
|
1272
2255
|
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1273
2256
|
const pointer = PlaitBoard.getPointer(board);
|
|
1274
|
-
if (drawMode && pointer !==
|
|
2257
|
+
if (drawMode && pointer !== GeometryShape.text) {
|
|
1275
2258
|
const points = normalizeShapePoints([start, movingPoint], isShift);
|
|
1276
2259
|
temporaryElement = createGeometryElement(pointer, points, '', {
|
|
1277
2260
|
strokeColor: DefaultGeometryProperty.strokeColor,
|
|
@@ -1290,7 +2273,7 @@ const withGeometryCreateByDraw = (board) => {
|
|
|
1290
2273
|
if (Math.hypot(width, height) === 0) {
|
|
1291
2274
|
const pointer = PlaitBoard.getPointer(board);
|
|
1292
2275
|
const points = getDefaultGeometryPoints(pointer, targetPoint);
|
|
1293
|
-
if (pointer !==
|
|
2276
|
+
if (pointer !== GeometryShape.text) {
|
|
1294
2277
|
temporaryElement = createGeometryElement(pointer, points, '', {
|
|
1295
2278
|
strokeColor: DefaultGeometryProperty.strokeColor,
|
|
1296
2279
|
strokeWidth: DefaultGeometryProperty.strokeWidth
|
|
@@ -1314,7 +2297,7 @@ const withGeometryCreateByDraw = (board) => {
|
|
|
1314
2297
|
return board;
|
|
1315
2298
|
};
|
|
1316
2299
|
const getDefaultGeometryPoints = (pointer, targetPoint) => {
|
|
1317
|
-
return pointer ===
|
|
2300
|
+
return pointer === GeometryShape.text
|
|
1318
2301
|
? getPointsByCenterPoint(targetPoint, DefaultTextProperty.width, DefaultTextProperty.height)
|
|
1319
2302
|
: getPointsByCenterPoint(targetPoint, DefaultGeometryProperty.width, DefaultGeometryProperty.height);
|
|
1320
2303
|
};
|
|
@@ -1333,7 +2316,7 @@ const getTemporaryTextG = (movingPoint) => {
|
|
|
1333
2316
|
|
|
1334
2317
|
const buildClipboardData = (board, elements, startPoint) => {
|
|
1335
2318
|
return elements.map(element => {
|
|
1336
|
-
if (PlaitDrawElement.isGeometry(element)) {
|
|
2319
|
+
if (PlaitDrawElement.isGeometry(element) || PlaitDrawElement.isImage(element)) {
|
|
1337
2320
|
const points = element.points.map(point => [point[0] - startPoint[0], point[1] - startPoint[1]]);
|
|
1338
2321
|
return { ...element, points };
|
|
1339
2322
|
}
|
|
@@ -1356,7 +2339,7 @@ const buildClipboardData = (board, elements, startPoint) => {
|
|
|
1356
2339
|
};
|
|
1357
2340
|
const insertClipboardData = (board, elements, startPoint) => {
|
|
1358
2341
|
const lines = elements.filter(value => PlaitDrawElement.isLine(value));
|
|
1359
|
-
const geometries = elements.filter(value => PlaitDrawElement.isGeometry(value));
|
|
2342
|
+
const geometries = elements.filter(value => PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isImage(value));
|
|
1360
2343
|
geometries.forEach(element => {
|
|
1361
2344
|
const sourceLines = [];
|
|
1362
2345
|
const targetLines = [];
|
|
@@ -1391,8 +2374,14 @@ const withDrawFragment = (baseBoard) => {
|
|
|
1391
2374
|
if (drawElements.length) {
|
|
1392
2375
|
const geometryElements = drawElements.filter(value => PlaitDrawElement.isGeometry(value));
|
|
1393
2376
|
const lineElements = drawElements.filter(value => PlaitDrawElement.isLine(value));
|
|
2377
|
+
const imageElements = drawElements.filter(value => PlaitDrawElement.isImage(value));
|
|
1394
2378
|
const boundLineElements = getBoundedLineElements(board, geometryElements).filter(line => !lineElements.includes(line));
|
|
1395
|
-
data.push(...[
|
|
2379
|
+
data.push(...[
|
|
2380
|
+
...geometryElements,
|
|
2381
|
+
...lineElements,
|
|
2382
|
+
...imageElements,
|
|
2383
|
+
...boundLineElements.filter(line => !lineElements.includes(line))
|
|
2384
|
+
]);
|
|
1396
2385
|
}
|
|
1397
2386
|
return getDeletedFragment(data);
|
|
1398
2387
|
};
|
|
@@ -1428,6 +2417,16 @@ const withDrawFragment = (baseBoard) => {
|
|
|
1428
2417
|
return;
|
|
1429
2418
|
}
|
|
1430
2419
|
}
|
|
2420
|
+
if (data?.files.length) {
|
|
2421
|
+
const acceptImageArray = acceptImageTypes.map(type => 'image/' + type);
|
|
2422
|
+
if (acceptImageArray.includes(data?.files[0].type)) {
|
|
2423
|
+
const imageFile = data.files[0];
|
|
2424
|
+
buildImage(board, imageFile, DEFAULT_IMAGE_WIDTH, imageItem => {
|
|
2425
|
+
DrawTransforms.insertImage(board, imageItem, targetPoint);
|
|
2426
|
+
});
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
1431
2430
|
insertFragment(data, targetPoint);
|
|
1432
2431
|
};
|
|
1433
2432
|
return board;
|
|
@@ -1453,10 +2452,10 @@ const getHitGeometryResizeHandleRef = (board, element, point) => {
|
|
|
1453
2452
|
const getHitOutlineGeometry = (board, point, offset = 0) => {
|
|
1454
2453
|
let geometry = null;
|
|
1455
2454
|
depthFirstRecursion(board, node => {
|
|
1456
|
-
if (PlaitDrawElement.isGeometry(node)) {
|
|
1457
|
-
const shape = node.shape;
|
|
2455
|
+
if (PlaitDrawElement.isGeometry(node) || PlaitDrawElement.isImage(node)) {
|
|
1458
2456
|
let client = getRectangleByPoints(node.points);
|
|
1459
2457
|
client = RectangleClient.getOutlineRectangle(client, offset);
|
|
2458
|
+
const shape = getShape(node);
|
|
1460
2459
|
const isHit = getEngine(shape).isHit(client, point);
|
|
1461
2460
|
if (isHit) {
|
|
1462
2461
|
geometry = node;
|
|
@@ -1474,7 +2473,8 @@ const withLineCreateByDraw = (board) => {
|
|
|
1474
2473
|
let lineShapeG = null;
|
|
1475
2474
|
let temporaryElement = null;
|
|
1476
2475
|
board.pointerDown = (event) => {
|
|
1477
|
-
const
|
|
2476
|
+
const linePointers = getLinePointers();
|
|
2477
|
+
const isLinePointer = PlaitBoard.isInPointer(board, linePointers);
|
|
1478
2478
|
if (isLinePointer && isDrawingMode(board)) {
|
|
1479
2479
|
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1480
2480
|
start = point;
|
|
@@ -1496,7 +2496,8 @@ const withLineCreateByDraw = (board) => {
|
|
|
1496
2496
|
targetRef.connection = hitElement ? transformPointToConnection(board, movingPoint, hitElement) : undefined;
|
|
1497
2497
|
targetRef.boundId = hitElement ? hitElement.id : undefined;
|
|
1498
2498
|
const lineGenerator = new LineShapeGenerator(board);
|
|
1499
|
-
|
|
2499
|
+
const lineShape = PlaitBoard.getPointer(board);
|
|
2500
|
+
temporaryElement = createLineElement(lineShape, [start, movingPoint], { marker: LineMarkerType.none, connection: sourceRef.connection, boundId: sourceRef?.boundId }, { marker: LineMarkerType.arrow, connection: targetRef.connection, boundId: targetRef?.boundId }, {
|
|
1500
2501
|
strokeColor: DefaultLineStyle.strokeColor,
|
|
1501
2502
|
strokeWidth: DefaultLineStyle.strokeWidth
|
|
1502
2503
|
});
|
|
@@ -1541,12 +2542,12 @@ const withGeometryResize = (board) => {
|
|
|
1541
2542
|
return true;
|
|
1542
2543
|
},
|
|
1543
2544
|
detect: (point) => {
|
|
1544
|
-
const
|
|
1545
|
-
if (
|
|
2545
|
+
const selectedElements = [...getSelectedGeometryElements(board), ...getSelectedImageElements(board)];
|
|
2546
|
+
if (selectedElements.length !== 1 || getSelectedElements(board).length !== 1) {
|
|
1546
2547
|
return null;
|
|
1547
2548
|
}
|
|
1548
|
-
const target =
|
|
1549
|
-
const targetComponent = PlaitElement.getComponent(
|
|
2549
|
+
const target = selectedElements[0];
|
|
2550
|
+
const targetComponent = PlaitElement.getComponent(selectedElements[0]);
|
|
1550
2551
|
if (targetComponent.activeGenerator.hasResizeHandle) {
|
|
1551
2552
|
const handleRef = getHitGeometryResizeHandleRef(board, target, point);
|
|
1552
2553
|
if (handleRef) {
|
|
@@ -1575,15 +2576,20 @@ const withGeometryResize = (board) => {
|
|
|
1575
2576
|
if (resizeRef.handle === ResizeHandle.sw) {
|
|
1576
2577
|
points = [resizeState.endTransformPoint, [resizeRef.element.points[1][0], resizeRef.element.points[0][1]]];
|
|
1577
2578
|
}
|
|
1578
|
-
if (isShift) {
|
|
2579
|
+
if (isShift || PlaitDrawElement.isImage(resizeRef.element)) {
|
|
1579
2580
|
const rectangle = getRectangleByPoints(points);
|
|
1580
2581
|
const factor = points[0][1] > points[1][1] ? 1 : -1;
|
|
1581
2582
|
const height = rectangle.width * ratio * factor;
|
|
1582
2583
|
points = [[resizeState.endTransformPoint[0], points[1][1] + height], points[1]];
|
|
1583
2584
|
}
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
2585
|
+
if (PlaitDrawElement.isGeometry(resizeRef.element)) {
|
|
2586
|
+
const { height: textHeight } = PlaitGeometry.getTextManage(resizeRef.element).getSize();
|
|
2587
|
+
DrawTransforms.resizeGeometry(board, points, textHeight, resizeRef.path);
|
|
2588
|
+
}
|
|
2589
|
+
else {
|
|
2590
|
+
points = normalizeShapePoints(points);
|
|
2591
|
+
Transforms.setNode(board, { points }, resizeRef.path);
|
|
2592
|
+
}
|
|
1587
2593
|
}
|
|
1588
2594
|
};
|
|
1589
2595
|
withResize(board, options);
|
|
@@ -1594,34 +2600,44 @@ var LineResizeHandle;
|
|
|
1594
2600
|
(function (LineResizeHandle) {
|
|
1595
2601
|
LineResizeHandle["source"] = "source";
|
|
1596
2602
|
LineResizeHandle["target"] = "target";
|
|
2603
|
+
LineResizeHandle["addHandle"] = "addHandle";
|
|
1597
2604
|
})(LineResizeHandle || (LineResizeHandle = {}));
|
|
1598
2605
|
const getHitLineResizeHandleRef = (board, element, point) => {
|
|
1599
|
-
const
|
|
1600
|
-
const
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
y: targetPoint[1] - RESIZE_HANDLE_DIAMETER / 2,
|
|
1610
|
-
width: RESIZE_HANDLE_DIAMETER,
|
|
1611
|
-
height: RESIZE_HANDLE_DIAMETER
|
|
1612
|
-
};
|
|
1613
|
-
const isHitSourceRectangle = RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), sourceRectangle);
|
|
1614
|
-
const isHitTargetRectangle = RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), targetRectangle);
|
|
1615
|
-
if (isHitSourceRectangle) {
|
|
1616
|
-
return { rectangle: sourceRectangle, handle: LineResizeHandle.source };
|
|
2606
|
+
const points = PlaitLine.getPoints(board, element);
|
|
2607
|
+
const index = getHitPointIndex(points, point);
|
|
2608
|
+
if (index !== -1) {
|
|
2609
|
+
if (index === 0) {
|
|
2610
|
+
return { handle: LineResizeHandle.source, index };
|
|
2611
|
+
}
|
|
2612
|
+
if (index === points.length - 1) {
|
|
2613
|
+
return { handle: LineResizeHandle.target, index };
|
|
2614
|
+
}
|
|
2615
|
+
return { index };
|
|
1617
2616
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
2617
|
+
const middlePoints = getMiddlePoints(board, element);
|
|
2618
|
+
const middleIndex = getHitPointIndex(middlePoints, point);
|
|
2619
|
+
if (middleIndex !== -1) {
|
|
2620
|
+
return { handle: LineResizeHandle.addHandle, index: middleIndex };
|
|
1620
2621
|
}
|
|
1621
2622
|
return undefined;
|
|
1622
2623
|
};
|
|
2624
|
+
function getHitPointIndex(points, movingPoint) {
|
|
2625
|
+
const rectangles = points.map(point => {
|
|
2626
|
+
return {
|
|
2627
|
+
x: point[0] - RESIZE_HANDLE_DIAMETER / 2,
|
|
2628
|
+
y: point[1] - RESIZE_HANDLE_DIAMETER / 2,
|
|
2629
|
+
width: RESIZE_HANDLE_DIAMETER,
|
|
2630
|
+
height: RESIZE_HANDLE_DIAMETER
|
|
2631
|
+
};
|
|
2632
|
+
});
|
|
2633
|
+
const rectangle = rectangles.find(rectangle => {
|
|
2634
|
+
return RectangleClient.isHit(RectangleClient.toRectangleClient([movingPoint, movingPoint]), rectangle);
|
|
2635
|
+
});
|
|
2636
|
+
return rectangle ? rectangles.indexOf(rectangle) : -1;
|
|
2637
|
+
}
|
|
1623
2638
|
|
|
1624
2639
|
const withLineResize = (board) => {
|
|
2640
|
+
let pointIndex = 0;
|
|
1625
2641
|
const options = {
|
|
1626
2642
|
key: 'draw-line',
|
|
1627
2643
|
canResize: () => {
|
|
@@ -1638,6 +2654,7 @@ const withLineResize = (board) => {
|
|
|
1638
2654
|
element: value,
|
|
1639
2655
|
handle: handleRef.handle
|
|
1640
2656
|
};
|
|
2657
|
+
pointIndex = handleRef.index;
|
|
1641
2658
|
}
|
|
1642
2659
|
});
|
|
1643
2660
|
return result;
|
|
@@ -1649,17 +2666,23 @@ const withLineResize = (board) => {
|
|
|
1649
2666
|
let source = { ...resizeRef.element.source };
|
|
1650
2667
|
let target = { ...resizeRef.element.target };
|
|
1651
2668
|
if (resizeRef.handle === LineResizeHandle.source) {
|
|
1652
|
-
points[
|
|
2669
|
+
points[pointIndex] = resizeState.endTransformPoint;
|
|
1653
2670
|
const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, -4);
|
|
1654
2671
|
source.connection = hitElement ? transformPointToConnection(board, resizeState.endTransformPoint, hitElement) : undefined;
|
|
1655
2672
|
source.boundId = hitElement ? hitElement.id : undefined;
|
|
1656
2673
|
}
|
|
1657
|
-
if (resizeRef.handle === LineResizeHandle.target) {
|
|
1658
|
-
points[
|
|
2674
|
+
else if (resizeRef.handle === LineResizeHandle.target) {
|
|
2675
|
+
points[pointIndex] = resizeState.endTransformPoint;
|
|
1659
2676
|
const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, -4);
|
|
1660
2677
|
target.connection = hitElement ? transformPointToConnection(board, resizeState.endTransformPoint, hitElement) : undefined;
|
|
1661
2678
|
target.boundId = hitElement ? hitElement.id : undefined;
|
|
1662
2679
|
}
|
|
2680
|
+
else if (resizeRef.handle === LineResizeHandle.addHandle) {
|
|
2681
|
+
points.splice(pointIndex + 1, 0, resizeState.endTransformPoint);
|
|
2682
|
+
}
|
|
2683
|
+
else {
|
|
2684
|
+
points[pointIndex] = resizeState.endTransformPoint;
|
|
2685
|
+
}
|
|
1663
2686
|
DrawTransforms.resizeLine(board, { points, source, target }, resizeRef.path);
|
|
1664
2687
|
}
|
|
1665
2688
|
};
|
|
@@ -1672,9 +2695,14 @@ const withLineBoundReaction = (board) => {
|
|
|
1672
2695
|
let boundShapeG = null;
|
|
1673
2696
|
board.pointerMove = (event) => {
|
|
1674
2697
|
boundShapeG?.remove();
|
|
1675
|
-
const
|
|
2698
|
+
const linePointers = Object.keys(LineShape);
|
|
2699
|
+
const isLinePointer = PlaitBoard.isInPointer(board, linePointers);
|
|
1676
2700
|
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1677
|
-
const isLineResizing = isResizingByCondition(board,
|
|
2701
|
+
const isLineResizing = isResizingByCondition(board, resizeRef => {
|
|
2702
|
+
const { element, handle } = resizeRef;
|
|
2703
|
+
const isSourceOrTarget = handle === LineResizeHandle.target || handle === LineResizeHandle.source;
|
|
2704
|
+
return PlaitDrawElement.isLine(element) && isSourceOrTarget;
|
|
2705
|
+
});
|
|
1678
2706
|
if (isLinePointer || isLineResizing) {
|
|
1679
2707
|
const hitElement = getHitOutlineGeometry(board, movingPoint, -4);
|
|
1680
2708
|
if (hitElement) {
|
|
@@ -1752,8 +2780,74 @@ function editHandle(board, element, manageIndex, isFirstEdit = false) {
|
|
|
1752
2780
|
});
|
|
1753
2781
|
}
|
|
1754
2782
|
|
|
2783
|
+
class ImageComponent extends CommonPluginElement {
|
|
2784
|
+
get activeGenerator() {
|
|
2785
|
+
return this.imageGenerator.componentRef.instance.activeGenerator;
|
|
2786
|
+
}
|
|
2787
|
+
constructor(viewContainerRef, cdr) {
|
|
2788
|
+
super(cdr);
|
|
2789
|
+
this.viewContainerRef = viewContainerRef;
|
|
2790
|
+
this.cdr = cdr;
|
|
2791
|
+
this.destroy$ = new Subject();
|
|
2792
|
+
}
|
|
2793
|
+
initializeGenerator() {
|
|
2794
|
+
this.imageGenerator = new ImageGenerator(this.board, {
|
|
2795
|
+
getRectangle: (element) => {
|
|
2796
|
+
return {
|
|
2797
|
+
x: element.points[0][0],
|
|
2798
|
+
y: element.points[0][1],
|
|
2799
|
+
width: element.points[1][0] - element.points[0][0],
|
|
2800
|
+
height: element.points[1][1] - element.points[0][1]
|
|
2801
|
+
};
|
|
2802
|
+
},
|
|
2803
|
+
getImageItem: element => {
|
|
2804
|
+
return {
|
|
2805
|
+
url: element.url,
|
|
2806
|
+
width: element.points[1][0] - element.points[0][0],
|
|
2807
|
+
height: element.points[1][1] - element.points[0][1]
|
|
2808
|
+
};
|
|
2809
|
+
}
|
|
2810
|
+
});
|
|
2811
|
+
}
|
|
2812
|
+
ngOnInit() {
|
|
2813
|
+
super.ngOnInit();
|
|
2814
|
+
this.initializeGenerator();
|
|
2815
|
+
this.imageGenerator.draw(this.element, this.g, this.viewContainerRef);
|
|
2816
|
+
}
|
|
2817
|
+
onContextChanged(value, previous) {
|
|
2818
|
+
if (value.element !== previous.element) {
|
|
2819
|
+
this.imageGenerator.updateImage(this.g, previous.element, value.element);
|
|
2820
|
+
this.imageGenerator.componentRef.instance.isFocus = this.selected;
|
|
2821
|
+
}
|
|
2822
|
+
else {
|
|
2823
|
+
const hasSameSelected = value.selected === previous.selected;
|
|
2824
|
+
const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
|
|
2825
|
+
if (!hasSameSelected || !hasSameHandleState) {
|
|
2826
|
+
this.imageGenerator.componentRef.instance.isFocus = this.selected;
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2830
|
+
ngOnDestroy() {
|
|
2831
|
+
super.ngOnDestroy();
|
|
2832
|
+
this.destroy$.next();
|
|
2833
|
+
this.destroy$.complete();
|
|
2834
|
+
this.imageGenerator.destroy();
|
|
2835
|
+
}
|
|
2836
|
+
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 }); }
|
|
2837
|
+
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 }); }
|
|
2838
|
+
}
|
|
2839
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: ImageComponent, decorators: [{
|
|
2840
|
+
type: Component,
|
|
2841
|
+
args: [{
|
|
2842
|
+
selector: 'plait-draw-geometry',
|
|
2843
|
+
template: ``,
|
|
2844
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2845
|
+
standalone: true
|
|
2846
|
+
}]
|
|
2847
|
+
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
|
|
2848
|
+
|
|
1755
2849
|
const withDraw = (board) => {
|
|
1756
|
-
const { drawElement, getRectangle, isHitSelection, isMovable,
|
|
2850
|
+
const { drawElement, getRectangle, isHitSelection, isMovable, isAlign } = board;
|
|
1757
2851
|
board.drawElement = (context) => {
|
|
1758
2852
|
if (PlaitDrawElement.isGeometry(context.element)) {
|
|
1759
2853
|
return GeometryComponent;
|
|
@@ -1761,6 +2855,9 @@ const withDraw = (board) => {
|
|
|
1761
2855
|
else if (PlaitDrawElement.isLine(context.element)) {
|
|
1762
2856
|
return LineComponent;
|
|
1763
2857
|
}
|
|
2858
|
+
else if (PlaitDrawElement.isImage(context.element)) {
|
|
2859
|
+
return ImageComponent;
|
|
2860
|
+
}
|
|
1764
2861
|
return drawElement(context);
|
|
1765
2862
|
};
|
|
1766
2863
|
board.getRectangle = (element) => {
|
|
@@ -1771,6 +2868,9 @@ const withDraw = (board) => {
|
|
|
1771
2868
|
const points = getLinePoints(board, element);
|
|
1772
2869
|
return getRectangleByPoints(points);
|
|
1773
2870
|
}
|
|
2871
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2872
|
+
return getRectangleByPoints(element.points);
|
|
2873
|
+
}
|
|
1774
2874
|
return getRectangle(element);
|
|
1775
2875
|
};
|
|
1776
2876
|
board.isHitSelection = (element, range) => {
|
|
@@ -1783,6 +2883,11 @@ const withDraw = (board) => {
|
|
|
1783
2883
|
}
|
|
1784
2884
|
return RectangleClient.isHit(rangeRectangle, client);
|
|
1785
2885
|
}
|
|
2886
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2887
|
+
const client = getRectangleByPoints(element.points);
|
|
2888
|
+
const rangeRectangle = RectangleClient.toRectangleClient([range.anchor, range.focus]);
|
|
2889
|
+
return RectangleClient.isHit(rangeRectangle, client);
|
|
2890
|
+
}
|
|
1786
2891
|
if (PlaitDrawElement.isLine(element)) {
|
|
1787
2892
|
const points = getLinePoints(board, element);
|
|
1788
2893
|
const strokeWidth = getStrokeWidthByElement(element);
|
|
@@ -1801,17 +2906,26 @@ const withDraw = (board) => {
|
|
|
1801
2906
|
if (PlaitDrawElement.isGeometry(element)) {
|
|
1802
2907
|
return true;
|
|
1803
2908
|
}
|
|
2909
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2910
|
+
return true;
|
|
2911
|
+
}
|
|
1804
2912
|
if (PlaitDrawElement.isLine(element)) {
|
|
1805
2913
|
return !element.source.boundId && !element.target.boundId;
|
|
1806
2914
|
}
|
|
1807
2915
|
return isMovable(element);
|
|
1808
2916
|
};
|
|
1809
|
-
|
|
2917
|
+
board.isAlign = (element) => {
|
|
2918
|
+
if (PlaitDrawElement.isGeometry(element) || PlaitDrawElement.isImage(element)) {
|
|
2919
|
+
return true;
|
|
2920
|
+
}
|
|
2921
|
+
return isAlign(element);
|
|
2922
|
+
};
|
|
2923
|
+
return withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))));
|
|
1810
2924
|
};
|
|
1811
2925
|
|
|
1812
2926
|
/**
|
|
1813
2927
|
* Generated bundle index. Do not edit.
|
|
1814
2928
|
*/
|
|
1815
2929
|
|
|
1816
|
-
export { DefaultGeometryActiveStyle, DefaultGeometryProperty, DefaultGeometryStyle, DefaultTextProperty,
|
|
2930
|
+
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 };
|
|
1817
2931
|
//# sourceMappingURL=plait-draw.mjs.map
|