@plait/draw 0.1.0-next.10 → 0.1.0-next.11

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.
Files changed (59) hide show
  1. package/esm2022/generators/line-active.generator.mjs +52 -0
  2. package/{esm2020 → esm2022}/geometry.component.mjs +4 -4
  3. package/esm2022/line.component.mjs +160 -0
  4. package/esm2022/plugins/with-draw-fragment.mjs +61 -0
  5. package/esm2022/plugins/with-draw.mjs +72 -0
  6. package/{esm2020 → esm2022}/utils/clipboard.mjs +2 -1
  7. package/{fesm2020 → fesm2022}/plait-draw.mjs +66 -35
  8. package/fesm2022/plait-draw.mjs.map +1 -0
  9. package/generators/line-active.generator.d.ts +1 -0
  10. package/line.component.d.ts +1 -0
  11. package/package.json +5 -11
  12. package/plugins/with-draw-fragment.d.ts +2 -0
  13. package/styles/styles.scss +2 -2
  14. package/esm2020/generators/line-active.generator.mjs +0 -36
  15. package/esm2020/line.component.mjs +0 -152
  16. package/esm2020/plugins/with-draw-fragment.mjs +0 -52
  17. package/esm2020/plugins/with-draw.mjs +0 -73
  18. package/fesm2015/plait-draw.mjs +0 -1765
  19. package/fesm2015/plait-draw.mjs.map +0 -1
  20. package/fesm2020/plait-draw.mjs.map +0 -1
  21. /package/{esm2020 → esm2022}/constants/geometry.mjs +0 -0
  22. /package/{esm2020 → esm2022}/constants/index.mjs +0 -0
  23. /package/{esm2020 → esm2022}/constants/line.mjs +0 -0
  24. /package/{esm2020 → esm2022}/constants/pointer.mjs +0 -0
  25. /package/{esm2020 → esm2022}/generators/geometry-shape.generator.mjs +0 -0
  26. /package/{esm2020 → esm2022}/generators/line.generator.mjs +0 -0
  27. /package/{esm2020 → esm2022}/interfaces/element.mjs +0 -0
  28. /package/{esm2020 → esm2022}/interfaces/geometry.mjs +0 -0
  29. /package/{esm2020 → esm2022}/interfaces/index.mjs +0 -0
  30. /package/{esm2020 → esm2022}/interfaces/line.mjs +0 -0
  31. /package/{esm2020 → esm2022}/interfaces/text.mjs +0 -0
  32. /package/{esm2020 → esm2022}/plait-draw.mjs +0 -0
  33. /package/{esm2020 → esm2022}/plugins/with-draw-hotkey.mjs +0 -0
  34. /package/{esm2020 → esm2022}/plugins/with-geometry-create.mjs +0 -0
  35. /package/{esm2020 → esm2022}/plugins/with-geometry-resize.mjs +0 -0
  36. /package/{esm2020 → esm2022}/plugins/with-line-bound-reaction.mjs +0 -0
  37. /package/{esm2020 → esm2022}/plugins/with-line-create.mjs +0 -0
  38. /package/{esm2020 → esm2022}/plugins/with-line-resize.mjs +0 -0
  39. /package/{esm2020 → esm2022}/plugins/with-line-text.mjs +0 -0
  40. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
  41. /package/{esm2020 → esm2022}/transforms/geometry-text.mjs +0 -0
  42. /package/{esm2020 → esm2022}/transforms/geometry.mjs +0 -0
  43. /package/{esm2020 → esm2022}/transforms/index.mjs +0 -0
  44. /package/{esm2020 → esm2022}/transforms/line.mjs +0 -0
  45. /package/{esm2020 → esm2022}/utils/engine/diamond.mjs +0 -0
  46. /package/{esm2020 → esm2022}/utils/engine/ellipse.mjs +0 -0
  47. /package/{esm2020 → esm2022}/utils/engine/index.mjs +0 -0
  48. /package/{esm2020 → esm2022}/utils/engine/parallelogram.mjs +0 -0
  49. /package/{esm2020 → esm2022}/utils/engine/rectangle.mjs +0 -0
  50. /package/{esm2020 → esm2022}/utils/engine/round-rectangle.mjs +0 -0
  51. /package/{esm2020 → esm2022}/utils/geometry.mjs +0 -0
  52. /package/{esm2020 → esm2022}/utils/index.mjs +0 -0
  53. /package/{esm2020 → esm2022}/utils/line-arrow.mjs +0 -0
  54. /package/{esm2020 → esm2022}/utils/line.mjs +0 -0
  55. /package/{esm2020 → esm2022}/utils/position/geometry.mjs +0 -0
  56. /package/{esm2020 → esm2022}/utils/position/line.mjs +0 -0
  57. /package/{esm2020 → esm2022}/utils/selected.mjs +0 -0
  58. /package/{esm2020 → esm2022}/utils/style/index.mjs +0 -0
  59. /package/{esm2020 → esm2022}/utils/style/stroke.mjs +0 -0
@@ -1,1765 +0,0 @@
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, getElementById, 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
- import * as i0 from '@angular/core';
3
- import { Component, ChangeDetectionStrategy } from '@angular/core';
4
- import { Subject } from 'rxjs';
5
- import { getRectangleByPoints, getFactorByPoints, Direction, getDirectionByPoint, getPoints, getPointOnPolyline, getDirectionFactor, Generator, normalizeShapePoints, CommonPluginElement, ActiveGenerator, WithTextPluginKey, RESIZE_HANDLE_DIAMETER, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, getRectangleResizeHandleRefs, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint } from '@plait/common';
6
- import { Alignment, buildText, AlignEditor, TextManage, DEFAULT_FONT_SIZE, getTextFromClipboard, getTextSize } from '@plait/text';
7
- import { isKeyHotkey } from 'is-hotkey';
8
- import { Node } from 'slate';
9
-
10
- var GeometryShape;
11
- (function (GeometryShape) {
12
- GeometryShape["rectangle"] = "rectangle";
13
- GeometryShape["ellipse"] = "ellipse";
14
- GeometryShape["diamond"] = "diamond";
15
- GeometryShape["roundRectangle"] = "roundRectangle";
16
- GeometryShape["parallelogram"] = "parallelogram";
17
- GeometryShape["text"] = "text";
18
- })(GeometryShape || (GeometryShape = {}));
19
- const PlaitGeometry = {
20
- getTextEditor(element) {
21
- return PlaitGeometry.getTextManage(element).componentRef.instance.editor;
22
- },
23
- getTextManage(element) {
24
- const component = PlaitElement.getComponent(element);
25
- if (component) {
26
- return component.textManage;
27
- }
28
- throw new Error('can not get correctly component in get text editor');
29
- }
30
- };
31
-
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
- const ShapeDefaultSpace = {
106
- rectangleAndText: 4
107
- };
108
- const DefaultGeometryStyle = {
109
- strokeWidth: 2,
110
- defaultRadius: 4,
111
- strokeColor: '#000',
112
- fill: 'none'
113
- };
114
- const DefaultGeometryActiveStyle = {
115
- strokeWidth: ACTIVE_STROKE_WIDTH,
116
- selectionStrokeWidth: ACTIVE_STROKE_WIDTH
117
- };
118
- const DefaultGeometryProperty = {
119
- width: 100,
120
- height: 100,
121
- strokeColor: '#333',
122
- strokeWidth: 2
123
- };
124
- const DefaultTextProperty = {
125
- width: 36,
126
- height: 20,
127
- text: '文本'
128
- };
129
- const GeometryThreshold = {
130
- defaultTextMaxWidth: 34 * 14,
131
- };
132
-
133
- var DrawPointerType;
134
- (function (DrawPointerType) {
135
- DrawPointerType["text"] = "text";
136
- DrawPointerType["rectangle"] = "rectangle";
137
- DrawPointerType["line"] = "line";
138
- DrawPointerType["diamond"] = "diamond";
139
- DrawPointerType["roundRectangle"] = "roundRectangle";
140
- DrawPointerType["parallelogram"] = "parallelogram";
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
- ];
151
-
152
- const getStrokeWidthByElement = (element) => {
153
- if (PlaitDrawElement.isText(element)) {
154
- return 0;
155
- }
156
- const strokeWidth = element.strokeWidth || DefaultGeometryStyle.strokeWidth;
157
- return strokeWidth;
158
- };
159
- const getStrokeColorByElement = (element) => {
160
- const strokeColor = element.strokeColor || DefaultGeometryStyle.strokeColor;
161
- return strokeColor;
162
- };
163
- const getFillByElement = (element) => {
164
- const fill = element.fill || DefaultGeometryStyle.fill;
165
- return fill;
166
- };
167
- const getLineDashByElement = (element) => {
168
- return element.strokeStyle === 'dashed' ? [8, 8 + getStrokeWidthByElement(element)] : undefined;
169
- };
170
- const getStrokeStyleByElement = (element) => {
171
- return element.strokeStyle || StrokeStyle.solid;
172
- };
173
-
174
- const DiamondEngine = {
175
- draw(board, rectangle, options) {
176
- const points = RectangleClient.getEdgeCenterPoints(rectangle);
177
- const rs = PlaitBoard.getRoughSVG(board);
178
- const polygon = rs.polygon(points, Object.assign(Object.assign({}, options), { fillStyle: 'solid' }));
179
- setStrokeLinecap(polygon, 'round');
180
- return polygon;
181
- },
182
- isHit(rectangle, point) {
183
- const controlPoints = RectangleClient.getEdgeCenterPoints(rectangle);
184
- return isPointInPolygon(point, controlPoints);
185
- },
186
- getNearestPoint(rectangle, point) {
187
- const connectorPoints = RectangleClient.getEdgeCenterPoints(rectangle);
188
- return getNearestPointBetweenPointAndSegments(point, connectorPoints);
189
- },
190
- getConnectorPoints(rectangle) {
191
- return RectangleClient.getEdgeCenterPoints(rectangle);
192
- }
193
- };
194
-
195
- const EllipseEngine = {
196
- draw(board, rectangle, options) {
197
- const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
198
- const rs = PlaitBoard.getRoughSVG(board);
199
- return rs.ellipse(centerPoint[0], centerPoint[1], rectangle.width, rectangle.height, Object.assign(Object.assign({}, options), { fillStyle: 'solid' }));
200
- },
201
- isHit(rectangle, point) {
202
- const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
203
- return isPointInEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
204
- },
205
- getNearestPoint(rectangle, point) {
206
- const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2];
207
- return getNearestPointBetweenPointAndEllipse(point, centerPoint, rectangle.width / 2, rectangle.height / 2);
208
- },
209
- getConnectorPoints(rectangle) {
210
- return RectangleClient.getEdgeCenterPoints(rectangle);
211
- }
212
- };
213
- function getNearestPointBetweenPointAndEllipse(point, center, rx, ry, rotation = 0) {
214
- const rectangleClient = {
215
- x: center[0] - rx,
216
- y: center[1] - ry,
217
- height: ry * 2,
218
- width: rx * 2
219
- };
220
- // https://stackoverflow.com/a/46007540/232122
221
- const px = Math.abs(point[0] - rectangleClient.x - rectangleClient.width / 2);
222
- const py = Math.abs(point[1] - rectangleClient.y - rectangleClient.height / 2);
223
- let tx = 0.707;
224
- let ty = 0.707;
225
- const a = Math.abs(rectangleClient.width) / 2;
226
- const b = Math.abs(rectangleClient.height) / 2;
227
- [0, 1, 2, 3].forEach(x => {
228
- const xx = a * tx;
229
- const yy = b * ty;
230
- const ex = ((a * a - b * b) * Math.pow(tx, 3)) / a;
231
- const ey = ((b * b - a * a) * Math.pow(ty, 3)) / b;
232
- const rx = xx - ex;
233
- const ry = yy - ey;
234
- const qx = px - ex;
235
- const qy = py - ey;
236
- const r = Math.hypot(ry, rx);
237
- const q = Math.hypot(qy, qx);
238
- tx = Math.min(1, Math.max(0, ((qx * r) / q + ex) / a));
239
- ty = Math.min(1, Math.max(0, ((qy * r) / q + ey) / b));
240
- const t = Math.hypot(ty, tx);
241
- tx /= t;
242
- ty /= t;
243
- });
244
- const signX = point[0] > center[0] ? 1 : -1;
245
- const signY = point[1] > center[1] ? 1 : -1;
246
- return [center[0] + a * tx * signX, center[1] + b * ty * signY];
247
- }
248
-
249
- const ParallelogramEngine = {
250
- draw(board, rectangle, options) {
251
- const points = getParallelogramPoints(rectangle);
252
- const rs = PlaitBoard.getRoughSVG(board);
253
- const polygon = rs.polygon(points, Object.assign(Object.assign({}, options), { fillStyle: 'solid' }));
254
- setStrokeLinecap(polygon, 'round');
255
- return polygon;
256
- },
257
- isHit(rectangle, point) {
258
- const parallelogramPoints = getParallelogramPoints(rectangle);
259
- return isPointInPolygon(point, parallelogramPoints);
260
- },
261
- getNearestPoint(rectangle, point) {
262
- const cornerPoints = getParallelogramPoints(rectangle);
263
- return getNearestPointBetweenPointAndSegments(point, cornerPoints);
264
- },
265
- getConnectorPoints(rectangle) {
266
- const cornerPoints = getParallelogramPoints(rectangle);
267
- return getCenterPointsOnPolygon(cornerPoints);
268
- }
269
- };
270
- const getParallelogramPoints = (rectangle) => {
271
- return [
272
- [rectangle.x + rectangle.width / 4, rectangle.y],
273
- [rectangle.x + rectangle.width, rectangle.y],
274
- [rectangle.x + (rectangle.width * 3) / 4, rectangle.y + rectangle.height],
275
- [rectangle.x, rectangle.y + rectangle.height]
276
- ];
277
- };
278
-
279
- const RectangleEngine = {
280
- draw(board, rectangle, options) {
281
- return drawRectangle(board, rectangle, Object.assign(Object.assign({}, options), { fillStyle: 'solid' }));
282
- },
283
- isHit(rectangle, point) {
284
- const rangeRectangle = RectangleClient.toRectangleClient([point, point]);
285
- return RectangleClient.isHit(rectangle, rangeRectangle);
286
- },
287
- getNearestPoint(rectangle, point) {
288
- const cornerPoints = RectangleClient.getCornerPoints(rectangle);
289
- return getNearestPointBetweenPointAndSegments(point, cornerPoints);
290
- },
291
- getConnectorPoints(rectangle) {
292
- return RectangleClient.getEdgeCenterPoints(rectangle);
293
- }
294
- };
295
-
296
- const RoundRectangleEngine = {
297
- draw(board, rectangle, options) {
298
- return drawRoundRectangle(PlaitBoard.getRoughSVG(board), rectangle.x, rectangle.y, rectangle.x + rectangle.width, rectangle.y + rectangle.height, Object.assign(Object.assign({}, options), { fillStyle: 'solid' }), false, getRoundRectangleRadius(rectangle));
299
- },
300
- isHit(rectangle, point) {
301
- return isPointInRoundRectangle(point, rectangle, getRoundRectangleRadius(rectangle));
302
- },
303
- getNearestPoint(rectangle, point) {
304
- return getNearestPointBetweenPointAndRoundRectangle(point, rectangle, getRoundRectangleRadius(rectangle));
305
- },
306
- getConnectorPoints(rectangle) {
307
- return RectangleClient.getEdgeCenterPoints(rectangle);
308
- }
309
- };
310
- const getRoundRectangleRadius = (rectangle) => {
311
- return Math.min(rectangle.width * 0.1, rectangle.height * 0.1);
312
- };
313
- function getNearestPointBetweenPointAndRoundRectangle(point, rectangle, radius) {
314
- const { x: rectX, y: rectY, width, height } = rectangle;
315
- const cornerPoints = RectangleClient.getCornerPoints(rectangle);
316
- let result = getNearestPointBetweenPointAndSegments(point, cornerPoints);
317
- let circleCenter = null;
318
- const inLeftTop = point[0] >= rectX && point[0] <= rectX + radius && point[1] >= rectY && point[1] <= rectY + radius;
319
- if (inLeftTop) {
320
- circleCenter = [rectX + radius, rectY + radius];
321
- }
322
- const inLeftBottom = point[0] >= rectX && point[0] <= rectX + radius && point[1] >= rectY + height && point[1] <= rectY + height - radius;
323
- if (inLeftBottom) {
324
- circleCenter = [rectX + radius, rectY + height - radius];
325
- }
326
- const inRightTop = point[0] >= rectX + width - radius && point[0] <= rectX + width && point[1] >= rectY && point[1] <= rectY + radius;
327
- if (inRightTop) {
328
- circleCenter = [rectX + width - radius, rectY + radius];
329
- }
330
- const inRightBottom = point[0] >= rectX + width - radius &&
331
- point[0] <= rectX + width &&
332
- point[1] >= rectY + height - radius &&
333
- point[1] <= rectY + height;
334
- if (inRightBottom) {
335
- circleCenter = [rectX + width - radius, rectY + height - radius];
336
- }
337
- if (circleCenter) {
338
- result = getNearestPointBetweenPointAndEllipse(point, circleCenter, radius, radius);
339
- }
340
- return result;
341
- }
342
-
343
- const ShapeEngineMap = {
344
- [GeometryShape.rectangle]: RectangleEngine,
345
- [GeometryShape.diamond]: DiamondEngine,
346
- [GeometryShape.ellipse]: EllipseEngine,
347
- [GeometryShape.parallelogram]: ParallelogramEngine,
348
- [GeometryShape.roundRectangle]: RoundRectangleEngine,
349
- [GeometryShape.text]: RectangleEngine
350
- };
351
- const getEngine = (shape) => {
352
- return ShapeEngineMap[shape];
353
- };
354
-
355
- const createGeometryElement = (shape, points, text, options) => {
356
- let textOptions = {};
357
- let alignment = Alignment.center;
358
- if (shape === GeometryShape.text) {
359
- textOptions = { autoSize: true };
360
- alignment = undefined;
361
- }
362
- return Object.assign(Object.assign({ id: idCreator(), type: 'geometry', shape, angle: 0, opacity: 1, textHeight: DefaultTextProperty.height, text: buildText(text, alignment), points }, textOptions), options);
363
- };
364
- const getPointsByCenterPoint = (point, width, height) => {
365
- const leftTopPoint = [point[0] - width / 2, point[1] - height / 2];
366
- const rightBottomPoint = [point[0] + width / 2, point[1] + height / 2];
367
- return [leftTopPoint, rightBottomPoint];
368
- };
369
- const getTextRectangle = (element) => {
370
- const elementRectangle = getRectangleByPoints(element.points);
371
- const strokeWidth = getStrokeWidthByElement(element);
372
- const height = element.textHeight;
373
- const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
374
- return {
375
- height,
376
- width: width > 0 ? width : 0,
377
- x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
378
- y: elementRectangle.y + (elementRectangle.height - height) / 2
379
- };
380
- };
381
- const drawBoundMask = (board, element) => {
382
- const G = createG();
383
- const rectangle = getRectangleByPoints(element.points);
384
- const activeRectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
385
- const maskG = drawGeometry(board, activeRectangle, element.shape, {
386
- stroke: SELECTION_BORDER_COLOR,
387
- strokeWidth: 1,
388
- fill: SELECTION_FILL_COLOR,
389
- fillStyle: 'solid'
390
- });
391
- G.appendChild(maskG);
392
- const connectorPoints = getEngine(element.shape).getConnectorPoints(activeRectangle);
393
- connectorPoints.forEach(point => {
394
- const circleG = drawCircle(PlaitBoard.getRoughSVG(board), point, 6, {
395
- stroke: '#999999',
396
- strokeWidth: 1,
397
- fill: '#FFF',
398
- fillStyle: 'solid'
399
- });
400
- G.appendChild(circleG);
401
- });
402
- return G;
403
- };
404
- const drawGeometry = (board, outerRectangle, shape, options) => {
405
- return getEngine(shape).draw(board, outerRectangle, options);
406
- };
407
- const getNearestPoint = (element, point, inflateDelta = 0) => {
408
- const rectangle = getRectangleByPoints(element.points);
409
- const activeRectangle = RectangleClient.inflate(rectangle, inflateDelta);
410
- return getEngine(element.shape).getNearestPoint(activeRectangle, point);
411
- };
412
- const getCenterPointsOnPolygon = (points) => {
413
- const centerPoint = [];
414
- for (let i = 0; i < points.length; i++) {
415
- let j = i == points.length - 1 ? 0 : i + 1;
416
- centerPoint.push([(points[i][0] + points[j][0]) / 2, (points[i][1] + points[j][1]) / 2]);
417
- }
418
- return centerPoint;
419
- };
420
-
421
- const drawLineArrow = (element, points, options) => {
422
- const arrowG = createG();
423
- if (PlaitLine.isSourceMark(element, LineMarkerType.none) && PlaitLine.isTargetMark(element, LineMarkerType.none)) {
424
- return null;
425
- }
426
- if (!PlaitLine.isSourceMark(element, LineMarkerType.none)) {
427
- const sourceArrow = getArrow(element, element.source.marker, points[1], points[0], options);
428
- sourceArrow && arrowG.appendChild(sourceArrow);
429
- }
430
- if (!PlaitLine.isTargetMark(element, LineMarkerType.none)) {
431
- const arrow = getArrow(element, element.target.marker, points[points.length - 2], points[points.length - 1], options);
432
- arrow && arrowG.appendChild(arrow);
433
- }
434
- return arrowG;
435
- };
436
- const getArrow = (element, marker, source, target, options) => {
437
- let targetArrow;
438
- switch (marker) {
439
- case LineMarkerType.openTriangle: {
440
- targetArrow = drawOpenTriangle(element, source, target, options);
441
- break;
442
- }
443
- case LineMarkerType.solidTriangle: {
444
- targetArrow = drawSolidTriangle(source, target, options);
445
- break;
446
- }
447
- case LineMarkerType.arrow: {
448
- targetArrow = drawArrow(element, source, target, options);
449
- break;
450
- }
451
- case LineMarkerType.sharpArrow: {
452
- targetArrow = drawSharpArrow(source, target, options);
453
- break;
454
- }
455
- }
456
- return targetArrow;
457
- };
458
- const drawSharpArrow = (source, target, options) => {
459
- const directionFactor = getFactorByPoints(source, target);
460
- const startPoint = target;
461
- // const startPoint: Point = [
462
- // target[0],
463
- // target[1]
464
- // ];
465
- const { pointLeft, pointRight } = arrowPoints(source, target, 12, 20);
466
- const g = createG();
467
- const path = createPath();
468
- let polylinePath = `M${pointRight[0]},${pointRight[1]}A8,8,20,0,1,${pointLeft[0]},${pointLeft[1]}L${startPoint[0]},${startPoint[1]}Z`;
469
- path.setAttribute('d', polylinePath);
470
- path.setAttribute('stroke', `${options === null || options === void 0 ? void 0 : options.stroke}`);
471
- path.setAttribute('stroke-width', `${options === null || options === void 0 ? void 0 : options.strokeWidth}`);
472
- path.setAttribute('fill', `${options === null || options === void 0 ? void 0 : options.stroke}`);
473
- g.appendChild(path);
474
- return g;
475
- };
476
- const drawArrow = (element, source, target, options) => {
477
- const directionFactor = getFactorByPoints(source, target);
478
- const strokeWidth = getStrokeWidthByElement(element);
479
- const endPoint = [
480
- target[0] + strokeWidth * directionFactor.x / 2,
481
- target[1] + strokeWidth * directionFactor.y / 2
482
- ];
483
- const middlePoint = [endPoint[0] - 8 * directionFactor.x, endPoint[1] - 8 * directionFactor.y];
484
- const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 30);
485
- const arrowG = drawLinearPath([pointLeft, endPoint, pointRight, middlePoint], Object.assign(Object.assign({}, options), { fill: options.stroke }), true);
486
- const path = arrowG.querySelector('path');
487
- path.setAttribute('stroke-linejoin', 'round');
488
- return arrowG;
489
- };
490
- const drawSolidTriangle = (source, target, options) => {
491
- const endPoint = target;
492
- const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 30);
493
- return drawLinearPath([pointLeft, endPoint, pointRight], Object.assign(Object.assign({}, options), { fill: options.stroke }), true);
494
- };
495
- const drawOpenTriangle = (element, source, target, options) => {
496
- const directionFactor = getFactorByPoints(source, target);
497
- const strokeWidth = getStrokeWidthByElement(element);
498
- const endPoint = [
499
- target[0] + strokeWidth * directionFactor.x / 2,
500
- target[1] + strokeWidth * directionFactor.y / 2
501
- ];
502
- const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 40);
503
- return drawLinearPath([pointLeft, endPoint, pointRight], options);
504
- };
505
-
506
- const createLineElement = (shape, points, source, target, options) => {
507
- return Object.assign({ id: idCreator(), type: 'line', shape,
508
- source, texts: [], target, opacity: 1, points }, options);
509
- };
510
- const getLinePoints = (board, element) => {
511
- return element.shape === LineShape.elbow ? getElbowPoints(board, element) : getStraightPoints(board, element);
512
- };
513
- const getStraightPoints = (board, element) => {
514
- return [getSourcePoint(board, element), getTargetPoint(board, element)];
515
- };
516
- const getElbowPoints = (board, element) => {
517
- if (element.points.length === 2) {
518
- const source = getSourcePoint(board, element);
519
- const target = getTargetPoint(board, element);
520
- let sourceDirection = source[0] < target[0] ? Direction.right : Direction.left;
521
- let targetDirection = source[0] < target[0] ? Direction.left : Direction.right;
522
- if (element.source.connection) {
523
- sourceDirection = getDirectionByPoint(element.source.connection, sourceDirection);
524
- }
525
- if (element.target.connection) {
526
- targetDirection = getDirectionByPoint(element.target.connection, targetDirection);
527
- }
528
- const points = getPoints(source, sourceDirection, target, targetDirection, 30);
529
- return points;
530
- }
531
- return element.points;
532
- };
533
- const isHitPolyLine = (pathPoints, point, strokeWidth, expand = 0) => {
534
- const distance = distanceBetweenPointAndSegments(pathPoints, point);
535
- return distance <= strokeWidth + expand;
536
- };
537
- const getHitLineTextIndex = (board, element, point) => {
538
- const texts = element.texts;
539
- if (!texts.length)
540
- return -1;
541
- const points = getElbowPoints(board, element);
542
- return texts.findIndex(text => {
543
- const center = getPointOnPolyline(points, text.position);
544
- const rectangle = {
545
- x: center[0] - text.width / 2,
546
- y: center[1] - text.height / 2,
547
- width: text.width,
548
- height: text.height
549
- };
550
- return RectangleClient.isHit(rectangle, RectangleClient.toRectangleClient([point, point]));
551
- });
552
- };
553
- const isHitLineText = (board, element, point) => {
554
- return getHitLineTextIndex(board, element, point) !== -1;
555
- };
556
- const drawLine = (board, element) => {
557
- const strokeWidth = getStrokeWidthByElement(element);
558
- const strokeColor = getStrokeColorByElement(element);
559
- const strokeLineDash = getLineDashByElement(element);
560
- const options = { stroke: strokeColor, strokeWidth, strokeLineDash };
561
- const lineG = createG();
562
- const points = getLinePoints(board, element);
563
- const line = drawLinearPath(points, options);
564
- const id = idCreator();
565
- line.setAttribute('mask', `url(#${id})`);
566
- lineG.appendChild(line);
567
- const { mask, maskTargetFillRect } = drawMask(board, element, id);
568
- lineG.appendChild(mask);
569
- line.appendChild(maskTargetFillRect);
570
- const arrow = drawLineArrow(element, points, { stroke: strokeColor, strokeWidth });
571
- arrow && lineG.appendChild(arrow);
572
- return lineG;
573
- };
574
- function drawMask(board, element, id) {
575
- const mask = createMask();
576
- mask.setAttribute('id', id);
577
- const points = getLinePoints(board, element);
578
- let rectangle = getRectangleByPoints(points);
579
- rectangle = RectangleClient.getOutlineRectangle(rectangle, -30);
580
- const maskFillRect = createRect(rectangle, {
581
- fill: 'white'
582
- });
583
- mask.appendChild(maskFillRect);
584
- const texts = element.texts;
585
- texts.forEach((text, index) => {
586
- const textRectangle = getLineTextRectangle(board, element, index);
587
- const rect = createRect(textRectangle, {
588
- fill: 'black'
589
- });
590
- mask.appendChild(rect);
591
- });
592
- //撑开 line
593
- const maskTargetFillRect = createRect(rectangle);
594
- maskTargetFillRect.setAttribute('opacity', '0');
595
- return { mask, maskTargetFillRect };
596
- }
597
- const getSourcePoint = (board, element) => {
598
- if (element.source.boundId) {
599
- const strokeWidth = getStrokeWidthByElement(element);
600
- const connectionOffset = PlaitLine.isSourceMark(element, LineMarkerType.none) ? 0 : strokeWidth;
601
- const boundElement = getElementById(board, element.source.boundId);
602
- return boundElement ? getConnectionPoint(boundElement, element.source.connection, connectionOffset) : element.points[0];
603
- }
604
- return element.points[0];
605
- };
606
- const getTargetPoint = (board, element) => {
607
- if (element.target.boundId) {
608
- const strokeWidth = getStrokeWidthByElement(element);
609
- const connectionOffset = PlaitLine.isTargetMark(element, LineMarkerType.none) ? 0 : strokeWidth;
610
- const boundElement = getElementById(board, element.target.boundId);
611
- return boundElement
612
- ? getConnectionPoint(boundElement, element.target.connection, connectionOffset)
613
- : element.points[element.points.length - 1];
614
- }
615
- return element.points[element.points.length - 1];
616
- };
617
- const getConnectionPoint = (geometry, connection, offset) => {
618
- const rectangle = getRectangleByPoints(geometry.points);
619
- const directionFactor = getDirectionFactor(getDirectionByPoint(connection, Direction.bottom));
620
- return [
621
- rectangle.x + rectangle.width * connection[0] + directionFactor.x * offset,
622
- rectangle.y + rectangle.height * connection[1] + directionFactor.y * offset
623
- ];
624
- };
625
- const transformPointToConnection = (board, point, hitElement) => {
626
- let rectangle = getRectangleByPoints(hitElement.points);
627
- rectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
628
- let nearestPoint = getNearestPoint(hitElement, point, ACTIVE_STROKE_WIDTH);
629
- const hitConnector = getHitConnectorPoint(nearestPoint, hitElement, rectangle);
630
- nearestPoint = hitConnector ? hitConnector : nearestPoint;
631
- return [(nearestPoint[0] - rectangle.x) / rectangle.width, (nearestPoint[1] - rectangle.y) / rectangle.height];
632
- };
633
- const getHitConnectorPoint = (movingPoint, hitElement, rectangle) => {
634
- const connector = getEngine(hitElement.shape).getConnectorPoints(rectangle);
635
- const points = getPointsByCenterPoint(movingPoint, 5, 5);
636
- const pointRectangle = getRectangleByPoints(points);
637
- return connector.find(point => {
638
- return RectangleClient.isHit(pointRectangle, RectangleClient.toRectangleClient([point, point]));
639
- });
640
- };
641
- const getLineTextRectangle = (board, element, index) => {
642
- const text = element.texts[index];
643
- const elbowPoints = getLinePoints(board, element);
644
- const point = getPointOnPolyline(elbowPoints, text.position);
645
- return {
646
- x: point[0] - text.width / 2,
647
- y: point[1] - text.height / 2,
648
- width: text.width,
649
- height: text.height
650
- };
651
- };
652
- const getBoardLines = (board) => {
653
- return findElements(board, {
654
- match: (element) => PlaitDrawElement.isLine(element),
655
- recursion: (element) => PlaitDrawElement.isDrawElement(element)
656
- });
657
- };
658
-
659
- const getSelectedDrawElements = (board) => {
660
- const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isDrawElement(value));
661
- return selectedElements;
662
- };
663
- const getSelectedGeometryElements = (board) => {
664
- const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isGeometry(value));
665
- return selectedElements;
666
- };
667
- const getSelectedLineElements = (board) => {
668
- const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isLine(value));
669
- return selectedElements;
670
- };
671
-
672
- class GeometryShapeGenerator extends Generator {
673
- canDraw(element, data) {
674
- return true;
675
- }
676
- baseDraw(element, data) {
677
- const rectangle = getRectangleByPoints(element.points);
678
- const shape = element.shape;
679
- if (shape === GeometryShape.text) {
680
- return;
681
- }
682
- const strokeWidth = getStrokeWidthByElement(element);
683
- const strokeColor = getStrokeColorByElement(element);
684
- const fill = getFillByElement(element);
685
- const strokeLineDash = getLineDashByElement(element);
686
- return drawGeometry(this.board, RectangleClient.inflate(rectangle, -strokeWidth), shape, { stroke: strokeColor, strokeWidth, fill, strokeLineDash });
687
- }
688
- }
689
-
690
- const insertGeometry = (board, points, shape) => {
691
- let newElement = createGeometryElement(shape, points, '', {
692
- strokeColor: DefaultGeometryProperty.strokeColor,
693
- strokeWidth: DefaultGeometryProperty.strokeWidth
694
- });
695
- Transforms.insertNode(board, newElement, [board.children.length]);
696
- clearSelectedElement(board);
697
- addSelectedElement(board, newElement);
698
- };
699
- const insertText = (board, points, text = '文本') => {
700
- let newElement = createGeometryElement(GeometryShape.text, points, text);
701
- Transforms.insertNode(board, newElement, [board.children.length]);
702
- clearSelectedElement(board);
703
- addSelectedElement(board, newElement);
704
- };
705
- const resizeGeometry = (board, points, textHeight, path) => {
706
- const normalizePoints = normalizeShapePoints(points);
707
- const element = PlaitNode.get(board, path);
708
- const newHeight = textHeight / board.viewport.zoom;
709
- const newProperties = { points: normalizePoints, textHeight: newHeight };
710
- if (PlaitDrawElement.isText(element) && element.autoSize) {
711
- newProperties.autoSize = false;
712
- }
713
- Transforms.setNode(board, newProperties, path);
714
- };
715
-
716
- const normalizePoints = (board, element, width, textHeight) => {
717
- let points = element.points;
718
- let autoSize = element.autoSize;
719
- const defaultSpace = ShapeDefaultSpace.rectangleAndText;
720
- if (autoSize) {
721
- const editor = PlaitGeometry.getTextEditor(element);
722
- if (AlignEditor.isActive(editor, Alignment.right)) {
723
- points = [
724
- [points[1][0] - (width + defaultSpace * 2), points[0][1]],
725
- [points[1][0], points[0][1] + textHeight]
726
- ];
727
- }
728
- else if (AlignEditor.isActive(editor, Alignment.center)) {
729
- const oldWidth = Math.abs(points[0][0] - points[1][0]);
730
- const offset = (width - oldWidth) / 2;
731
- points = [
732
- [points[0][0] - offset - defaultSpace, points[0][1]],
733
- [points[1][0] + offset + defaultSpace, points[0][1] + textHeight]
734
- ];
735
- }
736
- else {
737
- points = [points[0], [points[0][0] + width + defaultSpace * 2, points[0][1] + textHeight]];
738
- }
739
- }
740
- return { points };
741
- };
742
- const setText = (board, element, text, width, textHeight) => {
743
- const newElement = Object.assign({ text,
744
- textHeight }, normalizePoints(board, element, width, textHeight));
745
- const path = board.children.findIndex(child => child === element);
746
- Transforms.setNode(board, newElement, [path]);
747
- };
748
- const setTextSize = (board, element, textWidth, textHeight) => {
749
- if (element.autoSize) {
750
- const newElement = Object.assign({ textHeight }, normalizePoints(board, element, textWidth, textHeight));
751
- const isPointsEqual = Point.isEquals(element.points[0], newElement.points[0]) && Point.isEquals(element.points[1], newElement.points[1]);
752
- const isTextHeightEqual = Math.round(textHeight) === Math.round(element.textHeight);
753
- if (!isPointsEqual || !isTextHeightEqual) {
754
- const path = board.children.findIndex(child => child === element);
755
- Transforms.setNode(board, newElement, [path]);
756
- }
757
- }
758
- };
759
-
760
- const resizeLine = (board, options, path) => {
761
- Transforms.setNode(board, options, path);
762
- };
763
- const setLineTexts = (board, element, texts) => {
764
- const path = PlaitBoard.findPath(board, element);
765
- Transforms.setNode(board, { texts }, path);
766
- };
767
- const removeLineText = (board, element, index) => {
768
- var _a;
769
- const path = PlaitBoard.findPath(board, element);
770
- const texts = ((_a = element.texts) === null || _a === void 0 ? void 0 : _a.length) ? [...element.texts] : [];
771
- const newTexts = [...texts];
772
- newTexts.splice(index, 1);
773
- Transforms.setNode(board, { texts: newTexts }, path);
774
- };
775
- const setLineMark = (board, element, handleKey, marker) => {
776
- const path = PlaitBoard.findPath(board, element);
777
- let handle = handleKey === LineHandleKey.source ? element.source : element.target;
778
- handle = Object.assign(Object.assign({}, handle), { marker });
779
- Transforms.setNode(board, { [handleKey]: handle }, path);
780
- };
781
-
782
- const DrawTransforms = {
783
- setText,
784
- insertGeometry,
785
- resizeGeometry,
786
- insertText,
787
- setTextSize,
788
- resizeLine,
789
- setLineTexts,
790
- removeLineText,
791
- setLineMark
792
- };
793
-
794
- class GeometryComponent extends CommonPluginElement {
795
- get textManage() {
796
- return this.getTextManages()[0];
797
- }
798
- constructor(viewContainerRef, cdr) {
799
- super(cdr);
800
- this.viewContainerRef = viewContainerRef;
801
- this.cdr = cdr;
802
- this.destroy$ = new Subject();
803
- }
804
- initializeGenerator() {
805
- this.activeGenerator = new ActiveGenerator(this.board, {
806
- getStrokeWidth: () => {
807
- const selectedElements = getSelectedElements(this.board);
808
- if (selectedElements.length === 1 && !isSelectionMoving(this.board)) {
809
- return DefaultGeometryActiveStyle.strokeWidth;
810
- }
811
- else {
812
- return DefaultGeometryActiveStyle.selectionStrokeWidth;
813
- }
814
- },
815
- getStrokeOpacity: () => {
816
- const selectedElements = getSelectedElements(this.board);
817
- if (selectedElements.length === 1 && !isSelectionMoving(this.board)) {
818
- return 1;
819
- }
820
- else {
821
- return 0.5;
822
- }
823
- },
824
- getRectangle: (element) => {
825
- return getRectangleByPoints(element.points);
826
- },
827
- hasResizeHandle: () => {
828
- const selectedElements = getSelectedElements(this.board);
829
- if (PlaitBoard.hasBeenTextEditing(this.board) && PlaitDrawElement.isText(this.element)) {
830
- return false;
831
- }
832
- return selectedElements.length === 1 && !isSelectionMoving(this.board);
833
- }
834
- });
835
- this.shapeGenerator = new GeometryShapeGenerator(this.board);
836
- this.initializeTextManage();
837
- }
838
- ngOnInit() {
839
- super.ngOnInit();
840
- this.initializeGenerator();
841
- this.shapeGenerator.draw(this.element, this.g);
842
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
843
- this.drawText();
844
- }
845
- onContextChanged(value, previous) {
846
- if (value.element !== previous.element) {
847
- this.shapeGenerator.draw(this.element, this.g);
848
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
849
- this.updateText();
850
- }
851
- else {
852
- const hasSameSelected = value.selected === previous.selected;
853
- const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
854
- if (!hasSameSelected || !hasSameHandleState) {
855
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
856
- }
857
- }
858
- }
859
- editText() {
860
- this.textManage.edit();
861
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
862
- }
863
- drawText() {
864
- this.textManage.draw(this.element.text);
865
- this.g.append(this.textManage.g);
866
- }
867
- updateText() {
868
- this.textManage.updateText(this.element.text);
869
- this.textManage.updateRectangle();
870
- }
871
- initializeTextManage() {
872
- const plugins = this.board.getPluginOptions(WithTextPluginKey).textPlugins;
873
- const manage = new TextManage(this.board, this.viewContainerRef, {
874
- getRectangle: () => {
875
- return getTextRectangle(this.element);
876
- },
877
- onValueChangeHandle: (textManageRef) => {
878
- const height = textManageRef.height / this.board.viewport.zoom;
879
- const width = textManageRef.width / this.board.viewport.zoom;
880
- if (textManageRef.newValue) {
881
- DrawTransforms.setText(this.board, this.element, textManageRef.newValue, width, height);
882
- }
883
- else {
884
- DrawTransforms.setTextSize(this.board, this.element, width, height);
885
- }
886
- },
887
- getMaxWidth: () => {
888
- var _a;
889
- const width = getTextRectangle(this.element).width;
890
- return ((_a = this.element) === null || _a === void 0 ? void 0 : _a.autoSize) ? GeometryThreshold.defaultTextMaxWidth : width;
891
- },
892
- textPlugins: plugins
893
- });
894
- this.initializeTextManages([manage]);
895
- }
896
- ngOnDestroy() {
897
- super.ngOnDestroy();
898
- this.textManage.destroy();
899
- this.destroy$.next();
900
- this.destroy$.complete();
901
- }
902
- }
903
- GeometryComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: GeometryComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
904
- GeometryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: GeometryComponent, selector: "plait-draw-geometry", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
905
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: GeometryComponent, decorators: [{
906
- type: Component,
907
- args: [{
908
- selector: 'plait-draw-geometry',
909
- template: ``,
910
- changeDetection: ChangeDetectionStrategy.OnPush
911
- }]
912
- }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
913
-
914
- class LineShapeGenerator extends Generator {
915
- canDraw(element, data) {
916
- return true;
917
- }
918
- baseDraw(element, data) {
919
- const shape = element.shape;
920
- let lineG;
921
- switch (shape) {
922
- case LineShape.elbow:
923
- case LineShape.straight:
924
- lineG = drawLine(this.board, element);
925
- break;
926
- default:
927
- break;
928
- }
929
- return lineG;
930
- }
931
- }
932
-
933
- class LineActiveGenerator extends Generator {
934
- canDraw(element, data) {
935
- if (data.selected) {
936
- return true;
937
- }
938
- else {
939
- return false;
940
- }
941
- }
942
- baseDraw(element, data) {
943
- const activeG = createG();
944
- activeG.classList.add('active');
945
- activeG.classList.add('line-handle');
946
- const sourcePoint = getSourcePoint(this.board, element);
947
- const targetPoint = getTargetPoint(this.board, element);
948
- const sourceCircle = drawCircle(PlaitBoard.getRoughSVG(this.board), sourcePoint, RESIZE_HANDLE_DIAMETER, {
949
- stroke: '#999999',
950
- strokeWidth: 1,
951
- fill: '#FFF',
952
- fillStyle: 'solid'
953
- });
954
- const targetCircle = drawCircle(PlaitBoard.getRoughSVG(this.board), targetPoint, RESIZE_HANDLE_DIAMETER, {
955
- stroke: '#999999',
956
- strokeWidth: 1,
957
- fill: '#FFF',
958
- fillStyle: 'solid'
959
- });
960
- activeG.appendChild(targetCircle);
961
- activeG.appendChild(sourceCircle);
962
- return activeG;
963
- }
964
- }
965
-
966
- class LineComponent extends PlaitPluginElementComponent {
967
- constructor(viewContainerRef, cdr) {
968
- super(cdr);
969
- this.viewContainerRef = viewContainerRef;
970
- this.cdr = cdr;
971
- this.destroy$ = new Subject();
972
- this.textManages = [];
973
- this.boundedElements = {};
974
- }
975
- initializeGenerator() {
976
- this.shapeGenerator = new LineShapeGenerator(this.board);
977
- this.activeGenerator = new LineActiveGenerator(this.board);
978
- this.initializeTextManages();
979
- }
980
- ngOnInit() {
981
- this.initializeGenerator();
982
- this.shapeGenerator.draw(this.element, this.g);
983
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
984
- super.ngOnInit();
985
- this.boundedElements = this.getBoundedElements();
986
- this.drawText();
987
- }
988
- getBoundedElements() {
989
- const boundedElements = {};
990
- if (this.element.source.boundId) {
991
- const boundElement = getElementById(this.board, this.element.source.boundId);
992
- if (boundElement) {
993
- boundedElements.source = boundElement;
994
- }
995
- }
996
- if (this.element.target.boundId) {
997
- const boundElement = getElementById(this.board, this.element.target.boundId);
998
- if (boundElement) {
999
- boundedElements.target = boundElement;
1000
- }
1001
- }
1002
- return boundedElements;
1003
- }
1004
- onContextChanged(value, previous) {
1005
- const boundedElements = this.getBoundedElements();
1006
- const isBoundedElementsChanged = boundedElements.source !== this.boundedElements.source || boundedElements.target !== this.boundedElements.target;
1007
- this.boundedElements = boundedElements;
1008
- if (value.element !== previous.element) {
1009
- this.shapeGenerator.draw(this.element, this.g);
1010
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
1011
- this.updateText(previous.element.texts, value.element.texts);
1012
- this.updateTextRectangle();
1013
- }
1014
- if (isBoundedElementsChanged) {
1015
- this.shapeGenerator.draw(this.element, this.g);
1016
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
1017
- this.updateTextRectangle();
1018
- return;
1019
- }
1020
- const hasSameSelected = value.selected === previous.selected;
1021
- if (!hasSameSelected) {
1022
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
1023
- }
1024
- }
1025
- initializeTextManages() {
1026
- var _a;
1027
- if ((_a = this.element.texts) === null || _a === void 0 ? void 0 : _a.length) {
1028
- this.element.texts.forEach((text, index) => {
1029
- const manage = this.createTextManage(text, index);
1030
- this.textManages.push(manage);
1031
- });
1032
- }
1033
- }
1034
- destroyTextManages() {
1035
- this.textManages.forEach(manage => {
1036
- manage.destroy();
1037
- });
1038
- }
1039
- drawText() {
1040
- var _a;
1041
- if ((_a = this.element.texts) === null || _a === void 0 ? void 0 : _a.length) {
1042
- this.textManages.forEach((manage, index) => {
1043
- manage.draw(this.element.texts[index].text);
1044
- this.g.append(manage.g);
1045
- });
1046
- }
1047
- }
1048
- createTextManage(text, index) {
1049
- return new TextManage(this.board, this.viewContainerRef, {
1050
- getRectangle: () => {
1051
- return getLineTextRectangle(this.board, this.element, index);
1052
- },
1053
- onValueChangeHandle: (textManageRef) => {
1054
- const height = textManageRef.height / this.board.viewport.zoom;
1055
- const width = textManageRef.width / this.board.viewport.zoom;
1056
- const texts = [...this.element.texts];
1057
- texts.splice(index, 1, {
1058
- text: textManageRef.newValue ? textManageRef.newValue : this.element.texts[index].text,
1059
- position: this.element.texts[index].position,
1060
- width,
1061
- height
1062
- });
1063
- DrawTransforms.setLineTexts(this.board, this.element, texts);
1064
- },
1065
- getMaxWidth: () => GeometryThreshold.defaultTextMaxWidth
1066
- });
1067
- }
1068
- updateText(previousTexts, currentTexts) {
1069
- if (previousTexts === currentTexts)
1070
- return;
1071
- const previousTextsLength = previousTexts.length;
1072
- const currentTextsLength = currentTexts.length;
1073
- if (currentTextsLength === previousTextsLength) {
1074
- for (let i = 0; i < previousTextsLength; i++) {
1075
- if (previousTexts[i].text !== currentTexts[i].text) {
1076
- this.textManages[i].updateText(currentTexts[i].text);
1077
- }
1078
- }
1079
- }
1080
- else {
1081
- this.destroyTextManages();
1082
- this.textManages = [];
1083
- this.initializeTextManages();
1084
- this.drawText();
1085
- }
1086
- }
1087
- updateTextRectangle() {
1088
- this.textManages.forEach(manage => {
1089
- manage.updateRectangle();
1090
- });
1091
- }
1092
- ngOnDestroy() {
1093
- super.ngOnDestroy();
1094
- this.activeGenerator.destroy();
1095
- this.destroy$.next();
1096
- this.destroy$.complete();
1097
- }
1098
- }
1099
- LineComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: LineComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1100
- LineComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: LineComponent, selector: "plait-draw-line", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1101
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: LineComponent, decorators: [{
1102
- type: Component,
1103
- args: [{
1104
- selector: 'plait-draw-line',
1105
- template: ``,
1106
- changeDetection: ChangeDetectionStrategy.OnPush
1107
- }]
1108
- }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
1109
-
1110
- const withDrawHotkey = (board) => {
1111
- const { keydown, dblclick } = board;
1112
- board.keydown = (event) => {
1113
- const selectedElements = getSelectedElements(board);
1114
- const isSingleSelection = selectedElements.length === 1;
1115
- const targetElement = selectedElements[0];
1116
- if (!isVirtualKey(event) &&
1117
- !isDelete(event) &&
1118
- !isSpaceHotkey(event) &&
1119
- isSingleSelection &&
1120
- PlaitDrawElement.isGeometry(targetElement)) {
1121
- event.preventDefault();
1122
- PlaitElement.getComponent(targetElement).editText();
1123
- return;
1124
- }
1125
- keydown(event);
1126
- };
1127
- board.dblclick = (event) => {
1128
- event.preventDefault();
1129
- const geometries = getSelectedGeometryElements(board);
1130
- if (geometries.length === 1) {
1131
- const component = PlaitElement.getComponent(geometries[0]);
1132
- component.editText();
1133
- }
1134
- dblclick(event);
1135
- };
1136
- return board;
1137
- };
1138
-
1139
- const withGeometryCreateByDrag = (board) => {
1140
- const { pointerMove, pointerUp } = board;
1141
- let geometryShapeG = null;
1142
- board.pointerMove = (event) => {
1143
- geometryShapeG === null || geometryShapeG === void 0 ? void 0 : geometryShapeG.remove();
1144
- geometryShapeG = createG();
1145
- const geometryGenerator = new GeometryShapeGenerator(board);
1146
- const isGeometryPointer = PlaitBoard.isInPointer(board, GeometryPointer);
1147
- const dragMode = isGeometryPointer && isDndMode(board);
1148
- const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1149
- const pointer = PlaitBoard.getPointer(board);
1150
- if (dragMode) {
1151
- const points = getDefaultGeometryPoints(pointer, movingPoint);
1152
- if (pointer === DrawPointerType.text) {
1153
- const textG = getTemporaryTextG(movingPoint);
1154
- geometryShapeG.appendChild(textG);
1155
- PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1156
- }
1157
- else {
1158
- const temporaryElement = createGeometryElement(pointer, points, '', {
1159
- strokeColor: DefaultGeometryProperty.strokeColor,
1160
- strokeWidth: DefaultGeometryProperty.strokeWidth
1161
- });
1162
- geometryGenerator.draw(temporaryElement, geometryShapeG);
1163
- PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1164
- }
1165
- }
1166
- pointerMove(event);
1167
- };
1168
- board.pointerUp = (event) => {
1169
- const pointer = PlaitBoard.getPointer(board);
1170
- const isGeometryPointer = PlaitBoard.isInPointer(board, GeometryPointer);
1171
- const dragMode = isGeometryPointer && isDndMode(board);
1172
- if (dragMode) {
1173
- const targetPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1174
- const points = getDefaultGeometryPoints(pointer, targetPoint);
1175
- if (pointer === DrawPointerType.text) {
1176
- DrawTransforms.insertText(board, points);
1177
- }
1178
- else {
1179
- DrawTransforms.insertGeometry(board, points, pointer);
1180
- }
1181
- BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1182
- }
1183
- geometryShapeG === null || geometryShapeG === void 0 ? void 0 : geometryShapeG.remove();
1184
- geometryShapeG = null;
1185
- preventTouchMove(board, event, false);
1186
- pointerUp(event);
1187
- };
1188
- return board;
1189
- };
1190
- const withGeometryCreateByDraw = (board) => {
1191
- const { pointerDown, pointerMove, pointerUp, keydown, keyup } = board;
1192
- let start = null;
1193
- let geometryShapeG = null;
1194
- let temporaryElement = null;
1195
- let isShift = false;
1196
- board.keydown = (event) => {
1197
- isShift = isKeyHotkey('shift', event);
1198
- keydown(event);
1199
- };
1200
- board.keyup = (event) => {
1201
- isShift = false;
1202
- keyup(event);
1203
- };
1204
- board.pointerDown = (event) => {
1205
- const isGeometryPointer = PlaitBoard.isInPointer(board, GeometryPointer);
1206
- if (isGeometryPointer && isDrawingMode(board)) {
1207
- const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1208
- start = point;
1209
- const pointer = PlaitBoard.getPointer(board);
1210
- preventTouchMove(board, event, true);
1211
- if (pointer === DrawPointerType.text) {
1212
- const points = getDefaultGeometryPoints(pointer, point);
1213
- const textElement = createGeometryElement(GeometryShape.text, points, DefaultTextProperty.text);
1214
- Transforms.insertNode(board, textElement, [board.children.length]);
1215
- clearSelectedElement(board);
1216
- addSelectedElement(board, textElement);
1217
- BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1218
- start = null;
1219
- }
1220
- }
1221
- pointerDown(event);
1222
- };
1223
- board.pointerMove = (event) => {
1224
- geometryShapeG === null || geometryShapeG === void 0 ? void 0 : geometryShapeG.remove();
1225
- geometryShapeG = createG();
1226
- const geometryGenerator = new GeometryShapeGenerator(board);
1227
- const drawMode = !!start;
1228
- const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1229
- const pointer = PlaitBoard.getPointer(board);
1230
- if (drawMode && pointer !== DrawPointerType.text) {
1231
- const points = normalizeShapePoints([start, movingPoint], isShift);
1232
- temporaryElement = createGeometryElement(pointer, points, '', {
1233
- strokeColor: DefaultGeometryProperty.strokeColor,
1234
- strokeWidth: DefaultGeometryProperty.strokeWidth
1235
- });
1236
- geometryGenerator.draw(temporaryElement, geometryShapeG);
1237
- PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1238
- }
1239
- pointerMove(event);
1240
- };
1241
- board.pointerUp = (event) => {
1242
- const isDrawMode = !!start;
1243
- if (isDrawMode) {
1244
- const targetPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1245
- const { width, height } = RectangleClient.toRectangleClient([start, targetPoint]);
1246
- if (Math.hypot(width, height) === 0) {
1247
- const pointer = PlaitBoard.getPointer(board);
1248
- const points = getDefaultGeometryPoints(pointer, targetPoint);
1249
- if (pointer !== DrawPointerType.text) {
1250
- temporaryElement = createGeometryElement(pointer, points, '', {
1251
- strokeColor: DefaultGeometryProperty.strokeColor,
1252
- strokeWidth: DefaultGeometryProperty.strokeWidth
1253
- });
1254
- }
1255
- }
1256
- }
1257
- if (temporaryElement) {
1258
- Transforms.insertNode(board, temporaryElement, [board.children.length]);
1259
- clearSelectedElement(board);
1260
- addSelectedElement(board, temporaryElement);
1261
- BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1262
- }
1263
- geometryShapeG === null || geometryShapeG === void 0 ? void 0 : geometryShapeG.remove();
1264
- geometryShapeG = null;
1265
- start = null;
1266
- temporaryElement = null;
1267
- preventTouchMove(board, event, false);
1268
- pointerUp(event);
1269
- };
1270
- return board;
1271
- };
1272
- const getDefaultGeometryPoints = (pointer, targetPoint) => {
1273
- return pointer === DrawPointerType.text
1274
- ? getPointsByCenterPoint(targetPoint, DefaultTextProperty.width, DefaultTextProperty.height)
1275
- : getPointsByCenterPoint(targetPoint, DefaultGeometryProperty.width, DefaultGeometryProperty.height);
1276
- };
1277
- const getTemporaryTextG = (movingPoint) => {
1278
- const textG = createG();
1279
- const width = DefaultTextProperty.width - ShapeDefaultSpace.rectangleAndText * 2;
1280
- const foreignObject = createForeignObject(movingPoint[0] - width / 2, movingPoint[1] - DefaultTextProperty.height / 2, width, DefaultTextProperty.height);
1281
- const richtext = document.createElement('div');
1282
- richtext.textContent = DefaultTextProperty.text;
1283
- richtext.style.fontSize = `${DEFAULT_FONT_SIZE}px`;
1284
- richtext.style.cursor = 'default';
1285
- foreignObject.appendChild(richtext);
1286
- textG.appendChild(foreignObject);
1287
- return textG;
1288
- };
1289
-
1290
- const buildClipboardData = (board, elements, startPoint) => {
1291
- return elements.map(element => {
1292
- if (PlaitDrawElement.isGeometry(element)) {
1293
- const points = element.points.map(point => [point[0] - startPoint[0], point[1] - startPoint[1]]);
1294
- return Object.assign(Object.assign({}, element), { points });
1295
- }
1296
- if (PlaitDrawElement.isLine(element)) {
1297
- let source = Object.assign({}, element.source);
1298
- let target = Object.assign({}, element.target);
1299
- if (element.source.boundId && !getElementById(board, element.source.boundId, elements)) {
1300
- delete source.boundId;
1301
- delete source.connection;
1302
- }
1303
- if (element.target.boundId && !getElementById(board, element.target.boundId, elements)) {
1304
- delete target.boundId;
1305
- delete target.connection;
1306
- }
1307
- const points = element.points.map(point => [point[0] - startPoint[0], point[1] - startPoint[1]]);
1308
- return Object.assign(Object.assign({}, element), { points, source, target });
1309
- }
1310
- return element;
1311
- });
1312
- };
1313
- const insertClipboardData = (board, elements, startPoint) => {
1314
- const lines = elements.filter(value => PlaitDrawElement.isLine(value));
1315
- const geometries = elements.filter(value => PlaitDrawElement.isGeometry(value));
1316
- geometries.forEach(element => {
1317
- const sourceLines = [];
1318
- const targetLines = [];
1319
- lines.forEach(line => {
1320
- if (PlaitLine.isBoundElementOfSource(line, element)) {
1321
- sourceLines.push(line);
1322
- }
1323
- if (PlaitLine.isBoundElementOfTarget(line, element)) {
1324
- targetLines.push(line);
1325
- }
1326
- });
1327
- element.id = idCreator();
1328
- // update lines
1329
- sourceLines.forEach(sourceLine => (sourceLine.source.boundId = element.id));
1330
- targetLines.forEach(targetLine => (targetLine.target.boundId = element.id));
1331
- element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
1332
- Transforms.insertNode(board, element, [board.children.length]);
1333
- });
1334
- lines.forEach(element => {
1335
- element.id = idCreator();
1336
- element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
1337
- Transforms.insertNode(board, element, [board.children.length]);
1338
- });
1339
- };
1340
-
1341
- const withDrawFragment = (baseBoard) => {
1342
- const board = baseBoard;
1343
- const { getDeletedFragment, setFragment, insertFragment } = board;
1344
- board.getDeletedFragment = (data) => {
1345
- const drawElements = getSelectedDrawElements(board);
1346
- if (drawElements.length) {
1347
- const lines = getBoardLines(board);
1348
- const geometryElements = drawElements.filter(value => PlaitDrawElement.isGeometry(value));
1349
- const lineElements = drawElements.filter(value => PlaitDrawElement.isLine(value));
1350
- const boundLineElements = lines.filter(line => geometryElements.find(geometry => PlaitLine.isBoundElementOfSource(line, geometry) || PlaitLine.isBoundElementOfTarget(line, geometry)));
1351
- data.push(...[...geometryElements, ...lineElements, ...boundLineElements.filter(line => !lineElements.includes(line))]);
1352
- }
1353
- return getDeletedFragment(data);
1354
- };
1355
- board.setFragment = (data, rectangle) => {
1356
- const targetDrawElements = getSelectedDrawElements(board);
1357
- if (targetDrawElements.length) {
1358
- const elements = buildClipboardData(board, targetDrawElements, rectangle ? [rectangle.x, rectangle.y] : [0, 0]);
1359
- setClipboardData(data, elements);
1360
- }
1361
- setFragment(data, rectangle);
1362
- };
1363
- board.insertFragment = (data, targetPoint) => {
1364
- const elements = getDataFromClipboard(data);
1365
- const drawElements = elements.filter(value => PlaitDrawElement.isDrawElement(value));
1366
- if (elements.length > 0 && drawElements.length > 0) {
1367
- insertClipboardData(board, drawElements, targetPoint);
1368
- }
1369
- else if (elements.length === 0) {
1370
- const text = getTextFromClipboard(data);
1371
- const selectedElements = getSelectedElements(board);
1372
- // (* ̄︶ ̄)
1373
- const insertAsChildren = selectedElements.length === 1 && selectedElements[0].children;
1374
- const insertAsFreeText = !insertAsChildren;
1375
- if (text && insertAsFreeText) {
1376
- const { width, height } = getTextSize(board, text);
1377
- DrawTransforms.insertText(board, [targetPoint, [targetPoint[0] + width, targetPoint[1] + height]], text);
1378
- return;
1379
- }
1380
- }
1381
- insertFragment(data, targetPoint);
1382
- };
1383
- return board;
1384
- };
1385
-
1386
- const DefaultLineStyle = {
1387
- strokeWidth: 2,
1388
- strokeColor: '#000'
1389
- };
1390
-
1391
- const getHitGeometryResizeHandleRef = (board, element, point) => {
1392
- const rectangle = getRectangleByPoints(element.points);
1393
- const resizeHandleRefs = getRectangleResizeHandleRefs(rectangle, RESIZE_HANDLE_DIAMETER);
1394
- const result = resizeHandleRefs.find(resizeHandleRef => {
1395
- return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), resizeHandleRef.rectangle);
1396
- });
1397
- return result;
1398
- };
1399
- const getHitOutlineGeometry = (board, point, offset = 0) => {
1400
- let geometry = null;
1401
- depthFirstRecursion(board, node => {
1402
- if (PlaitDrawElement.isGeometry(node)) {
1403
- const shape = node.shape;
1404
- let client = getRectangleByPoints(node.points);
1405
- client = RectangleClient.getOutlineRectangle(client, offset);
1406
- const isHit = getEngine(shape).isHit(client, point);
1407
- if (isHit) {
1408
- geometry = node;
1409
- }
1410
- }
1411
- }, getIsRecursionFunc(board), true);
1412
- return geometry;
1413
- };
1414
-
1415
- const withLineCreateByDraw = (board) => {
1416
- const { pointerDown, pointerMove, pointerUp } = board;
1417
- let start = null;
1418
- let sourceRef = {};
1419
- let targetRef = {};
1420
- let lineShapeG = null;
1421
- let temporaryElement = null;
1422
- board.pointerDown = (event) => {
1423
- const isLinePointer = PlaitBoard.isPointer(board, DrawPointerType.line);
1424
- if (isLinePointer && isDrawingMode(board)) {
1425
- const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1426
- start = point;
1427
- const hitElement = getHitOutlineGeometry(board, point, -4);
1428
- if (hitElement) {
1429
- sourceRef.connection = transformPointToConnection(board, point, hitElement);
1430
- sourceRef.boundId = hitElement.id;
1431
- }
1432
- preventTouchMove(board, event, true);
1433
- }
1434
- pointerDown(event);
1435
- };
1436
- board.pointerMove = (event) => {
1437
- lineShapeG === null || lineShapeG === void 0 ? void 0 : lineShapeG.remove();
1438
- lineShapeG = createG();
1439
- const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1440
- if (start) {
1441
- const hitElement = getHitOutlineGeometry(board, movingPoint, -4);
1442
- targetRef.connection = hitElement ? transformPointToConnection(board, movingPoint, hitElement) : undefined;
1443
- targetRef.boundId = hitElement ? hitElement.id : undefined;
1444
- const lineGenerator = new LineShapeGenerator(board);
1445
- temporaryElement = createLineElement(LineShape.elbow, [start, movingPoint], { marker: LineMarkerType.none, connection: sourceRef.connection, boundId: sourceRef === null || sourceRef === void 0 ? void 0 : sourceRef.boundId }, { marker: LineMarkerType.arrow, connection: targetRef.connection, boundId: targetRef === null || targetRef === void 0 ? void 0 : targetRef.boundId }, {
1446
- strokeColor: DefaultLineStyle.strokeColor,
1447
- strokeWidth: DefaultLineStyle.strokeWidth
1448
- });
1449
- lineGenerator.draw(temporaryElement, lineShapeG);
1450
- PlaitBoard.getElementActiveHost(board).append(lineShapeG);
1451
- }
1452
- pointerMove(event);
1453
- };
1454
- board.pointerUp = (event) => {
1455
- if (temporaryElement) {
1456
- Transforms.insertNode(board, temporaryElement, [board.children.length]);
1457
- clearSelectedElement(board);
1458
- addSelectedElement(board, temporaryElement);
1459
- BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1460
- }
1461
- lineShapeG === null || lineShapeG === void 0 ? void 0 : lineShapeG.remove();
1462
- lineShapeG = null;
1463
- start = null;
1464
- sourceRef = {};
1465
- targetRef = {};
1466
- temporaryElement = null;
1467
- preventTouchMove(board, event, false);
1468
- pointerUp(event);
1469
- };
1470
- return board;
1471
- };
1472
-
1473
- const withGeometryResize = (board) => {
1474
- const { keydown, keyup } = board;
1475
- let isShift = false;
1476
- board.keydown = (event) => {
1477
- isShift = isKeyHotkey('shift', event);
1478
- keydown(event);
1479
- };
1480
- board.keyup = (event) => {
1481
- isShift = false;
1482
- keyup(event);
1483
- };
1484
- const options = {
1485
- key: 'draw-geometry',
1486
- canResize: () => {
1487
- return true;
1488
- },
1489
- detect: (point) => {
1490
- const selectedGeometryElements = getSelectedGeometryElements(board);
1491
- if (selectedGeometryElements.length !== 1 || getSelectedElements(board).length !== 1) {
1492
- return null;
1493
- }
1494
- const target = selectedGeometryElements[0];
1495
- const targetComponent = PlaitElement.getComponent(selectedGeometryElements[0]);
1496
- if (targetComponent.activeGenerator.hasResizeHandle) {
1497
- const handleRef = getHitGeometryResizeHandleRef(board, target, point);
1498
- if (handleRef) {
1499
- return {
1500
- element: target,
1501
- handle: handleRef.handle,
1502
- cursorClass: handleRef.cursorClass
1503
- };
1504
- }
1505
- }
1506
- return null;
1507
- },
1508
- onResize: (resizeRef, resizeState) => {
1509
- let points = [...resizeRef.element.points];
1510
- const rectangle = getRectangleByPoints(resizeRef.element.points);
1511
- const ratio = rectangle.height / rectangle.width;
1512
- if (resizeRef.handle === ResizeHandle.nw) {
1513
- points = [resizeState.endTransformPoint, resizeRef.element.points[1]];
1514
- }
1515
- if (resizeRef.handle === ResizeHandle.ne) {
1516
- points = [resizeState.endTransformPoint, [resizeRef.element.points[0][0], resizeRef.element.points[1][1]]];
1517
- }
1518
- if (resizeRef.handle === ResizeHandle.se) {
1519
- points = [resizeState.endTransformPoint, resizeRef.element.points[0]];
1520
- }
1521
- if (resizeRef.handle === ResizeHandle.sw) {
1522
- points = [resizeState.endTransformPoint, [resizeRef.element.points[1][0], resizeRef.element.points[0][1]]];
1523
- }
1524
- if (isShift) {
1525
- const rectangle = getRectangleByPoints(points);
1526
- const factor = points[0][1] > points[1][1] ? 1 : -1;
1527
- const height = rectangle.width * ratio * factor;
1528
- points = [[resizeState.endTransformPoint[0], points[1][1] + height], points[1]];
1529
- }
1530
- points = normalizeShapePoints(points);
1531
- const { height: textHeight } = PlaitGeometry.getTextManage(resizeRef.element).getSize();
1532
- DrawTransforms.resizeGeometry(board, points, textHeight, resizeRef.path);
1533
- }
1534
- };
1535
- withResize(board, options);
1536
- return board;
1537
- };
1538
-
1539
- var LineResizeHandle;
1540
- (function (LineResizeHandle) {
1541
- LineResizeHandle["source"] = "source";
1542
- LineResizeHandle["target"] = "target";
1543
- })(LineResizeHandle || (LineResizeHandle = {}));
1544
- const getHitLineResizeHandleRef = (board, element, point) => {
1545
- const sourcePoint = getSourcePoint(board, element);
1546
- const targetPoint = getTargetPoint(board, element);
1547
- const sourceRectangle = {
1548
- x: sourcePoint[0] - RESIZE_HANDLE_DIAMETER / 2,
1549
- y: sourcePoint[1] - RESIZE_HANDLE_DIAMETER / 2,
1550
- width: RESIZE_HANDLE_DIAMETER,
1551
- height: RESIZE_HANDLE_DIAMETER
1552
- };
1553
- const targetRectangle = {
1554
- x: targetPoint[0] - RESIZE_HANDLE_DIAMETER / 2,
1555
- y: targetPoint[1] - RESIZE_HANDLE_DIAMETER / 2,
1556
- width: RESIZE_HANDLE_DIAMETER,
1557
- height: RESIZE_HANDLE_DIAMETER
1558
- };
1559
- const isHitSourceRectangle = RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), sourceRectangle);
1560
- const isHitTargetRectangle = RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), targetRectangle);
1561
- if (isHitSourceRectangle) {
1562
- return { rectangle: sourceRectangle, handle: LineResizeHandle.source };
1563
- }
1564
- if (isHitTargetRectangle) {
1565
- return { rectangle: targetRectangle, handle: LineResizeHandle.target };
1566
- }
1567
- return undefined;
1568
- };
1569
-
1570
- const withLineResize = (board) => {
1571
- const options = {
1572
- key: 'draw-line',
1573
- canResize: () => {
1574
- return true;
1575
- },
1576
- detect: (point) => {
1577
- const selectedLineElements = getSelectedLineElements(board);
1578
- if (selectedLineElements.length > 0) {
1579
- let result = null;
1580
- selectedLineElements.forEach(value => {
1581
- const handleRef = getHitLineResizeHandleRef(board, value, point);
1582
- if (handleRef) {
1583
- result = {
1584
- element: value,
1585
- handle: handleRef.handle
1586
- };
1587
- }
1588
- });
1589
- return result;
1590
- }
1591
- return null;
1592
- },
1593
- onResize: (resizeRef, resizeState) => {
1594
- let points = [...resizeRef.element.points];
1595
- let source = Object.assign({}, resizeRef.element.source);
1596
- let target = Object.assign({}, resizeRef.element.target);
1597
- if (resizeRef.handle === LineResizeHandle.source) {
1598
- points[0] = resizeState.endTransformPoint;
1599
- const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, -4);
1600
- source.connection = hitElement ? transformPointToConnection(board, resizeState.endTransformPoint, hitElement) : undefined;
1601
- source.boundId = hitElement ? hitElement.id : undefined;
1602
- }
1603
- if (resizeRef.handle === LineResizeHandle.target) {
1604
- points[1] = resizeState.endTransformPoint;
1605
- const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, -4);
1606
- target.connection = hitElement ? transformPointToConnection(board, resizeState.endTransformPoint, hitElement) : undefined;
1607
- target.boundId = hitElement ? hitElement.id : undefined;
1608
- }
1609
- DrawTransforms.resizeLine(board, { points, source, target }, resizeRef.path);
1610
- }
1611
- };
1612
- withResize(board, options);
1613
- return board;
1614
- };
1615
-
1616
- const withLineBoundReaction = (board) => {
1617
- const { pointerMove, pointerUp } = board;
1618
- let boundShapeG = null;
1619
- board.pointerMove = (event) => {
1620
- boundShapeG === null || boundShapeG === void 0 ? void 0 : boundShapeG.remove();
1621
- const isLinePointer = PlaitBoard.isPointer(board, DrawPointerType.line);
1622
- const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1623
- const isLineResizing = isResizingByCondition(board, element => PlaitDrawElement.isLine(element));
1624
- if (isLinePointer || isLineResizing) {
1625
- const hitElement = getHitOutlineGeometry(board, movingPoint, -4);
1626
- if (hitElement) {
1627
- boundShapeG = drawBoundMask(board, hitElement);
1628
- let nearestPoint = getNearestPoint(hitElement, movingPoint, ACTIVE_STROKE_WIDTH);
1629
- const rectangle = getRectangleByPoints(hitElement.points);
1630
- const activeRectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
1631
- const hitConnector = getHitConnectorPoint(nearestPoint, hitElement, activeRectangle);
1632
- nearestPoint = hitConnector ? hitConnector : nearestPoint;
1633
- const circleG = drawCircle(PlaitBoard.getRoughSVG(board), nearestPoint, 6, {
1634
- stroke: SELECTION_BORDER_COLOR,
1635
- strokeWidth: ACTIVE_STROKE_WIDTH,
1636
- fill: SELECTION_BORDER_COLOR,
1637
- fillStyle: 'solid'
1638
- });
1639
- boundShapeG.appendChild(circleG);
1640
- PlaitBoard.getElementActiveHost(board).append(boundShapeG);
1641
- }
1642
- }
1643
- pointerMove(event);
1644
- };
1645
- board.pointerUp = event => {
1646
- boundShapeG === null || boundShapeG === void 0 ? void 0 : boundShapeG.remove();
1647
- boundShapeG = null;
1648
- pointerUp(event);
1649
- };
1650
- return board;
1651
- };
1652
-
1653
- const withLineText = (board) => {
1654
- const { dblclick } = board;
1655
- board.dblclick = (event) => {
1656
- var _a;
1657
- const clickPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
1658
- const hitTarget = getHitElements(board, { ranges: [{ anchor: clickPoint, focus: clickPoint }] }, (element) => {
1659
- return PlaitDrawElement.isLine(element);
1660
- })[0];
1661
- if (hitTarget) {
1662
- const points = getLinePoints(board, hitTarget);
1663
- const point = getNearestPointBetweenPointAndSegments(clickPoint, points);
1664
- const texts = ((_a = hitTarget.texts) === null || _a === void 0 ? void 0 : _a.length) ? [...hitTarget.texts] : [];
1665
- const textIndex = getHitLineTextIndex(board, hitTarget, clickPoint);
1666
- const isHitText = isHitLineText(board, hitTarget, clickPoint);
1667
- if (isHitText) {
1668
- editHandle(board, hitTarget, textIndex);
1669
- }
1670
- else {
1671
- const ratio = getRatioByPoint(points, point);
1672
- texts.push({
1673
- text: buildText('文本'),
1674
- position: ratio,
1675
- width: 28,
1676
- height: 20
1677
- });
1678
- DrawTransforms.setLineTexts(board, hitTarget, texts);
1679
- setTimeout(() => {
1680
- const hitComponent = PlaitElement.getComponent(hitTarget);
1681
- editHandle(board, hitTarget, hitComponent.textManages.length - 1, true);
1682
- });
1683
- }
1684
- }
1685
- dblclick(event);
1686
- };
1687
- return board;
1688
- };
1689
- function editHandle(board, element, manageIndex, isFirstEdit = false) {
1690
- const hitComponent = PlaitElement.getComponent(element);
1691
- const textManage = hitComponent.textManages[manageIndex];
1692
- const originText = textManage.componentRef.instance.children;
1693
- textManage.edit((origin, descendant) => {
1694
- const text = Node.string(descendant[0]);
1695
- const shouldRemove = (isFirstEdit && originText === descendant) || !text;
1696
- if (shouldRemove) {
1697
- DrawTransforms.removeLineText(board, element, manageIndex);
1698
- }
1699
- });
1700
- }
1701
-
1702
- const withDraw = (board) => {
1703
- const { drawElement, getRectangle, isHitSelection, isMovable, dblclick } = board;
1704
- board.drawElement = (context) => {
1705
- if (PlaitDrawElement.isGeometry(context.element)) {
1706
- return GeometryComponent;
1707
- }
1708
- else if (PlaitDrawElement.isLine(context.element)) {
1709
- return LineComponent;
1710
- }
1711
- return drawElement(context);
1712
- };
1713
- board.getRectangle = (element) => {
1714
- if (PlaitDrawElement.isGeometry(element)) {
1715
- return getRectangleByPoints(element.points);
1716
- }
1717
- if (PlaitDrawElement.isLine(element)) {
1718
- const source = getSourcePoint(board, element);
1719
- const target = getTargetPoint(board, element);
1720
- return getRectangleByPoints([source, target]);
1721
- }
1722
- return getRectangle(element);
1723
- };
1724
- board.isHitSelection = (element, range) => {
1725
- if (PlaitDrawElement.isGeometry(element)) {
1726
- const client = getRectangleByPoints(element.points);
1727
- const rangeRectangle = RectangleClient.toRectangleClient([range.anchor, range.focus]);
1728
- if (element.textHeight > client.height) {
1729
- const textClient = getTextRectangle(element);
1730
- return RectangleClient.isHit(rangeRectangle, client) || RectangleClient.isHit(rangeRectangle, textClient);
1731
- }
1732
- return RectangleClient.isHit(rangeRectangle, client);
1733
- }
1734
- if (PlaitDrawElement.isLine(element)) {
1735
- const points = getLinePoints(board, element);
1736
- const strokeWidth = getStrokeWidthByElement(element);
1737
- const isHitText = isHitLineText(board, element, range.focus);
1738
- const isHit = isHitPolyLine(points, range.focus, strokeWidth, 3) || isHitText;
1739
- const rangeRectangle = RectangleClient.toRectangleClient([range.anchor, range.focus]);
1740
- const isContainPolyLinePoint = points.some(point => {
1741
- return RectangleClient.isHit(rangeRectangle, RectangleClient.toRectangleClient([point, point]));
1742
- });
1743
- const isIntersect = range.anchor === range.focus ? isHit : isPolylineHitRectangle(points, rangeRectangle);
1744
- return isContainPolyLinePoint || isIntersect;
1745
- }
1746
- return isHitSelection(element, range);
1747
- };
1748
- board.isMovable = (element) => {
1749
- if (PlaitDrawElement.isGeometry(element)) {
1750
- return true;
1751
- }
1752
- if (PlaitDrawElement.isLine(element)) {
1753
- return !element.source.boundId && !element.target.boundId;
1754
- }
1755
- return isMovable(element);
1756
- };
1757
- return withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withGeometryCreateByDrag(withGeometryCreateByDraw(withDrawFragment(withDrawHotkey(board)))))))));
1758
- };
1759
-
1760
- /**
1761
- * Generated bundle index. Do not edit.
1762
- */
1763
-
1764
- 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, getSourcePoint, getStraightPoints, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTargetPoint, getTextRectangle, isHitLineText, isHitPolyLine, transformPointToConnection, withDraw };
1765
- //# sourceMappingURL=plait-draw.mjs.map