@plait/draw 0.1.0-next.11 → 0.1.0-next.12
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/pointer.d.ts +5 -1
- package/esm2022/constants/pointer.mjs +10 -2
- package/esm2022/generators/line-active.generator.mjs +3 -4
- package/esm2022/interfaces/geometry.mjs +5 -1
- package/esm2022/interfaces/line.mjs +11 -3
- package/esm2022/plugins/with-draw.mjs +1 -1
- package/esm2022/utils/engine/diamond.mjs +11 -3
- package/esm2022/utils/engine/ellipse.mjs +38 -1
- package/esm2022/utils/engine/index.mjs +10 -2
- package/esm2022/utils/engine/left-arrow.mjs +45 -0
- package/esm2022/utils/engine/parallelogram.mjs +16 -9
- package/esm2022/utils/engine/rectangle.mjs +11 -3
- package/esm2022/utils/engine/right-arrow.mjs +45 -0
- package/esm2022/utils/engine/round-rectangle.mjs +11 -1
- package/esm2022/utils/engine/trapezoid.mjs +40 -0
- package/esm2022/utils/engine/triangle.mjs +40 -0
- package/esm2022/utils/geometry.mjs +13 -2
- package/esm2022/utils/line.mjs +75 -39
- package/esm2022/utils/position/line.mjs +3 -4
- package/fesm2022/plait-draw.mjs +353 -56
- package/fesm2022/plait-draw.mjs.map +1 -1
- package/interfaces/geometry.d.ts +9 -2
- package/interfaces/line.d.ts +9 -2
- package/package.json +3 -2
- package/styles/styles.scss +1 -1
- package/utils/engine/left-arrow.d.ts +4 -0
- package/utils/engine/parallelogram.d.ts +1 -1
- package/utils/engine/right-arrow.d.ts +4 -0
- package/utils/engine/trapezoid.d.ts +4 -0
- package/utils/engine/triangle.d.ts +4 -0
- package/utils/geometry.d.ts +1 -0
- package/utils/line.d.ts +10 -6
package/fesm2022/plait-draw.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { PlaitElement, ACTIVE_STROKE_WIDTH, RectangleClient, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, idCreator, createG, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, arrowPoints, createPath, drawLinearPath, distanceBetweenPointAndSegments, createMask, createRect,
|
|
1
|
+
import { PlaitElement, ACTIVE_STROKE_WIDTH, RectangleClient, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, idCreator, createG, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, arrowPoints, createPath, drawLinearPath, getElementById, Direction, distanceBetweenPointAndSegments, createMask, createRect, findElements, getSelectedElements, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Point, isSelectionMoving, PlaitPluginElementComponent, transformPoint, toPoint, BoardTransforms, PlaitPointerType, preventTouchMove, createForeignObject, setClipboardData, getDataFromClipboard, depthFirstRecursion, getIsRecursionFunc, getHitElements, isPolylineHitRectangle } from '@plait/core';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
|
4
4
|
import { Subject } from 'rxjs';
|
|
5
|
-
import { getRectangleByPoints, getFactorByPoints,
|
|
5
|
+
import { getRectangleByPoints, getFactorByPoints, getPoints, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVector90, getDirectionByVector, 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
6
|
import { Alignment, buildText, AlignEditor, TextManage, DEFAULT_FONT_SIZE, getTextFromClipboard, getTextSize } from '@plait/text';
|
|
7
7
|
import { isKeyHotkey } from 'is-hotkey';
|
|
8
8
|
import { Node } from 'slate';
|
|
@@ -15,6 +15,10 @@ var GeometryShape;
|
|
|
15
15
|
GeometryShape["roundRectangle"] = "roundRectangle";
|
|
16
16
|
GeometryShape["parallelogram"] = "parallelogram";
|
|
17
17
|
GeometryShape["text"] = "text";
|
|
18
|
+
GeometryShape["triangle"] = "triangle";
|
|
19
|
+
GeometryShape["leftArrow"] = "leftArrow";
|
|
20
|
+
GeometryShape["trapezoid"] = "trapezoid";
|
|
21
|
+
GeometryShape["rightArrow"] = "rightArrow";
|
|
18
22
|
})(GeometryShape || (GeometryShape = {}));
|
|
19
23
|
const PlaitGeometry = {
|
|
20
24
|
getTextEditor(element) {
|
|
@@ -62,11 +66,19 @@ const PlaitLine = {
|
|
|
62
66
|
}
|
|
63
67
|
throw new Error('can not get correctly component in get text editor');
|
|
64
68
|
},
|
|
69
|
+
isSourceMarkOrTargetMark(line, markType, handleKey) {
|
|
70
|
+
if (handleKey === LineHandleKey.source) {
|
|
71
|
+
return line.source.marker === markType;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return line.target.marker === markType;
|
|
75
|
+
}
|
|
76
|
+
},
|
|
65
77
|
isSourceMark(line, markType) {
|
|
66
|
-
return line.source
|
|
78
|
+
return PlaitLine.isSourceMarkOrTargetMark(line, markType, LineHandleKey.source);
|
|
67
79
|
},
|
|
68
80
|
isTargetMark(line, markType) {
|
|
69
|
-
return line.target
|
|
81
|
+
return PlaitLine.isSourceMarkOrTargetMark(line, markType, LineHandleKey.target);
|
|
70
82
|
},
|
|
71
83
|
isBoundElementOfSource(line, element) {
|
|
72
84
|
return line.source.boundId === element.id;
|
|
@@ -139,6 +151,10 @@ var DrawPointerType;
|
|
|
139
151
|
DrawPointerType["roundRectangle"] = "roundRectangle";
|
|
140
152
|
DrawPointerType["parallelogram"] = "parallelogram";
|
|
141
153
|
DrawPointerType["ellipse"] = "ellipse";
|
|
154
|
+
DrawPointerType["triangle"] = "triangle";
|
|
155
|
+
DrawPointerType["leftArrow"] = "leftArrow";
|
|
156
|
+
DrawPointerType["trapezoid"] = "trapezoid";
|
|
157
|
+
DrawPointerType["rightArrow"] = "rightArrow";
|
|
142
158
|
})(DrawPointerType || (DrawPointerType = {}));
|
|
143
159
|
const GeometryPointer = [
|
|
144
160
|
DrawPointerType.rectangle,
|
|
@@ -146,7 +162,11 @@ const GeometryPointer = [
|
|
|
146
162
|
DrawPointerType.diamond,
|
|
147
163
|
DrawPointerType.ellipse,
|
|
148
164
|
DrawPointerType.parallelogram,
|
|
149
|
-
DrawPointerType.roundRectangle
|
|
165
|
+
DrawPointerType.roundRectangle,
|
|
166
|
+
DrawPointerType.triangle,
|
|
167
|
+
DrawPointerType.leftArrow,
|
|
168
|
+
DrawPointerType.trapezoid,
|
|
169
|
+
DrawPointerType.rightArrow
|
|
150
170
|
];
|
|
151
171
|
|
|
152
172
|
const getStrokeWidthByElement = (element) => {
|
|
@@ -183,9 +203,16 @@ const DiamondEngine = {
|
|
|
183
203
|
const controlPoints = RectangleClient.getEdgeCenterPoints(rectangle);
|
|
184
204
|
return isPointInPolygon(point, controlPoints);
|
|
185
205
|
},
|
|
206
|
+
getCornerPoints(rectangle) {
|
|
207
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
208
|
+
},
|
|
186
209
|
getNearestPoint(rectangle, point) {
|
|
187
|
-
|
|
188
|
-
|
|
210
|
+
return getNearestPointBetweenPointAndSegments(point, DiamondEngine.getCornerPoints(rectangle));
|
|
211
|
+
},
|
|
212
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
213
|
+
const corners = DiamondEngine.getCornerPoints(rectangle);
|
|
214
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
215
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
189
216
|
},
|
|
190
217
|
getConnectorPoints(rectangle) {
|
|
191
218
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
@@ -202,10 +229,22 @@ const EllipseEngine = {
|
|
|
202
229
|
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
203
230
|
return isPointInEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
|
|
204
231
|
},
|
|
232
|
+
getCornerPoints(rectangle) {
|
|
233
|
+
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
234
|
+
},
|
|
205
235
|
getNearestPoint(rectangle, point) {
|
|
206
236
|
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
207
237
|
return getNearestPointBetweenPointAndEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
|
|
208
238
|
},
|
|
239
|
+
getTangentVectorByConnectionPoint(rectangle, pointOfRectangle) {
|
|
240
|
+
const connectionPoint = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
241
|
+
const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
|
|
242
|
+
const point = [connectionPoint[0] - centerPoint[0], -(connectionPoint[1] - centerPoint[1])];
|
|
243
|
+
const a = rectangle.width / 2;
|
|
244
|
+
const b = rectangle.height / 2;
|
|
245
|
+
const slope = getTangentSlope(point[0], point[1], a, b);
|
|
246
|
+
return getVectorBySlope(point[0], point[1], slope);
|
|
247
|
+
},
|
|
209
248
|
getConnectorPoints(rectangle) {
|
|
210
249
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
211
250
|
}
|
|
@@ -245,29 +284,104 @@ function getNearestPointBetweenPointAndEllipse(point, center, rx, ry, rotation =
|
|
|
245
284
|
const signY = point[1] > center[1] ? 1 : -1;
|
|
246
285
|
return [center[0] + a * tx * signX, center[1] + b * ty * signY];
|
|
247
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* the result of slope is based on Cartesian coordinate system
|
|
289
|
+
* x, y are based on the position in the Cartesian coordinate system
|
|
290
|
+
*/
|
|
291
|
+
function getTangentSlope(x, y, a, b) {
|
|
292
|
+
const k = (-b * b * x) / (a * a * y);
|
|
293
|
+
return k;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* x, y are based on the position in the Cartesian coordinate system
|
|
297
|
+
*/
|
|
298
|
+
function getVectorBySlope(x, y, slope) {
|
|
299
|
+
const deltaX = 30;
|
|
300
|
+
const deltaY = -slope * deltaX;
|
|
301
|
+
let start = [0 - deltaX, 0 - deltaY];
|
|
302
|
+
let end = [0 + deltaX, 0 + deltaY];
|
|
303
|
+
// 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.
|
|
304
|
+
if (y < 0) {
|
|
305
|
+
const temp = start;
|
|
306
|
+
start = end;
|
|
307
|
+
end = temp;
|
|
308
|
+
}
|
|
309
|
+
const vector = [end[0] - start[0], end[1] - start[1]];
|
|
310
|
+
return vector;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const LeftArrowEngine = {
|
|
314
|
+
draw(board, rectangle, options) {
|
|
315
|
+
const points = getLeftArrowPoints(rectangle);
|
|
316
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
317
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
318
|
+
setStrokeLinecap(polygon, 'round');
|
|
319
|
+
return polygon;
|
|
320
|
+
},
|
|
321
|
+
getCornerPoints(rectangle) {
|
|
322
|
+
return getLeftArrowPoints(rectangle);
|
|
323
|
+
},
|
|
324
|
+
isHit(rectangle, point) {
|
|
325
|
+
const points = getLeftArrowPoints(rectangle);
|
|
326
|
+
return isPointInPolygon(point, points);
|
|
327
|
+
},
|
|
328
|
+
getNearestPoint(rectangle, point) {
|
|
329
|
+
const cornerPoints = getLeftArrowPoints(rectangle);
|
|
330
|
+
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
331
|
+
},
|
|
332
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
333
|
+
const corners = getLeftArrowPoints(rectangle);
|
|
334
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
335
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
336
|
+
},
|
|
337
|
+
getConnectorPoints(rectangle) {
|
|
338
|
+
return [
|
|
339
|
+
[rectangle.x, rectangle.y + rectangle.height / 2],
|
|
340
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2]
|
|
341
|
+
];
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
const getLeftArrowPoints = (rectangle) => {
|
|
345
|
+
return [
|
|
346
|
+
[rectangle.x, rectangle.y + rectangle.height / 2],
|
|
347
|
+
[rectangle.x + rectangle.width * 0.32, rectangle.y],
|
|
348
|
+
[rectangle.x + rectangle.width * 0.32, rectangle.y + rectangle.height * 0.2],
|
|
349
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height * 0.2],
|
|
350
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height * 0.8],
|
|
351
|
+
[rectangle.x + rectangle.width * 0.32, rectangle.y + rectangle.height * 0.8],
|
|
352
|
+
[rectangle.x + rectangle.width * 0.32, rectangle.y + rectangle.height]
|
|
353
|
+
];
|
|
354
|
+
};
|
|
248
355
|
|
|
249
356
|
const ParallelogramEngine = {
|
|
250
357
|
draw(board, rectangle, options) {
|
|
251
|
-
const points =
|
|
358
|
+
const points = getParallelogramCornerPoints(rectangle);
|
|
252
359
|
const rs = PlaitBoard.getRoughSVG(board);
|
|
253
360
|
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
254
361
|
setStrokeLinecap(polygon, 'round');
|
|
255
362
|
return polygon;
|
|
256
363
|
},
|
|
257
364
|
isHit(rectangle, point) {
|
|
258
|
-
const parallelogramPoints =
|
|
365
|
+
const parallelogramPoints = getParallelogramCornerPoints(rectangle);
|
|
259
366
|
return isPointInPolygon(point, parallelogramPoints);
|
|
260
367
|
},
|
|
368
|
+
getCornerPoints(rectangle) {
|
|
369
|
+
return getParallelogramCornerPoints(rectangle);
|
|
370
|
+
},
|
|
261
371
|
getNearestPoint(rectangle, point) {
|
|
262
|
-
|
|
263
|
-
|
|
372
|
+
return getNearestPointBetweenPointAndSegments(point, ParallelogramEngine.getCornerPoints(rectangle));
|
|
373
|
+
},
|
|
374
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
375
|
+
const corners = getParallelogramCornerPoints(rectangle);
|
|
376
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
377
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
264
378
|
},
|
|
265
379
|
getConnectorPoints(rectangle) {
|
|
266
|
-
const cornerPoints =
|
|
380
|
+
const cornerPoints = getParallelogramCornerPoints(rectangle);
|
|
267
381
|
return getCenterPointsOnPolygon(cornerPoints);
|
|
268
382
|
}
|
|
269
383
|
};
|
|
270
|
-
const
|
|
384
|
+
const getParallelogramCornerPoints = (rectangle) => {
|
|
271
385
|
return [
|
|
272
386
|
[rectangle.x + rectangle.width / 4, rectangle.y],
|
|
273
387
|
[rectangle.x + rectangle.width, rectangle.y],
|
|
@@ -284,15 +398,65 @@ const RectangleEngine = {
|
|
|
284
398
|
const rangeRectangle = RectangleClient.toRectangleClient([point, point]);
|
|
285
399
|
return RectangleClient.isHit(rectangle, rangeRectangle);
|
|
286
400
|
},
|
|
401
|
+
getCornerPoints(rectangle) {
|
|
402
|
+
return RectangleClient.getCornerPoints(rectangle);
|
|
403
|
+
},
|
|
287
404
|
getNearestPoint(rectangle, point) {
|
|
288
|
-
|
|
289
|
-
|
|
405
|
+
return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
|
|
406
|
+
},
|
|
407
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
408
|
+
const corners = RectangleEngine.getCornerPoints(rectangle);
|
|
409
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
410
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
290
411
|
},
|
|
291
412
|
getConnectorPoints(rectangle) {
|
|
292
413
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
293
414
|
}
|
|
294
415
|
};
|
|
295
416
|
|
|
417
|
+
const RightArrowEngine = {
|
|
418
|
+
draw(board, rectangle, options) {
|
|
419
|
+
const points = getRightArrowPoints(rectangle);
|
|
420
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
421
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
422
|
+
setStrokeLinecap(polygon, 'round');
|
|
423
|
+
return polygon;
|
|
424
|
+
},
|
|
425
|
+
getCornerPoints(rectangle) {
|
|
426
|
+
return getRightArrowPoints(rectangle);
|
|
427
|
+
},
|
|
428
|
+
isHit(rectangle, point) {
|
|
429
|
+
const points = getRightArrowPoints(rectangle);
|
|
430
|
+
return isPointInPolygon(point, points);
|
|
431
|
+
},
|
|
432
|
+
getNearestPoint(rectangle, point) {
|
|
433
|
+
const cornerPoints = getRightArrowPoints(rectangle);
|
|
434
|
+
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
435
|
+
},
|
|
436
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
437
|
+
const corners = getRightArrowPoints(rectangle);
|
|
438
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
439
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
440
|
+
},
|
|
441
|
+
getConnectorPoints(rectangle) {
|
|
442
|
+
return [
|
|
443
|
+
[rectangle.x, rectangle.y + rectangle.height / 2],
|
|
444
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2]
|
|
445
|
+
];
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
const getRightArrowPoints = (rectangle) => {
|
|
449
|
+
return [
|
|
450
|
+
[rectangle.x, rectangle.y + rectangle.height * 0.2],
|
|
451
|
+
[rectangle.x + rectangle.width * 0.68, rectangle.y + rectangle.height * 0.2],
|
|
452
|
+
[rectangle.x + rectangle.width * 0.68, rectangle.y],
|
|
453
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2],
|
|
454
|
+
[rectangle.x + rectangle.width * 0.68, rectangle.y + rectangle.height],
|
|
455
|
+
[rectangle.x + rectangle.width * 0.68, rectangle.y + rectangle.height * 0.8],
|
|
456
|
+
[rectangle.x, rectangle.y + rectangle.height * 0.8]
|
|
457
|
+
];
|
|
458
|
+
};
|
|
459
|
+
|
|
296
460
|
const RoundRectangleEngine = {
|
|
297
461
|
draw(board, rectangle, options) {
|
|
298
462
|
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 +464,17 @@ const RoundRectangleEngine = {
|
|
|
300
464
|
isHit(rectangle, point) {
|
|
301
465
|
return isPointInRoundRectangle(point, rectangle, getRoundRectangleRadius(rectangle));
|
|
302
466
|
},
|
|
467
|
+
getCornerPoints(rectangle) {
|
|
468
|
+
return RectangleClient.getCornerPoints(rectangle);
|
|
469
|
+
},
|
|
303
470
|
getNearestPoint(rectangle, point) {
|
|
304
471
|
return getNearestPointBetweenPointAndRoundRectangle(point, rectangle, getRoundRectangleRadius(rectangle));
|
|
305
472
|
},
|
|
473
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
474
|
+
const corners = RectangleEngine.getCornerPoints(rectangle);
|
|
475
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
476
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
477
|
+
},
|
|
306
478
|
getConnectorPoints(rectangle) {
|
|
307
479
|
return RectangleClient.getEdgeCenterPoints(rectangle);
|
|
308
480
|
}
|
|
@@ -340,13 +512,93 @@ function getNearestPointBetweenPointAndRoundRectangle(point, rectangle, radius)
|
|
|
340
512
|
return result;
|
|
341
513
|
}
|
|
342
514
|
|
|
515
|
+
const TrapezoidEngine = {
|
|
516
|
+
draw(board, rectangle, options) {
|
|
517
|
+
const points = getTrapezoidPoints(rectangle);
|
|
518
|
+
const rs = PlaitBoard.getRoughSVG(board);
|
|
519
|
+
const polygon = rs.polygon(points, { ...options, fillStyle: 'solid' });
|
|
520
|
+
setStrokeLinecap(polygon, 'round');
|
|
521
|
+
return polygon;
|
|
522
|
+
},
|
|
523
|
+
isHit(rectangle, point) {
|
|
524
|
+
const points = getTrapezoidPoints(rectangle);
|
|
525
|
+
return isPointInPolygon(point, points);
|
|
526
|
+
},
|
|
527
|
+
getNearestPoint(rectangle, point) {
|
|
528
|
+
const cornerPoints = getTrapezoidPoints(rectangle);
|
|
529
|
+
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
530
|
+
},
|
|
531
|
+
getConnectorPoints(rectangle) {
|
|
532
|
+
const points = getTrapezoidPoints(rectangle);
|
|
533
|
+
return getCenterPointsOnPolygon(points);
|
|
534
|
+
},
|
|
535
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
536
|
+
const corners = getTrapezoidPoints(rectangle);
|
|
537
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
538
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
539
|
+
},
|
|
540
|
+
getCornerPoints(rectangle) {
|
|
541
|
+
return getTrapezoidPoints(rectangle);
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
const getTrapezoidPoints = (rectangle) => {
|
|
545
|
+
return [
|
|
546
|
+
[rectangle.x + rectangle.width * 0.15, rectangle.y],
|
|
547
|
+
[rectangle.x + rectangle.width * 0.85, rectangle.y],
|
|
548
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height],
|
|
549
|
+
[rectangle.x, rectangle.y + rectangle.height]
|
|
550
|
+
];
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
const TriangleEngine = {
|
|
554
|
+
draw(board, rectangle, options) {
|
|
555
|
+
const points = getTrianglePoints(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 points = getTrianglePoints(rectangle);
|
|
563
|
+
return isPointInPolygon(point, points);
|
|
564
|
+
},
|
|
565
|
+
getNearestPoint(rectangle, point) {
|
|
566
|
+
const cornerPoints = getTrianglePoints(rectangle);
|
|
567
|
+
return getNearestPointBetweenPointAndSegments(point, cornerPoints);
|
|
568
|
+
},
|
|
569
|
+
getConnectorPoints(rectangle) {
|
|
570
|
+
const cornerPoints = getTrianglePoints(rectangle);
|
|
571
|
+
const lineCenterPoints = getCenterPointsOnPolygon(cornerPoints);
|
|
572
|
+
return [...lineCenterPoints, ...cornerPoints];
|
|
573
|
+
},
|
|
574
|
+
getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
|
|
575
|
+
const corners = getTrianglePoints(rectangle);
|
|
576
|
+
const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
|
|
577
|
+
return getEdgeOnPolygonByPoint(corners, point);
|
|
578
|
+
},
|
|
579
|
+
getCornerPoints(rectangle) {
|
|
580
|
+
return getTrianglePoints(rectangle);
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
const getTrianglePoints = (rectangle) => {
|
|
584
|
+
return [
|
|
585
|
+
[rectangle.x + rectangle.width / 2, rectangle.y],
|
|
586
|
+
[rectangle.x + rectangle.width, rectangle.y + rectangle.height],
|
|
587
|
+
[rectangle.x, rectangle.y + rectangle.height]
|
|
588
|
+
];
|
|
589
|
+
};
|
|
590
|
+
|
|
343
591
|
const ShapeEngineMap = {
|
|
344
592
|
[GeometryShape.rectangle]: RectangleEngine,
|
|
345
593
|
[GeometryShape.diamond]: DiamondEngine,
|
|
346
594
|
[GeometryShape.ellipse]: EllipseEngine,
|
|
347
595
|
[GeometryShape.parallelogram]: ParallelogramEngine,
|
|
348
596
|
[GeometryShape.roundRectangle]: RoundRectangleEngine,
|
|
349
|
-
[GeometryShape.text]: RectangleEngine
|
|
597
|
+
[GeometryShape.text]: RectangleEngine,
|
|
598
|
+
[GeometryShape.triangle]: TriangleEngine,
|
|
599
|
+
[GeometryShape.leftArrow]: LeftArrowEngine,
|
|
600
|
+
[GeometryShape.trapezoid]: TrapezoidEngine,
|
|
601
|
+
[GeometryShape.rightArrow]: RightArrowEngine
|
|
350
602
|
};
|
|
351
603
|
const getEngine = (shape) => {
|
|
352
604
|
return ShapeEngineMap[shape];
|
|
@@ -428,6 +680,17 @@ const getCenterPointsOnPolygon = (points) => {
|
|
|
428
680
|
}
|
|
429
681
|
return centerPoint;
|
|
430
682
|
};
|
|
683
|
+
const getEdgeOnPolygonByPoint = (corners, point) => {
|
|
684
|
+
for (let index = 1; index <= corners.length; index++) {
|
|
685
|
+
let start = corners[index - 1];
|
|
686
|
+
let end = index === corners.length ? corners[0] : corners[index];
|
|
687
|
+
const distance = distanceBetweenPointAndSegment(point[0], point[1], start[0], start[1], end[0], end[1]);
|
|
688
|
+
if (distance < 1) {
|
|
689
|
+
return [start, end];
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
return null;
|
|
693
|
+
};
|
|
431
694
|
|
|
432
695
|
const drawLineArrow = (element, points, options) => {
|
|
433
696
|
const arrowG = createG();
|
|
@@ -531,21 +794,48 @@ const getLinePoints = (board, element) => {
|
|
|
531
794
|
return element.shape === LineShape.elbow ? getElbowPoints(board, element) : getStraightPoints(board, element);
|
|
532
795
|
};
|
|
533
796
|
const getStraightPoints = (board, element) => {
|
|
534
|
-
return
|
|
797
|
+
return getLineHandlePoints(board, element);
|
|
798
|
+
};
|
|
799
|
+
const getLineHandlePoints = (board, element) => {
|
|
800
|
+
const handleRefPair = getLineHandleRefPair(board, element);
|
|
801
|
+
return [handleRefPair.source.point, handleRefPair.target.point];
|
|
802
|
+
};
|
|
803
|
+
const getLineHandleRefPair = (board, element) => {
|
|
804
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
805
|
+
const sourceBoundElement = element.source.boundId ? getElementById(board, element.source.boundId) : undefined;
|
|
806
|
+
const targetBoundElement = element.target.boundId ? getElementById(board, element.target.boundId) : undefined;
|
|
807
|
+
let sourcePoint = sourceBoundElement ? getConnectionPoint(sourceBoundElement, element.source.connection) : element.points[0];
|
|
808
|
+
let targetPoint = targetBoundElement
|
|
809
|
+
? getConnectionPoint(targetBoundElement, element.target.connection)
|
|
810
|
+
: element.points[element.points.length - 1];
|
|
811
|
+
let sourceDirection = sourcePoint[0] < targetPoint[0] ? Direction.right : Direction.left;
|
|
812
|
+
let targetDirection = sourcePoint[0] < targetPoint[0] ? Direction.left : Direction.right;
|
|
813
|
+
const sourceHandleRef = { key: LineHandleKey.source, point: sourcePoint, direction: sourceDirection };
|
|
814
|
+
const targetHandleRef = { key: LineHandleKey.target, point: targetPoint, direction: targetDirection };
|
|
815
|
+
if (sourceBoundElement) {
|
|
816
|
+
const connectionOffset = PlaitLine.isSourceMarkOrTargetMark(element, LineMarkerType.none, LineHandleKey.source) ? 0 : strokeWidth;
|
|
817
|
+
const direction = getDirectionByBoundElementAndConnection(board, sourceBoundElement, element.source.connection);
|
|
818
|
+
sourceDirection = direction ? direction : sourceDirection;
|
|
819
|
+
sourcePoint = getConnectionPoint(sourceBoundElement, element.source.connection, sourceDirection, connectionOffset);
|
|
820
|
+
sourceHandleRef.boundElement = sourceBoundElement;
|
|
821
|
+
sourceHandleRef.direction = sourceDirection;
|
|
822
|
+
sourceHandleRef.point = sourcePoint;
|
|
823
|
+
}
|
|
824
|
+
if (targetBoundElement) {
|
|
825
|
+
const connectionOffset = PlaitLine.isSourceMarkOrTargetMark(element, LineMarkerType.none, LineHandleKey.target) ? 0 : strokeWidth;
|
|
826
|
+
const direction = getDirectionByBoundElementAndConnection(board, targetBoundElement, element.target.connection);
|
|
827
|
+
targetDirection = direction ? direction : targetDirection;
|
|
828
|
+
targetPoint = getConnectionPoint(targetBoundElement, element.target.connection, targetDirection, connectionOffset);
|
|
829
|
+
targetHandleRef.boundElement = sourceBoundElement;
|
|
830
|
+
targetHandleRef.direction = targetDirection;
|
|
831
|
+
targetHandleRef.point = targetPoint;
|
|
832
|
+
}
|
|
833
|
+
return { source: sourceHandleRef, target: targetHandleRef };
|
|
535
834
|
};
|
|
536
835
|
const getElbowPoints = (board, element) => {
|
|
537
836
|
if (element.points.length === 2) {
|
|
538
|
-
const
|
|
539
|
-
const
|
|
540
|
-
let sourceDirection = source[0] < target[0] ? Direction.right : Direction.left;
|
|
541
|
-
let targetDirection = source[0] < target[0] ? Direction.left : Direction.right;
|
|
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);
|
|
837
|
+
const handleRefPair = getLineHandleRefPair(board, element);
|
|
838
|
+
const points = getPoints(handleRefPair.source.point, handleRefPair.source.direction, handleRefPair.target.point, handleRefPair.target.direction, 30);
|
|
549
839
|
return points;
|
|
550
840
|
}
|
|
551
841
|
return element.points;
|
|
@@ -614,33 +904,42 @@ function drawMask(board, element, id) {
|
|
|
614
904
|
maskTargetFillRect.setAttribute('opacity', '0');
|
|
615
905
|
return { mask, maskTargetFillRect };
|
|
616
906
|
}
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
return
|
|
907
|
+
const getDirectionByBoundElementAndConnection = (board, boundElement, connection) => {
|
|
908
|
+
const rectangle = getRectangleByPoints(boundElement.points);
|
|
909
|
+
const engine = getEngine(boundElement.shape);
|
|
910
|
+
const direction = getDirectionByPointOfRectangle(connection);
|
|
911
|
+
if (direction) {
|
|
912
|
+
return direction;
|
|
623
913
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
914
|
+
if (engine.getEdgeByConnectionPoint) {
|
|
915
|
+
const edge = engine.getEdgeByConnectionPoint(rectangle, connection);
|
|
916
|
+
if (edge) {
|
|
917
|
+
const vector = [edge[1][0] - edge[0][0], edge[1][1] - edge[0][1]];
|
|
918
|
+
const vector90 = rotateVector90(vector);
|
|
919
|
+
const direction = getDirectionByVector(vector90);
|
|
920
|
+
return direction;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
if (engine.getTangentVectorByConnectionPoint) {
|
|
924
|
+
const vector = engine.getTangentVectorByConnectionPoint(rectangle, connection);
|
|
925
|
+
if (vector) {
|
|
926
|
+
const vector90 = rotateVector90(vector);
|
|
927
|
+
const direction = getDirectionByVector(vector90);
|
|
928
|
+
return direction;
|
|
929
|
+
}
|
|
634
930
|
}
|
|
635
|
-
return
|
|
931
|
+
return null;
|
|
636
932
|
};
|
|
637
|
-
const getConnectionPoint = (geometry, connection,
|
|
933
|
+
const getConnectionPoint = (geometry, connection, direction, delta) => {
|
|
638
934
|
const rectangle = getRectangleByPoints(geometry.points);
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
935
|
+
if (direction && delta) {
|
|
936
|
+
const directionFactor = getDirectionFactor(direction);
|
|
937
|
+
const point = RectangleClient.getConnectionPoint(rectangle, connection);
|
|
938
|
+
return [point[0] + directionFactor.x * delta, point[1] + directionFactor.y * delta];
|
|
939
|
+
}
|
|
940
|
+
else {
|
|
941
|
+
return RectangleClient.getConnectionPoint(rectangle, connection);
|
|
942
|
+
}
|
|
644
943
|
};
|
|
645
944
|
const transformPointToConnection = (board, point, hitElement) => {
|
|
646
945
|
let rectangle = getRectangleByPoints(hitElement.points);
|
|
@@ -972,8 +1271,7 @@ class LineActiveGenerator extends Generator {
|
|
|
972
1271
|
if (this.hasResizeHandle) {
|
|
973
1272
|
activeG.classList.add('active');
|
|
974
1273
|
activeG.classList.add('line-handle');
|
|
975
|
-
const sourcePoint =
|
|
976
|
-
const targetPoint = getTargetPoint(this.board, element);
|
|
1274
|
+
const [sourcePoint, targetPoint] = getLineHandlePoints(this.board, element);
|
|
977
1275
|
const sourceCircle = drawCircle(PlaitBoard.getRoughSVG(this.board), sourcePoint, RESIZE_HANDLE_DIAMETER, {
|
|
978
1276
|
stroke: '#999999',
|
|
979
1277
|
strokeWidth: 1,
|
|
@@ -1596,8 +1894,7 @@ var LineResizeHandle;
|
|
|
1596
1894
|
LineResizeHandle["target"] = "target";
|
|
1597
1895
|
})(LineResizeHandle || (LineResizeHandle = {}));
|
|
1598
1896
|
const getHitLineResizeHandleRef = (board, element, point) => {
|
|
1599
|
-
const sourcePoint =
|
|
1600
|
-
const targetPoint = getTargetPoint(board, element);
|
|
1897
|
+
const [sourcePoint, targetPoint] = getLineHandlePoints(board, element);
|
|
1601
1898
|
const sourceRectangle = {
|
|
1602
1899
|
x: sourcePoint[0] - RESIZE_HANDLE_DIAMETER / 2,
|
|
1603
1900
|
y: sourcePoint[1] - RESIZE_HANDLE_DIAMETER / 2,
|
|
@@ -1813,5 +2110,5 @@ const withDraw = (board) => {
|
|
|
1813
2110
|
* Generated bundle index. Do not edit.
|
|
1814
2111
|
*/
|
|
1815
2112
|
|
|
1816
|
-
export { DefaultGeometryActiveStyle, DefaultGeometryProperty, DefaultGeometryStyle, DefaultTextProperty, DrawPointerType, DrawTransforms, GeometryComponent, GeometryPointer, GeometryShape, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, ShapeDefaultSpace, StrokeStyle, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getElbowPoints, getFillByElement, getHitConnectorPoint, getHitLineTextIndex, getLineDashByElement, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedLineElements,
|
|
2113
|
+
export { DefaultGeometryActiveStyle, DefaultGeometryProperty, DefaultGeometryStyle, DefaultTextProperty, DrawPointerType, DrawTransforms, GeometryComponent, GeometryPointer, GeometryShape, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, ShapeDefaultSpace, StrokeStyle, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getDirectionByBoundElementAndConnection, getEdgeOnPolygonByPoint, getElbowPoints, getFillByElement, getHitConnectorPoint, getHitLineTextIndex, getLineDashByElement, getLineHandlePoints, getLineHandleRefPair, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedLineElements, getStraightPoints, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, isHitLineText, isHitPolyLine, transformPointToConnection, withDraw };
|
|
1817
2114
|
//# sourceMappingURL=plait-draw.mjs.map
|