@plait/draw 0.29.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/constants/line.mjs +1 -1
- package/esm2022/generators/line-active.generator.mjs +1 -1
- package/esm2022/plugins/with-draw-fragment.mjs +5 -4
- package/esm2022/plugins/with-draw.mjs +15 -31
- package/esm2022/plugins/with-geometry-create.mjs +2 -2
- package/esm2022/plugins/with-geometry-resize.mjs +50 -15
- package/esm2022/plugins/with-line-create.mjs +2 -2
- package/esm2022/plugins/with-line-resize.mjs +28 -10
- package/esm2022/plugins/with-line-text.mjs +4 -4
- package/esm2022/utils/geometry.mjs +64 -3
- package/esm2022/utils/hit.mjs +58 -0
- package/esm2022/utils/index.mjs +2 -1
- package/esm2022/utils/line.mjs +39 -17
- package/esm2022/utils/position/geometry.mjs +1 -1
- package/fesm2022/plait-draw.mjs +770 -604
- package/fesm2022/plait-draw.mjs.map +1 -1
- package/package.json +1 -1
- package/plugins/with-geometry-create.d.ts +2 -1
- package/utils/geometry.d.ts +1 -0
- package/utils/hit.d.ts +3 -0
- package/utils/index.d.ts +1 -0
- package/utils/line.d.ts +2 -3
- package/utils/position/geometry.d.ts +2 -1
package/fesm2022/plait-draw.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { PlaitElement, ACTIVE_STROKE_WIDTH, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle,
|
|
2
|
-
import { getRectangleByPoints, getFactorByPoints, getDirectionByVector, getOppositeDirection, getDirectionFactor, getPoints, getPointByVector, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90,
|
|
3
|
-
import { Alignment,
|
|
1
|
+
import { PlaitElement, ACTIVE_STROKE_WIDTH, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Point, BOARD_TO_HOST, transformPoint, toPoint, idCreator, createG, BoardTransforms, PlaitPointerType, preventTouchMove, createForeignObject, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, arrowPoints, createPath, drawLinearPath, rotate, getElementById, distanceBetweenPointAndPoint, distanceBetweenPointAndSegments, createMask, createRect, findElements, getSelectedElements, isPolylineHitRectangle, isSelectionMoving, PlaitPluginElementComponent, setClipboardData, getDataFromClipboard, depthFirstRecursion, getIsRecursionFunc, getHitElementByPoint } from '@plait/core';
|
|
2
|
+
import { getRectangleByPoints, Generator, normalizeShapePoints, isDndMode, isDrawingMode, getFactorByPoints, getDirectionByVector, getOppositeDirection, getDirectionFactor, DEFAULT_ROUTE_MARGIN, reduceRouteMargin, getNextPoint, generateElbowLineRoute, getPoints, removeDuplicatePoints, getPointByVector, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90, TRANSPARENT, CommonPluginElement, ActiveGenerator, WithTextPluginKey, RESIZE_HANDLE_DIAMETER, PRIMARY_COLOR, isVirtualKey, isDelete, isSpaceHotkey, acceptImageTypes, getElementOfFocusedImage, buildImage, getRectangleResizeHandleRefs, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint, ImageGenerator } from '@plait/common';
|
|
3
|
+
import { AlignEditor, Alignment, DEFAULT_FONT_SIZE, buildText, TextManage, getTextFromClipboard, getTextSize } from '@plait/text';
|
|
4
|
+
import { isKeyHotkey } from 'is-hotkey';
|
|
4
5
|
import { pointsOnBezierCurves } from 'points-on-curve';
|
|
5
6
|
import * as i0 from '@angular/core';
|
|
6
7
|
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
|
7
8
|
import { Subject } from 'rxjs';
|
|
8
|
-
import { isKeyHotkey } from 'is-hotkey';
|
|
9
9
|
import { Node } from 'slate';
|
|
10
10
|
|
|
11
11
|
var BasicShapes;
|
|
@@ -1168,192 +1168,575 @@ const getShape = (value) => {
|
|
|
1168
1168
|
return value.shape;
|
|
1169
1169
|
};
|
|
1170
1170
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
if (shape === BasicShapes.text) {
|
|
1175
|
-
textOptions = { autoSize: true };
|
|
1176
|
-
alignment = undefined;
|
|
1177
|
-
}
|
|
1178
|
-
let flowchartOptions = {};
|
|
1179
|
-
if (getFlowchartPointers().includes(shape)) {
|
|
1180
|
-
flowchartOptions = { fill: '#ffffff' };
|
|
1171
|
+
class GeometryShapeGenerator extends Generator {
|
|
1172
|
+
canDraw(element, data) {
|
|
1173
|
+
return true;
|
|
1181
1174
|
}
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
shape
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
const leftTopPoint = [point[0] - width / 2, point[1] - height / 2];
|
|
1198
|
-
const rightBottomPoint = [point[0] + width / 2, point[1] + height / 2];
|
|
1199
|
-
return [leftTopPoint, rightBottomPoint];
|
|
1200
|
-
};
|
|
1201
|
-
const getTextRectangle = (element) => {
|
|
1202
|
-
const elementRectangle = getRectangleByPoints(element.points);
|
|
1203
|
-
const strokeWidth = getStrokeWidthByElement(element);
|
|
1204
|
-
const height = element.textHeight;
|
|
1205
|
-
const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
|
|
1206
|
-
return {
|
|
1207
|
-
height,
|
|
1208
|
-
width: width > 0 ? width : 0,
|
|
1209
|
-
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
|
|
1210
|
-
y: elementRectangle.y + (elementRectangle.height - height) / 2
|
|
1211
|
-
};
|
|
1212
|
-
};
|
|
1213
|
-
const drawBoundMask = (board, element) => {
|
|
1214
|
-
const G = createG();
|
|
1215
|
-
const rectangle = getRectangleByPoints(element.points);
|
|
1216
|
-
const activeRectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
|
|
1217
|
-
const shape = getShape(element);
|
|
1218
|
-
const maskG = drawGeometry(board, activeRectangle, shape, {
|
|
1219
|
-
stroke: SELECTION_BORDER_COLOR,
|
|
1220
|
-
strokeWidth: 1,
|
|
1221
|
-
fill: SELECTION_FILL_COLOR,
|
|
1222
|
-
fillStyle: 'solid'
|
|
1223
|
-
});
|
|
1224
|
-
G.appendChild(maskG);
|
|
1225
|
-
const connectorPoints = getEngine(shape).getConnectorPoints(activeRectangle);
|
|
1226
|
-
connectorPoints.forEach(point => {
|
|
1227
|
-
const circleG = drawCircle(PlaitBoard.getRoughSVG(board), point, 6, {
|
|
1228
|
-
stroke: '#999999',
|
|
1229
|
-
strokeWidth: 1,
|
|
1230
|
-
fill: '#FFF',
|
|
1231
|
-
fillStyle: 'solid'
|
|
1175
|
+
baseDraw(element, data) {
|
|
1176
|
+
const rectangle = getRectangleByPoints(element.points);
|
|
1177
|
+
const shape = element.shape;
|
|
1178
|
+
if (shape === BasicShapes.text) {
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1182
|
+
const strokeColor = getStrokeColorByElement(element);
|
|
1183
|
+
const fill = getFillByElement(element);
|
|
1184
|
+
const strokeLineDash = getLineDashByElement(element);
|
|
1185
|
+
return drawGeometry(this.board, RectangleClient.inflate(rectangle, -strokeWidth), shape, {
|
|
1186
|
+
stroke: strokeColor,
|
|
1187
|
+
strokeWidth,
|
|
1188
|
+
fill,
|
|
1189
|
+
strokeLineDash
|
|
1232
1190
|
});
|
|
1233
|
-
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
const insertGeometry = (board, points, shape) => {
|
|
1195
|
+
let newElement = createGeometryElement(shape, points, '', {
|
|
1196
|
+
strokeColor: DefaultBasicShapeProperty.strokeColor,
|
|
1197
|
+
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
1234
1198
|
});
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
return getEngine(shape).draw(board, outerRectangle, options);
|
|
1239
|
-
};
|
|
1240
|
-
const getNearestPoint = (element, point, inflateDelta = 0) => {
|
|
1241
|
-
const rectangle = getRectangleByPoints(element.points);
|
|
1242
|
-
const activeRectangle = RectangleClient.inflate(rectangle, inflateDelta);
|
|
1243
|
-
const shape = getShape(element);
|
|
1244
|
-
return getEngine(shape).getNearestPoint(activeRectangle, point);
|
|
1199
|
+
Transforms.insertNode(board, newElement, [board.children.length]);
|
|
1200
|
+
clearSelectedElement(board);
|
|
1201
|
+
addSelectedElement(board, newElement);
|
|
1245
1202
|
};
|
|
1246
|
-
const
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
}
|
|
1252
|
-
return centerPoint;
|
|
1203
|
+
const insertText = (board, points, text = '文本') => {
|
|
1204
|
+
let newElement = createGeometryElement(BasicShapes.text, points, text);
|
|
1205
|
+
Transforms.insertNode(board, newElement, [board.children.length]);
|
|
1206
|
+
clearSelectedElement(board);
|
|
1207
|
+
addSelectedElement(board, newElement);
|
|
1253
1208
|
};
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
}
|
|
1209
|
+
const resizeGeometry = (board, points, textHeight, path) => {
|
|
1210
|
+
const normalizePoints = normalizeShapePoints(points);
|
|
1211
|
+
const element = PlaitNode.get(board, path);
|
|
1212
|
+
const newHeight = textHeight / board.viewport.zoom;
|
|
1213
|
+
const newProperties = { points: normalizePoints, textHeight: newHeight };
|
|
1214
|
+
if (PlaitDrawElement.isText(element) && element.autoSize) {
|
|
1215
|
+
newProperties.autoSize = false;
|
|
1262
1216
|
}
|
|
1263
|
-
|
|
1264
|
-
};
|
|
1265
|
-
const getDefaultFlowchartProperty = (symbol) => {
|
|
1266
|
-
return DefaultFlowchartPropertyMap[symbol];
|
|
1217
|
+
Transforms.setNode(board, newProperties, path);
|
|
1267
1218
|
};
|
|
1268
1219
|
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
const source = getExtendPoint(points[points.length - 1], points[points.length - 2], 24);
|
|
1281
|
-
const arrow = getArrow(element, { marker: element.target.marker, source, target: points[points.length - 1], isSource: false }, options);
|
|
1282
|
-
arrow && arrowG.appendChild(arrow);
|
|
1283
|
-
}
|
|
1284
|
-
return arrowG;
|
|
1285
|
-
};
|
|
1286
|
-
const getArrow = (element, arrowOptions, options) => {
|
|
1287
|
-
const { marker, source, target, isSource } = arrowOptions;
|
|
1288
|
-
let targetArrow;
|
|
1289
|
-
switch (marker) {
|
|
1290
|
-
case LineMarkerType.openTriangle: {
|
|
1291
|
-
targetArrow = drawOpenTriangle(element, source, target, options);
|
|
1292
|
-
break;
|
|
1293
|
-
}
|
|
1294
|
-
case LineMarkerType.solidTriangle: {
|
|
1295
|
-
targetArrow = drawSolidTriangle(source, target, options);
|
|
1296
|
-
break;
|
|
1297
|
-
}
|
|
1298
|
-
case LineMarkerType.arrow: {
|
|
1299
|
-
targetArrow = drawArrow(element, source, target, options);
|
|
1300
|
-
break;
|
|
1301
|
-
}
|
|
1302
|
-
case LineMarkerType.sharpArrow: {
|
|
1303
|
-
targetArrow = drawSharpArrow(source, target, options);
|
|
1304
|
-
break;
|
|
1305
|
-
}
|
|
1306
|
-
case LineMarkerType.oneSideUp: {
|
|
1307
|
-
targetArrow = drawOneSideArrow(source, target, isSource ? 'down' : 'up', options);
|
|
1308
|
-
break;
|
|
1309
|
-
}
|
|
1310
|
-
case LineMarkerType.oneSideDown: {
|
|
1311
|
-
targetArrow = drawOneSideArrow(source, target, isSource ? 'up' : 'down', options);
|
|
1312
|
-
break;
|
|
1220
|
+
const normalizePoints = (board, element, width, textHeight) => {
|
|
1221
|
+
let points = element.points;
|
|
1222
|
+
let autoSize = element.autoSize;
|
|
1223
|
+
const defaultSpace = ShapeDefaultSpace.rectangleAndText;
|
|
1224
|
+
if (autoSize) {
|
|
1225
|
+
const editor = PlaitGeometry.getTextEditor(element);
|
|
1226
|
+
if (AlignEditor.isActive(editor, Alignment.right)) {
|
|
1227
|
+
points = [
|
|
1228
|
+
[points[1][0] - (width + defaultSpace * 2), points[0][1]],
|
|
1229
|
+
[points[1][0], points[0][1] + textHeight]
|
|
1230
|
+
];
|
|
1313
1231
|
}
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1232
|
+
else if (AlignEditor.isActive(editor, Alignment.center)) {
|
|
1233
|
+
const oldWidth = Math.abs(points[0][0] - points[1][0]);
|
|
1234
|
+
const offset = (width - oldWidth) / 2;
|
|
1235
|
+
points = [
|
|
1236
|
+
[points[0][0] - offset - defaultSpace, points[0][1]],
|
|
1237
|
+
[points[1][0] + offset + defaultSpace, points[0][1] + textHeight]
|
|
1238
|
+
];
|
|
1317
1239
|
}
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
break;
|
|
1240
|
+
else {
|
|
1241
|
+
points = [points[0], [points[0][0] + width + defaultSpace * 2, points[0][1] + textHeight]];
|
|
1321
1242
|
}
|
|
1322
1243
|
}
|
|
1323
|
-
return
|
|
1324
|
-
};
|
|
1325
|
-
const drawSharpArrow = (source, target, options) => {
|
|
1326
|
-
const startPoint = target;
|
|
1327
|
-
const { pointLeft, pointRight } = arrowPoints(source, target, 12, 20);
|
|
1328
|
-
const g = createG();
|
|
1329
|
-
const path = createPath();
|
|
1330
|
-
let polylinePath = `M${pointRight[0]},${pointRight[1]}A8,8,20,0,1,${pointLeft[0]},${pointLeft[1]}L${startPoint[0]},${startPoint[1]}Z`;
|
|
1331
|
-
path.setAttribute('d', polylinePath);
|
|
1332
|
-
path.setAttribute('stroke', `${options?.stroke}`);
|
|
1333
|
-
path.setAttribute('stroke-width', `${options?.strokeWidth}`);
|
|
1334
|
-
path.setAttribute('fill', `${options?.stroke}`);
|
|
1335
|
-
g.appendChild(path);
|
|
1336
|
-
return g;
|
|
1244
|
+
return { points };
|
|
1337
1245
|
};
|
|
1338
|
-
const
|
|
1339
|
-
const
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
const
|
|
1345
|
-
|
|
1346
|
-
path.setAttribute('stroke-linejoin', 'round');
|
|
1347
|
-
return arrowG;
|
|
1246
|
+
const setText = (board, element, text, width, textHeight) => {
|
|
1247
|
+
const newElement = {
|
|
1248
|
+
text,
|
|
1249
|
+
textHeight,
|
|
1250
|
+
...normalizePoints(board, element, width, textHeight)
|
|
1251
|
+
};
|
|
1252
|
+
const path = board.children.findIndex(child => child === element);
|
|
1253
|
+
Transforms.setNode(board, newElement, [path]);
|
|
1348
1254
|
};
|
|
1349
|
-
const
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1255
|
+
const setTextSize = (board, element, textWidth, textHeight) => {
|
|
1256
|
+
if (element.autoSize) {
|
|
1257
|
+
const newElement = {
|
|
1258
|
+
textHeight,
|
|
1259
|
+
...normalizePoints(board, element, textWidth, textHeight)
|
|
1260
|
+
};
|
|
1261
|
+
const isPointsEqual = Point.isEquals(element.points[0], newElement.points[0]) && Point.isEquals(element.points[1], newElement.points[1]);
|
|
1262
|
+
const isTextHeightEqual = Math.round(textHeight) === Math.round(element.textHeight);
|
|
1263
|
+
if (!isPointsEqual || !isTextHeightEqual) {
|
|
1264
|
+
const path = board.children.findIndex(child => child === element);
|
|
1265
|
+
Transforms.setNode(board, newElement, [path]);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1353
1268
|
};
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
const
|
|
1269
|
+
|
|
1270
|
+
const insertImage = (board, imageItem, startPoint) => {
|
|
1271
|
+
const { width, height, url } = imageItem;
|
|
1272
|
+
const host = BOARD_TO_HOST.get(board);
|
|
1273
|
+
const viewportWidth = PlaitBoard.getComponent(board).nativeElement.clientWidth;
|
|
1274
|
+
const viewportHeight = PlaitBoard.getComponent(board).nativeElement.clientHeight;
|
|
1275
|
+
const point = transformPoint(board, toPoint(viewportWidth / 2, viewportHeight / 2, host));
|
|
1276
|
+
const points = startPoint
|
|
1277
|
+
? [startPoint, [startPoint[0] + width, startPoint[1] + height]]
|
|
1278
|
+
: [
|
|
1279
|
+
[point[0] - width / 2, point[1] - height / 2],
|
|
1280
|
+
[point[0] + width / 2, point[1] + height / 2]
|
|
1281
|
+
];
|
|
1282
|
+
const imageElement = {
|
|
1283
|
+
id: idCreator(),
|
|
1284
|
+
type: 'image',
|
|
1285
|
+
points,
|
|
1286
|
+
url
|
|
1287
|
+
};
|
|
1288
|
+
Transforms.insertNode(board, imageElement, [board.children.length]);
|
|
1289
|
+
Transforms.addSelectionWithTemporaryElements(board, [imageElement]);
|
|
1290
|
+
};
|
|
1291
|
+
|
|
1292
|
+
const resizeLine = (board, options, path) => {
|
|
1293
|
+
Transforms.setNode(board, options, path);
|
|
1294
|
+
};
|
|
1295
|
+
const setLineTexts = (board, element, texts) => {
|
|
1296
|
+
const path = PlaitBoard.findPath(board, element);
|
|
1297
|
+
Transforms.setNode(board, { texts }, path);
|
|
1298
|
+
};
|
|
1299
|
+
const removeLineText = (board, element, index) => {
|
|
1300
|
+
const path = PlaitBoard.findPath(board, element);
|
|
1301
|
+
const texts = element.texts?.length ? [...element.texts] : [];
|
|
1302
|
+
const newTexts = [...texts];
|
|
1303
|
+
newTexts.splice(index, 1);
|
|
1304
|
+
Transforms.setNode(board, { texts: newTexts }, path);
|
|
1305
|
+
};
|
|
1306
|
+
const setLineMark = (board, element, handleKey, marker) => {
|
|
1307
|
+
const path = PlaitBoard.findPath(board, element);
|
|
1308
|
+
let handle = handleKey === LineHandleKey.source ? element.source : element.target;
|
|
1309
|
+
handle = { ...handle, marker };
|
|
1310
|
+
Transforms.setNode(board, { [handleKey]: handle }, path);
|
|
1311
|
+
};
|
|
1312
|
+
|
|
1313
|
+
const DrawTransforms = {
|
|
1314
|
+
setText,
|
|
1315
|
+
insertGeometry,
|
|
1316
|
+
resizeGeometry,
|
|
1317
|
+
insertText,
|
|
1318
|
+
setTextSize,
|
|
1319
|
+
resizeLine,
|
|
1320
|
+
setLineTexts,
|
|
1321
|
+
removeLineText,
|
|
1322
|
+
setLineMark,
|
|
1323
|
+
insertImage
|
|
1324
|
+
};
|
|
1325
|
+
|
|
1326
|
+
const withGeometryCreateByDrag = (board) => {
|
|
1327
|
+
const { pointerMove, pointerUp } = board;
|
|
1328
|
+
let geometryShapeG = null;
|
|
1329
|
+
board.pointerMove = (event) => {
|
|
1330
|
+
geometryShapeG?.remove();
|
|
1331
|
+
geometryShapeG = createG();
|
|
1332
|
+
const geometryGenerator = new GeometryShapeGenerator(board);
|
|
1333
|
+
const geometryPointers = getGeometryPointers();
|
|
1334
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
1335
|
+
const dragMode = isGeometryPointer && isDndMode(board);
|
|
1336
|
+
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1337
|
+
const pointer = PlaitBoard.getPointer(board);
|
|
1338
|
+
if (dragMode) {
|
|
1339
|
+
const points = getDefaultGeometryPoints(pointer, movingPoint);
|
|
1340
|
+
if (pointer === BasicShapes.text) {
|
|
1341
|
+
const textG = getTemporaryTextG(movingPoint);
|
|
1342
|
+
geometryShapeG.appendChild(textG);
|
|
1343
|
+
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
1344
|
+
}
|
|
1345
|
+
else {
|
|
1346
|
+
const temporaryElement = createGeometryElement(pointer, points, '', {
|
|
1347
|
+
strokeColor: DefaultBasicShapeProperty.strokeColor,
|
|
1348
|
+
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
1349
|
+
});
|
|
1350
|
+
geometryGenerator.draw(temporaryElement, geometryShapeG);
|
|
1351
|
+
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
pointerMove(event);
|
|
1355
|
+
};
|
|
1356
|
+
board.pointerUp = (event) => {
|
|
1357
|
+
const pointer = PlaitBoard.getPointer(board);
|
|
1358
|
+
const geometryPointers = getGeometryPointers();
|
|
1359
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
1360
|
+
const dragMode = isGeometryPointer && isDndMode(board);
|
|
1361
|
+
if (dragMode) {
|
|
1362
|
+
const targetPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1363
|
+
const points = getDefaultGeometryPoints(pointer, targetPoint);
|
|
1364
|
+
if (pointer === BasicShapes.text) {
|
|
1365
|
+
DrawTransforms.insertText(board, points);
|
|
1366
|
+
}
|
|
1367
|
+
else {
|
|
1368
|
+
DrawTransforms.insertGeometry(board, points, pointer);
|
|
1369
|
+
}
|
|
1370
|
+
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
1371
|
+
}
|
|
1372
|
+
geometryShapeG?.remove();
|
|
1373
|
+
geometryShapeG = null;
|
|
1374
|
+
preventTouchMove(board, event, false);
|
|
1375
|
+
pointerUp(event);
|
|
1376
|
+
};
|
|
1377
|
+
return board;
|
|
1378
|
+
};
|
|
1379
|
+
const withGeometryCreateByDrawing = (board) => {
|
|
1380
|
+
const { pointerDown, pointerMove, pointerUp, keydown, keyup } = board;
|
|
1381
|
+
let start = null;
|
|
1382
|
+
let geometryShapeG = null;
|
|
1383
|
+
let temporaryElement = null;
|
|
1384
|
+
let isShift = false;
|
|
1385
|
+
board.keydown = (event) => {
|
|
1386
|
+
isShift = isKeyHotkey('shift', event);
|
|
1387
|
+
keydown(event);
|
|
1388
|
+
};
|
|
1389
|
+
board.keyup = (event) => {
|
|
1390
|
+
isShift = false;
|
|
1391
|
+
keyup(event);
|
|
1392
|
+
};
|
|
1393
|
+
board.pointerDown = (event) => {
|
|
1394
|
+
const geometryPointers = getGeometryPointers();
|
|
1395
|
+
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
1396
|
+
if (isGeometryPointer && isDrawingMode(board)) {
|
|
1397
|
+
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1398
|
+
start = point;
|
|
1399
|
+
const pointer = PlaitBoard.getPointer(board);
|
|
1400
|
+
preventTouchMove(board, event, true);
|
|
1401
|
+
if (pointer === BasicShapes.text) {
|
|
1402
|
+
const points = getDefaultGeometryPoints(pointer, point);
|
|
1403
|
+
const textElement = createGeometryElement(BasicShapes.text, points, DefaultTextProperty.text);
|
|
1404
|
+
Transforms.insertNode(board, textElement, [board.children.length]);
|
|
1405
|
+
clearSelectedElement(board);
|
|
1406
|
+
addSelectedElement(board, textElement);
|
|
1407
|
+
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
1408
|
+
start = null;
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
pointerDown(event);
|
|
1412
|
+
};
|
|
1413
|
+
board.pointerMove = (event) => {
|
|
1414
|
+
geometryShapeG?.remove();
|
|
1415
|
+
geometryShapeG = createG();
|
|
1416
|
+
const geometryGenerator = new GeometryShapeGenerator(board);
|
|
1417
|
+
const drawMode = !!start;
|
|
1418
|
+
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1419
|
+
const pointer = PlaitBoard.getPointer(board);
|
|
1420
|
+
if (drawMode && pointer !== BasicShapes.text) {
|
|
1421
|
+
const points = normalizeShapePoints([start, movingPoint], isShift);
|
|
1422
|
+
temporaryElement = createGeometryElement(pointer, points, '', {
|
|
1423
|
+
strokeColor: DefaultBasicShapeProperty.strokeColor,
|
|
1424
|
+
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
1425
|
+
});
|
|
1426
|
+
geometryGenerator.draw(temporaryElement, geometryShapeG);
|
|
1427
|
+
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
1428
|
+
}
|
|
1429
|
+
pointerMove(event);
|
|
1430
|
+
};
|
|
1431
|
+
board.pointerUp = (event) => {
|
|
1432
|
+
const isDrawMode = !!start;
|
|
1433
|
+
if (isDrawMode) {
|
|
1434
|
+
const targetPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
1435
|
+
const { width, height } = RectangleClient.toRectangleClient([start, targetPoint]);
|
|
1436
|
+
if (Math.hypot(width, height) === 0) {
|
|
1437
|
+
const pointer = PlaitBoard.getPointer(board);
|
|
1438
|
+
const points = getDefaultGeometryPoints(pointer, targetPoint);
|
|
1439
|
+
if (pointer !== BasicShapes.text) {
|
|
1440
|
+
temporaryElement = createGeometryElement(pointer, points, '', {
|
|
1441
|
+
strokeColor: DefaultBasicShapeProperty.strokeColor,
|
|
1442
|
+
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
if (temporaryElement) {
|
|
1448
|
+
Transforms.insertNode(board, temporaryElement, [board.children.length]);
|
|
1449
|
+
clearSelectedElement(board);
|
|
1450
|
+
addSelectedElement(board, temporaryElement);
|
|
1451
|
+
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
1452
|
+
}
|
|
1453
|
+
geometryShapeG?.remove();
|
|
1454
|
+
geometryShapeG = null;
|
|
1455
|
+
start = null;
|
|
1456
|
+
temporaryElement = null;
|
|
1457
|
+
preventTouchMove(board, event, false);
|
|
1458
|
+
pointerUp(event);
|
|
1459
|
+
};
|
|
1460
|
+
return board;
|
|
1461
|
+
};
|
|
1462
|
+
const getDefaultGeometryPoints = (pointer, targetPoint) => {
|
|
1463
|
+
const defaultProperty = getGeometryDefaultProperty(pointer);
|
|
1464
|
+
return getPointsByCenterPoint(targetPoint, defaultProperty.width, defaultProperty.height);
|
|
1465
|
+
};
|
|
1466
|
+
const getGeometryDefaultProperty = (pointer) => {
|
|
1467
|
+
const isText = pointer === BasicShapes.text;
|
|
1468
|
+
const isFlowChart = getFlowchartPointers().includes(pointer);
|
|
1469
|
+
if (isText) {
|
|
1470
|
+
return DefaultTextProperty;
|
|
1471
|
+
}
|
|
1472
|
+
else if (isFlowChart) {
|
|
1473
|
+
return getDefaultFlowchartProperty(pointer);
|
|
1474
|
+
}
|
|
1475
|
+
else {
|
|
1476
|
+
return DefaultBasicShapeProperty;
|
|
1477
|
+
}
|
|
1478
|
+
};
|
|
1479
|
+
const getTemporaryTextG = (movingPoint) => {
|
|
1480
|
+
const textG = createG();
|
|
1481
|
+
const width = DefaultTextProperty.width - ShapeDefaultSpace.rectangleAndText * 2;
|
|
1482
|
+
const foreignObject = createForeignObject(movingPoint[0] - width / 2, movingPoint[1] - DefaultTextProperty.height / 2, width, DefaultTextProperty.height);
|
|
1483
|
+
const richtext = document.createElement('div');
|
|
1484
|
+
richtext.textContent = DefaultTextProperty.text;
|
|
1485
|
+
richtext.style.fontSize = `${DEFAULT_FONT_SIZE}px`;
|
|
1486
|
+
richtext.style.cursor = 'default';
|
|
1487
|
+
foreignObject.appendChild(richtext);
|
|
1488
|
+
textG.appendChild(foreignObject);
|
|
1489
|
+
return textG;
|
|
1490
|
+
};
|
|
1491
|
+
|
|
1492
|
+
const DefaultLineStyle = {
|
|
1493
|
+
strokeWidth: 2,
|
|
1494
|
+
strokeColor: '#000'
|
|
1495
|
+
};
|
|
1496
|
+
|
|
1497
|
+
const createGeometryElement = (shape, points, text, options) => {
|
|
1498
|
+
let textOptions = {};
|
|
1499
|
+
let alignment = Alignment.center;
|
|
1500
|
+
if (shape === BasicShapes.text) {
|
|
1501
|
+
textOptions = { autoSize: true };
|
|
1502
|
+
alignment = undefined;
|
|
1503
|
+
}
|
|
1504
|
+
let flowchartOptions = {};
|
|
1505
|
+
if (getFlowchartPointers().includes(shape)) {
|
|
1506
|
+
flowchartOptions = { fill: '#ffffff' };
|
|
1507
|
+
}
|
|
1508
|
+
return {
|
|
1509
|
+
id: idCreator(),
|
|
1510
|
+
type: 'geometry',
|
|
1511
|
+
shape,
|
|
1512
|
+
angle: 0,
|
|
1513
|
+
opacity: 1,
|
|
1514
|
+
textHeight: DefaultTextProperty.height,
|
|
1515
|
+
text: buildText(text, alignment),
|
|
1516
|
+
points,
|
|
1517
|
+
...textOptions,
|
|
1518
|
+
...options,
|
|
1519
|
+
...flowchartOptions
|
|
1520
|
+
};
|
|
1521
|
+
};
|
|
1522
|
+
const getPointsByCenterPoint = (point, width, height) => {
|
|
1523
|
+
const leftTopPoint = [point[0] - width / 2, point[1] - height / 2];
|
|
1524
|
+
const rightBottomPoint = [point[0] + width / 2, point[1] + height / 2];
|
|
1525
|
+
return [leftTopPoint, rightBottomPoint];
|
|
1526
|
+
};
|
|
1527
|
+
const getTextRectangle = (element) => {
|
|
1528
|
+
const elementRectangle = getRectangleByPoints(element.points);
|
|
1529
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1530
|
+
const height = element.textHeight;
|
|
1531
|
+
const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
|
|
1532
|
+
return {
|
|
1533
|
+
height,
|
|
1534
|
+
width: width > 0 ? width : 0,
|
|
1535
|
+
x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
|
|
1536
|
+
y: elementRectangle.y + (elementRectangle.height - height) / 2
|
|
1537
|
+
};
|
|
1538
|
+
};
|
|
1539
|
+
const drawBoundMask = (board, element) => {
|
|
1540
|
+
const G = createG();
|
|
1541
|
+
const rectangle = getRectangleByPoints(element.points);
|
|
1542
|
+
const activeRectangle = RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH);
|
|
1543
|
+
const shape = getShape(element);
|
|
1544
|
+
const maskG = drawGeometry(board, activeRectangle, shape, {
|
|
1545
|
+
stroke: SELECTION_BORDER_COLOR,
|
|
1546
|
+
strokeWidth: 1,
|
|
1547
|
+
fill: SELECTION_FILL_COLOR,
|
|
1548
|
+
fillStyle: 'solid'
|
|
1549
|
+
});
|
|
1550
|
+
G.appendChild(maskG);
|
|
1551
|
+
const connectorPoints = getEngine(shape).getConnectorPoints(activeRectangle);
|
|
1552
|
+
connectorPoints.forEach(point => {
|
|
1553
|
+
const circleG = drawCircle(PlaitBoard.getRoughSVG(board), point, 6, {
|
|
1554
|
+
stroke: '#999999',
|
|
1555
|
+
strokeWidth: 1,
|
|
1556
|
+
fill: '#FFF',
|
|
1557
|
+
fillStyle: 'solid'
|
|
1558
|
+
});
|
|
1559
|
+
G.appendChild(circleG);
|
|
1560
|
+
});
|
|
1561
|
+
return G;
|
|
1562
|
+
};
|
|
1563
|
+
const drawGeometry = (board, outerRectangle, shape, options) => {
|
|
1564
|
+
return getEngine(shape).draw(board, outerRectangle, options);
|
|
1565
|
+
};
|
|
1566
|
+
const getNearestPoint = (element, point, inflateDelta = 0) => {
|
|
1567
|
+
const rectangle = getRectangleByPoints(element.points);
|
|
1568
|
+
const activeRectangle = RectangleClient.inflate(rectangle, inflateDelta);
|
|
1569
|
+
const shape = getShape(element);
|
|
1570
|
+
return getEngine(shape).getNearestPoint(activeRectangle, point);
|
|
1571
|
+
};
|
|
1572
|
+
const getCenterPointsOnPolygon = (points) => {
|
|
1573
|
+
const centerPoint = [];
|
|
1574
|
+
for (let i = 0; i < points.length; i++) {
|
|
1575
|
+
let j = i == points.length - 1 ? 0 : i + 1;
|
|
1576
|
+
centerPoint.push([(points[i][0] + points[j][0]) / 2, (points[i][1] + points[j][1]) / 2]);
|
|
1577
|
+
}
|
|
1578
|
+
return centerPoint;
|
|
1579
|
+
};
|
|
1580
|
+
const getEdgeOnPolygonByPoint = (corners, point) => {
|
|
1581
|
+
for (let index = 1; index <= corners.length; index++) {
|
|
1582
|
+
let start = corners[index - 1];
|
|
1583
|
+
let end = index === corners.length ? corners[0] : corners[index];
|
|
1584
|
+
const distance = distanceBetweenPointAndSegment(point[0], point[1], start[0], start[1], end[0], end[1]);
|
|
1585
|
+
if (distance < 1) {
|
|
1586
|
+
return [start, end];
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
return null;
|
|
1590
|
+
};
|
|
1591
|
+
const getDefaultFlowchartProperty = (symbol) => {
|
|
1592
|
+
return DefaultFlowchartPropertyMap[symbol];
|
|
1593
|
+
};
|
|
1594
|
+
const createDefaultFlowchart = (point) => {
|
|
1595
|
+
const decisionProperty = getDefaultFlowchartProperty(FlowchartSymbols.decision);
|
|
1596
|
+
const processProperty = getDefaultFlowchartProperty(FlowchartSymbols.process);
|
|
1597
|
+
const terminalProperty = getDefaultFlowchartProperty(FlowchartSymbols.terminal);
|
|
1598
|
+
const options = {
|
|
1599
|
+
strokeColor: DefaultBasicShapeProperty.strokeColor,
|
|
1600
|
+
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
1601
|
+
};
|
|
1602
|
+
const lineOptions = {
|
|
1603
|
+
strokeColor: DefaultLineStyle.strokeColor,
|
|
1604
|
+
strokeWidth: DefaultLineStyle.strokeWidth
|
|
1605
|
+
};
|
|
1606
|
+
const startElement = createGeometryElement(FlowchartSymbols.terminal, getDefaultGeometryPoints(FlowchartSymbols.terminal, point), '开始', options);
|
|
1607
|
+
const processPoint1 = [point[0], point[1] + terminalProperty.height / 2 + 55 + processProperty.height / 2];
|
|
1608
|
+
const processElement1 = createGeometryElement(FlowchartSymbols.process, getDefaultGeometryPoints(FlowchartSymbols.process, processPoint1), '过程', options);
|
|
1609
|
+
const decisionPoint = [processPoint1[0], processPoint1[1] + processProperty.height / 2 + 55 + decisionProperty.height / 2];
|
|
1610
|
+
const decisionElement = createGeometryElement(FlowchartSymbols.decision, getDefaultGeometryPoints(FlowchartSymbols.decision, decisionPoint), '过程', options);
|
|
1611
|
+
const processPoint2 = [decisionPoint[0] + decisionProperty.width / 2 + 75 + processProperty.width / 2, decisionPoint[1]];
|
|
1612
|
+
const processElement2 = createGeometryElement(FlowchartSymbols.process, getDefaultGeometryPoints(FlowchartSymbols.process, processPoint2), '过程', options);
|
|
1613
|
+
const endPoint = [decisionPoint[0], decisionPoint[1] + decisionProperty.height / 2 + 95 + terminalProperty.height / 2];
|
|
1614
|
+
const endElement = createGeometryElement(FlowchartSymbols.terminal, getDefaultGeometryPoints(FlowchartSymbols.terminal, endPoint), '结束', options);
|
|
1615
|
+
const line1 = createLineElement(LineShape.elbow, [
|
|
1616
|
+
[0, 0],
|
|
1617
|
+
[0, 0]
|
|
1618
|
+
], { marker: LineMarkerType.none, connection: [0.5, 1], boundId: startElement.id }, { marker: LineMarkerType.arrow, connection: [0.5, 0], boundId: processElement1.id }, [], lineOptions);
|
|
1619
|
+
const line2 = createLineElement(LineShape.elbow, [
|
|
1620
|
+
[0, 0],
|
|
1621
|
+
[0, 0]
|
|
1622
|
+
], { marker: LineMarkerType.none, connection: [0.5, 1], boundId: processElement1.id }, { marker: LineMarkerType.arrow, connection: [0.5, 0], boundId: decisionElement.id }, [], lineOptions);
|
|
1623
|
+
const line3 = createLineElement(LineShape.elbow, [
|
|
1624
|
+
[0, 0],
|
|
1625
|
+
[0, 0]
|
|
1626
|
+
], { marker: LineMarkerType.none, connection: [0.5, 1], boundId: decisionElement.id }, { marker: LineMarkerType.arrow, connection: [0.5, 0], boundId: endElement.id }, [
|
|
1627
|
+
{
|
|
1628
|
+
text: buildText('是'),
|
|
1629
|
+
position: 0.5,
|
|
1630
|
+
width: 14,
|
|
1631
|
+
height: 20
|
|
1632
|
+
}
|
|
1633
|
+
], lineOptions);
|
|
1634
|
+
const line4 = createLineElement(LineShape.elbow, [
|
|
1635
|
+
[0, 0],
|
|
1636
|
+
[0, 0]
|
|
1637
|
+
], { marker: LineMarkerType.none, connection: [1, 0.5], boundId: decisionElement.id }, { marker: LineMarkerType.arrow, connection: [0, 0.5], boundId: processElement2.id }, [
|
|
1638
|
+
{
|
|
1639
|
+
text: buildText('否'),
|
|
1640
|
+
position: 0.5,
|
|
1641
|
+
width: 14,
|
|
1642
|
+
height: 20
|
|
1643
|
+
}
|
|
1644
|
+
], lineOptions);
|
|
1645
|
+
const line5 = createLineElement(LineShape.elbow, [
|
|
1646
|
+
[0, 0],
|
|
1647
|
+
[0, 0]
|
|
1648
|
+
], { marker: LineMarkerType.none, connection: [0.5, 1], boundId: processElement2.id }, { marker: LineMarkerType.arrow, connection: [1, 0.5], boundId: endElement.id }, [], lineOptions);
|
|
1649
|
+
return [startElement, processElement1, decisionElement, processElement2, endElement, line1, line2, line3, line4, line5];
|
|
1650
|
+
};
|
|
1651
|
+
|
|
1652
|
+
const drawLineArrow = (element, points, options) => {
|
|
1653
|
+
const arrowG = createG();
|
|
1654
|
+
if (PlaitLine.isSourceMark(element, LineMarkerType.none) && PlaitLine.isTargetMark(element, LineMarkerType.none)) {
|
|
1655
|
+
return null;
|
|
1656
|
+
}
|
|
1657
|
+
if (!PlaitLine.isSourceMark(element, LineMarkerType.none)) {
|
|
1658
|
+
const source = getExtendPoint(points[0], points[1], 24);
|
|
1659
|
+
const sourceArrow = getArrow(element, { marker: element.source.marker, source, target: points[0], isSource: true }, options);
|
|
1660
|
+
sourceArrow && arrowG.appendChild(sourceArrow);
|
|
1661
|
+
}
|
|
1662
|
+
if (!PlaitLine.isTargetMark(element, LineMarkerType.none)) {
|
|
1663
|
+
const source = getExtendPoint(points[points.length - 1], points[points.length - 2], 24);
|
|
1664
|
+
const arrow = getArrow(element, { marker: element.target.marker, source, target: points[points.length - 1], isSource: false }, options);
|
|
1665
|
+
arrow && arrowG.appendChild(arrow);
|
|
1666
|
+
}
|
|
1667
|
+
return arrowG;
|
|
1668
|
+
};
|
|
1669
|
+
const getArrow = (element, arrowOptions, options) => {
|
|
1670
|
+
const { marker, source, target, isSource } = arrowOptions;
|
|
1671
|
+
let targetArrow;
|
|
1672
|
+
switch (marker) {
|
|
1673
|
+
case LineMarkerType.openTriangle: {
|
|
1674
|
+
targetArrow = drawOpenTriangle(element, source, target, options);
|
|
1675
|
+
break;
|
|
1676
|
+
}
|
|
1677
|
+
case LineMarkerType.solidTriangle: {
|
|
1678
|
+
targetArrow = drawSolidTriangle(source, target, options);
|
|
1679
|
+
break;
|
|
1680
|
+
}
|
|
1681
|
+
case LineMarkerType.arrow: {
|
|
1682
|
+
targetArrow = drawArrow(element, source, target, options);
|
|
1683
|
+
break;
|
|
1684
|
+
}
|
|
1685
|
+
case LineMarkerType.sharpArrow: {
|
|
1686
|
+
targetArrow = drawSharpArrow(source, target, options);
|
|
1687
|
+
break;
|
|
1688
|
+
}
|
|
1689
|
+
case LineMarkerType.oneSideUp: {
|
|
1690
|
+
targetArrow = drawOneSideArrow(source, target, isSource ? 'down' : 'up', options);
|
|
1691
|
+
break;
|
|
1692
|
+
}
|
|
1693
|
+
case LineMarkerType.oneSideDown: {
|
|
1694
|
+
targetArrow = drawOneSideArrow(source, target, isSource ? 'up' : 'down', options);
|
|
1695
|
+
break;
|
|
1696
|
+
}
|
|
1697
|
+
case LineMarkerType.hollowTriangle: {
|
|
1698
|
+
targetArrow = drawHollowTriangleArrow(source, target, options);
|
|
1699
|
+
break;
|
|
1700
|
+
}
|
|
1701
|
+
case LineMarkerType.singleSlash: {
|
|
1702
|
+
targetArrow = drawSingleSlash(source, target, isSource, options);
|
|
1703
|
+
break;
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
return targetArrow;
|
|
1707
|
+
};
|
|
1708
|
+
const drawSharpArrow = (source, target, options) => {
|
|
1709
|
+
const startPoint = target;
|
|
1710
|
+
const { pointLeft, pointRight } = arrowPoints(source, target, 12, 20);
|
|
1711
|
+
const g = createG();
|
|
1712
|
+
const path = createPath();
|
|
1713
|
+
let polylinePath = `M${pointRight[0]},${pointRight[1]}A8,8,20,0,1,${pointLeft[0]},${pointLeft[1]}L${startPoint[0]},${startPoint[1]}Z`;
|
|
1714
|
+
path.setAttribute('d', polylinePath);
|
|
1715
|
+
path.setAttribute('stroke', `${options?.stroke}`);
|
|
1716
|
+
path.setAttribute('stroke-width', `${options?.strokeWidth}`);
|
|
1717
|
+
path.setAttribute('fill', `${options?.stroke}`);
|
|
1718
|
+
g.appendChild(path);
|
|
1719
|
+
return g;
|
|
1720
|
+
};
|
|
1721
|
+
const drawArrow = (element, source, target, options) => {
|
|
1722
|
+
const directionFactor = getFactorByPoints(source, target);
|
|
1723
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1724
|
+
const endPoint = [target[0] + (strokeWidth * directionFactor.x) / 2, target[1] + (strokeWidth * directionFactor.y) / 2];
|
|
1725
|
+
const middlePoint = [endPoint[0] - 8 * directionFactor.x, endPoint[1] - 8 * directionFactor.y];
|
|
1726
|
+
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 30);
|
|
1727
|
+
const arrowG = drawLinearPath([pointLeft, endPoint, pointRight, middlePoint], { ...options, fill: options.stroke }, true);
|
|
1728
|
+
const path = arrowG.querySelector('path');
|
|
1729
|
+
path.setAttribute('stroke-linejoin', 'round');
|
|
1730
|
+
return arrowG;
|
|
1731
|
+
};
|
|
1732
|
+
const drawSolidTriangle = (source, target, options) => {
|
|
1733
|
+
const endPoint = target;
|
|
1734
|
+
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 30);
|
|
1735
|
+
return drawLinearPath([pointLeft, endPoint, pointRight], { ...options, fill: options.stroke }, true);
|
|
1736
|
+
};
|
|
1737
|
+
const drawOpenTriangle = (element, source, target, options) => {
|
|
1738
|
+
const directionFactor = getFactorByPoints(source, target);
|
|
1739
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
1357
1740
|
const endPoint = [target[0] + (strokeWidth * directionFactor.x) / 2, target[1] + (strokeWidth * directionFactor.y) / 2];
|
|
1358
1741
|
const { pointLeft, pointRight } = arrowPoints(source, endPoint, 12, 40);
|
|
1359
1742
|
return drawLinearPath([pointLeft, endPoint, pointRight], options);
|
|
@@ -1375,13 +1758,13 @@ const drawHollowTriangleArrow = (source, target, options) => {
|
|
|
1375
1758
|
return drawLinearPath([pointLeft, pointRight, target], { ...options, fill: 'white' }, true);
|
|
1376
1759
|
};
|
|
1377
1760
|
|
|
1378
|
-
const createLineElement = (shape, points, source, target, options) => {
|
|
1761
|
+
const createLineElement = (shape, points, source, target, texts, options) => {
|
|
1379
1762
|
return {
|
|
1380
1763
|
id: idCreator(),
|
|
1381
1764
|
type: 'line',
|
|
1382
1765
|
shape,
|
|
1383
1766
|
source,
|
|
1384
|
-
texts: [],
|
|
1767
|
+
texts: texts ? texts : [],
|
|
1385
1768
|
target,
|
|
1386
1769
|
opacity: 1,
|
|
1387
1770
|
points,
|
|
@@ -1452,8 +1835,41 @@ const getLineHandleRefPair = (board, element) => {
|
|
|
1452
1835
|
const getElbowPoints = (board, element) => {
|
|
1453
1836
|
if (element.points.length === 2) {
|
|
1454
1837
|
const handleRefPair = getLineHandleRefPair(board, element);
|
|
1455
|
-
const offset = element.source.boundId || element.target.boundId ?
|
|
1456
|
-
|
|
1838
|
+
const offset = element.source.boundId || element.target.boundId ? DEFAULT_ROUTE_MARGIN : 0;
|
|
1839
|
+
const sourceElement = element.source.boundId && getElementById(board, element.source.boundId);
|
|
1840
|
+
const targetElement = element.target.boundId && getElementById(board, element.target.boundId);
|
|
1841
|
+
const isBound = sourceElement && targetElement;
|
|
1842
|
+
let points = [];
|
|
1843
|
+
if (isBound) {
|
|
1844
|
+
const targetRectangle = RectangleClient.inflate(getRectangleByPoints(targetElement.points), getStrokeWidthByElement(targetElement) * 2);
|
|
1845
|
+
const sourceRectangle = RectangleClient.inflate(getRectangleByPoints(sourceElement.points), getStrokeWidthByElement(sourceElement) * 2);
|
|
1846
|
+
const sourcePoint = handleRefPair.source.point;
|
|
1847
|
+
const targetPoint = handleRefPair.target.point;
|
|
1848
|
+
const { sourceOffset, targetOffset } = reduceRouteMargin(sourceRectangle, targetRectangle);
|
|
1849
|
+
const sourceOuterRectangle = RectangleClient.expand(sourceRectangle, sourceOffset[3], sourceOffset[0], sourceOffset[1], sourceOffset[2]);
|
|
1850
|
+
const targetOuterRectangle = RectangleClient.expand(targetRectangle, targetOffset[3], targetOffset[0], targetOffset[1], targetOffset[2]);
|
|
1851
|
+
const nextSourcePoint = getNextPoint(sourcePoint, sourceOuterRectangle, handleRefPair.source.direction);
|
|
1852
|
+
const nextTargetPoint = getNextPoint(targetPoint, targetOuterRectangle, handleRefPair.target.direction);
|
|
1853
|
+
const isIntersect = RectangleClient.isPointInRectangle(targetRectangle, sourcePoint) ||
|
|
1854
|
+
RectangleClient.isPointInRectangle(targetOuterRectangle, nextSourcePoint) ||
|
|
1855
|
+
RectangleClient.isPointInRectangle(sourceOuterRectangle, nextTargetPoint) ||
|
|
1856
|
+
RectangleClient.isPointInRectangle(sourceRectangle, targetPoint);
|
|
1857
|
+
if (!isIntersect) {
|
|
1858
|
+
points = generateElbowLineRoute({
|
|
1859
|
+
sourcePoint,
|
|
1860
|
+
nextSourcePoint,
|
|
1861
|
+
sourceRectangle,
|
|
1862
|
+
sourceOuterRectangle,
|
|
1863
|
+
targetPoint,
|
|
1864
|
+
nextTargetPoint,
|
|
1865
|
+
targetRectangle,
|
|
1866
|
+
targetOuterRectangle
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
if (!points.length) {
|
|
1871
|
+
points = getPoints(handleRefPair.source.point, handleRefPair.source.direction, handleRefPair.target.point, handleRefPair.target.direction, offset);
|
|
1872
|
+
}
|
|
1457
1873
|
points = removeDuplicatePoints(points);
|
|
1458
1874
|
return points;
|
|
1459
1875
|
}
|
|
@@ -1626,17 +2042,6 @@ const getBoardLines = (board) => {
|
|
|
1626
2042
|
recursion: (element) => PlaitDrawElement.isDrawElement(element)
|
|
1627
2043
|
});
|
|
1628
2044
|
};
|
|
1629
|
-
const removeDuplicatePoints = (points) => {
|
|
1630
|
-
const newArray = [];
|
|
1631
|
-
points.forEach(point => {
|
|
1632
|
-
const index = newArray.findIndex(otherPoint => {
|
|
1633
|
-
return point[0] === otherPoint[0] && point[1] === otherPoint[1];
|
|
1634
|
-
});
|
|
1635
|
-
if (index === -1)
|
|
1636
|
-
newArray.push(point);
|
|
1637
|
-
});
|
|
1638
|
-
return newArray;
|
|
1639
|
-
};
|
|
1640
2045
|
const getExtendPoint = (source, target, extendDistance) => {
|
|
1641
2046
|
const distance = distanceBetweenPointAndPoint(...source, ...target);
|
|
1642
2047
|
const sin = (target[1] - source[1]) / distance;
|
|
@@ -1702,6 +2107,55 @@ const getSelectedImageElements = (board) => {
|
|
|
1702
2107
|
return selectedElements;
|
|
1703
2108
|
};
|
|
1704
2109
|
|
|
2110
|
+
const isRectangleHitDrawElement = (board, element, selection) => {
|
|
2111
|
+
if (PlaitDrawElement.isGeometry(element)) {
|
|
2112
|
+
const client = getRectangleByPoints(element.points);
|
|
2113
|
+
const rangeRectangle = RectangleClient.toRectangleClient([selection.anchor, selection.focus]);
|
|
2114
|
+
if (element.textHeight > client.height) {
|
|
2115
|
+
const textClient = getTextRectangle(element);
|
|
2116
|
+
return RectangleClient.isHit(rangeRectangle, client) || RectangleClient.isHit(rangeRectangle, textClient);
|
|
2117
|
+
}
|
|
2118
|
+
return RectangleClient.isHit(rangeRectangle, client);
|
|
2119
|
+
}
|
|
2120
|
+
if (PlaitDrawElement.isImage(element)) {
|
|
2121
|
+
const client = getRectangleByPoints(element.points);
|
|
2122
|
+
const rangeRectangle = RectangleClient.toRectangleClient([selection.anchor, selection.focus]);
|
|
2123
|
+
return RectangleClient.isHit(rangeRectangle, client);
|
|
2124
|
+
}
|
|
2125
|
+
if (PlaitDrawElement.isLine(element)) {
|
|
2126
|
+
const points = getLinePoints(board, element);
|
|
2127
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
2128
|
+
const isHitText = isHitLineText(board, element, selection.focus);
|
|
2129
|
+
const isHit = isHitPolyLine(points, selection.focus, strokeWidth, 3) || isHitText;
|
|
2130
|
+
const rangeRectangle = RectangleClient.toRectangleClient([selection.anchor, selection.focus]);
|
|
2131
|
+
const isContainPolyLinePoint = points.some(point => {
|
|
2132
|
+
return RectangleClient.isHit(rangeRectangle, RectangleClient.toRectangleClient([point, point]));
|
|
2133
|
+
});
|
|
2134
|
+
const isIntersect = Point.isEquals(selection.anchor, selection.focus) ? isHit : isPolylineHitRectangle(points, rangeRectangle);
|
|
2135
|
+
return isContainPolyLinePoint || isIntersect;
|
|
2136
|
+
}
|
|
2137
|
+
return null;
|
|
2138
|
+
};
|
|
2139
|
+
const isHitDrawElement = (board, element, point) => {
|
|
2140
|
+
if (PlaitDrawElement.isGeometry(element)) {
|
|
2141
|
+
const fill = getFillByElement(element);
|
|
2142
|
+
if (fill !== DefaultGeometryStyle.fill && fill !== TRANSPARENT) {
|
|
2143
|
+
return isRectangleHitDrawElement(board, element, { anchor: point, focus: point });
|
|
2144
|
+
}
|
|
2145
|
+
else {
|
|
2146
|
+
const strokeWidth = getStrokeWidthByElement(element);
|
|
2147
|
+
const engine = getEngine(getShape(element));
|
|
2148
|
+
const corners = engine.getCornerPoints(getRectangleByPoints(element.points));
|
|
2149
|
+
const isHit = isHitPolyLine(corners, point, strokeWidth, 3);
|
|
2150
|
+
return isHit;
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
if (PlaitDrawElement.isImage(element) || PlaitDrawElement.isLine(element)) {
|
|
2154
|
+
return isRectangleHitDrawElement(board, element, { anchor: point, focus: point });
|
|
2155
|
+
}
|
|
2156
|
+
return null;
|
|
2157
|
+
};
|
|
2158
|
+
|
|
1705
2159
|
var LineMarkerType;
|
|
1706
2160
|
(function (LineMarkerType) {
|
|
1707
2161
|
LineMarkerType["arrow"] = "arrow";
|
|
@@ -1773,195 +2227,40 @@ const PlaitLine = {
|
|
|
1773
2227
|
|
|
1774
2228
|
var StrokeStyle;
|
|
1775
2229
|
(function (StrokeStyle) {
|
|
1776
|
-
StrokeStyle["solid"] = "solid";
|
|
1777
|
-
StrokeStyle["dashed"] = "dashed";
|
|
1778
|
-
})(StrokeStyle || (StrokeStyle = {}));
|
|
1779
|
-
|
|
1780
|
-
const PlaitDrawElement = {
|
|
1781
|
-
isGeometry: (value) => {
|
|
1782
|
-
return value.type === 'geometry';
|
|
1783
|
-
},
|
|
1784
|
-
isLine: (value) => {
|
|
1785
|
-
return value.type === 'line';
|
|
1786
|
-
},
|
|
1787
|
-
isText: (value) => {
|
|
1788
|
-
return value.type === 'geometry' && value.shape === BasicShapes.text;
|
|
1789
|
-
},
|
|
1790
|
-
isImage: (value) => {
|
|
1791
|
-
return value.type === 'image';
|
|
1792
|
-
},
|
|
1793
|
-
isDrawElement: (value) => {
|
|
1794
|
-
if (PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isLine(value) || PlaitDrawElement.isImage(value)) {
|
|
1795
|
-
return true;
|
|
1796
|
-
}
|
|
1797
|
-
else {
|
|
1798
|
-
return false;
|
|
1799
|
-
}
|
|
1800
|
-
},
|
|
1801
|
-
isShape: (value) => {
|
|
1802
|
-
return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value);
|
|
1803
|
-
},
|
|
1804
|
-
isBaseShape: (value) => {
|
|
1805
|
-
return Object.keys(BasicShapes).includes(value.type);
|
|
1806
|
-
},
|
|
1807
|
-
isFlowchart: (value) => {
|
|
1808
|
-
return Object.keys(FlowchartSymbols).includes(value.type);
|
|
1809
|
-
}
|
|
1810
|
-
};
|
|
1811
|
-
|
|
1812
|
-
class GeometryShapeGenerator extends Generator {
|
|
1813
|
-
canDraw(element, data) {
|
|
1814
|
-
return true;
|
|
1815
|
-
}
|
|
1816
|
-
baseDraw(element, data) {
|
|
1817
|
-
const rectangle = getRectangleByPoints(element.points);
|
|
1818
|
-
const shape = element.shape;
|
|
1819
|
-
if (shape === BasicShapes.text) {
|
|
1820
|
-
return;
|
|
1821
|
-
}
|
|
1822
|
-
const strokeWidth = getStrokeWidthByElement(element);
|
|
1823
|
-
const strokeColor = getStrokeColorByElement(element);
|
|
1824
|
-
const fill = getFillByElement(element);
|
|
1825
|
-
const strokeLineDash = getLineDashByElement(element);
|
|
1826
|
-
return drawGeometry(this.board, RectangleClient.inflate(rectangle, -strokeWidth), shape, {
|
|
1827
|
-
stroke: strokeColor,
|
|
1828
|
-
strokeWidth,
|
|
1829
|
-
fill,
|
|
1830
|
-
strokeLineDash
|
|
1831
|
-
});
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
|
|
1835
|
-
const insertGeometry = (board, points, shape) => {
|
|
1836
|
-
let newElement = createGeometryElement(shape, points, '', {
|
|
1837
|
-
strokeColor: DefaultBasicShapeProperty.strokeColor,
|
|
1838
|
-
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
1839
|
-
});
|
|
1840
|
-
Transforms.insertNode(board, newElement, [board.children.length]);
|
|
1841
|
-
clearSelectedElement(board);
|
|
1842
|
-
addSelectedElement(board, newElement);
|
|
1843
|
-
};
|
|
1844
|
-
const insertText = (board, points, text = '文本') => {
|
|
1845
|
-
let newElement = createGeometryElement(BasicShapes.text, points, text);
|
|
1846
|
-
Transforms.insertNode(board, newElement, [board.children.length]);
|
|
1847
|
-
clearSelectedElement(board);
|
|
1848
|
-
addSelectedElement(board, newElement);
|
|
1849
|
-
};
|
|
1850
|
-
const resizeGeometry = (board, points, textHeight, path) => {
|
|
1851
|
-
const normalizePoints = normalizeShapePoints(points);
|
|
1852
|
-
const element = PlaitNode.get(board, path);
|
|
1853
|
-
const newHeight = textHeight / board.viewport.zoom;
|
|
1854
|
-
const newProperties = { points: normalizePoints, textHeight: newHeight };
|
|
1855
|
-
if (PlaitDrawElement.isText(element) && element.autoSize) {
|
|
1856
|
-
newProperties.autoSize = false;
|
|
1857
|
-
}
|
|
1858
|
-
Transforms.setNode(board, newProperties, path);
|
|
1859
|
-
};
|
|
1860
|
-
|
|
1861
|
-
const normalizePoints = (board, element, width, textHeight) => {
|
|
1862
|
-
let points = element.points;
|
|
1863
|
-
let autoSize = element.autoSize;
|
|
1864
|
-
const defaultSpace = ShapeDefaultSpace.rectangleAndText;
|
|
1865
|
-
if (autoSize) {
|
|
1866
|
-
const editor = PlaitGeometry.getTextEditor(element);
|
|
1867
|
-
if (AlignEditor.isActive(editor, Alignment.right)) {
|
|
1868
|
-
points = [
|
|
1869
|
-
[points[1][0] - (width + defaultSpace * 2), points[0][1]],
|
|
1870
|
-
[points[1][0], points[0][1] + textHeight]
|
|
1871
|
-
];
|
|
1872
|
-
}
|
|
1873
|
-
else if (AlignEditor.isActive(editor, Alignment.center)) {
|
|
1874
|
-
const oldWidth = Math.abs(points[0][0] - points[1][0]);
|
|
1875
|
-
const offset = (width - oldWidth) / 2;
|
|
1876
|
-
points = [
|
|
1877
|
-
[points[0][0] - offset - defaultSpace, points[0][1]],
|
|
1878
|
-
[points[1][0] + offset + defaultSpace, points[0][1] + textHeight]
|
|
1879
|
-
];
|
|
1880
|
-
}
|
|
1881
|
-
else {
|
|
1882
|
-
points = [points[0], [points[0][0] + width + defaultSpace * 2, points[0][1] + textHeight]];
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
return { points };
|
|
1886
|
-
};
|
|
1887
|
-
const setText = (board, element, text, width, textHeight) => {
|
|
1888
|
-
const newElement = {
|
|
1889
|
-
text,
|
|
1890
|
-
textHeight,
|
|
1891
|
-
...normalizePoints(board, element, width, textHeight)
|
|
1892
|
-
};
|
|
1893
|
-
const path = board.children.findIndex(child => child === element);
|
|
1894
|
-
Transforms.setNode(board, newElement, [path]);
|
|
1895
|
-
};
|
|
1896
|
-
const setTextSize = (board, element, textWidth, textHeight) => {
|
|
1897
|
-
if (element.autoSize) {
|
|
1898
|
-
const newElement = {
|
|
1899
|
-
textHeight,
|
|
1900
|
-
...normalizePoints(board, element, textWidth, textHeight)
|
|
1901
|
-
};
|
|
1902
|
-
const isPointsEqual = Point.isEquals(element.points[0], newElement.points[0]) && Point.isEquals(element.points[1], newElement.points[1]);
|
|
1903
|
-
const isTextHeightEqual = Math.round(textHeight) === Math.round(element.textHeight);
|
|
1904
|
-
if (!isPointsEqual || !isTextHeightEqual) {
|
|
1905
|
-
const path = board.children.findIndex(child => child === element);
|
|
1906
|
-
Transforms.setNode(board, newElement, [path]);
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
|
-
};
|
|
1910
|
-
|
|
1911
|
-
const insertImage = (board, imageItem, startPoint) => {
|
|
1912
|
-
const { width, height, url } = imageItem;
|
|
1913
|
-
const host = BOARD_TO_HOST.get(board);
|
|
1914
|
-
const viewportWidth = PlaitBoard.getComponent(board).nativeElement.clientWidth;
|
|
1915
|
-
const viewportHeight = PlaitBoard.getComponent(board).nativeElement.clientHeight;
|
|
1916
|
-
const point = transformPoint(board, toPoint(viewportWidth / 2, viewportHeight / 2, host));
|
|
1917
|
-
const points = startPoint
|
|
1918
|
-
? [startPoint, [startPoint[0] + width, startPoint[1] + height]]
|
|
1919
|
-
: [
|
|
1920
|
-
[point[0] - width / 2, point[1] - height / 2],
|
|
1921
|
-
[point[0] + width / 2, point[1] + height / 2]
|
|
1922
|
-
];
|
|
1923
|
-
const imageElement = {
|
|
1924
|
-
id: idCreator(),
|
|
1925
|
-
type: 'image',
|
|
1926
|
-
points,
|
|
1927
|
-
url
|
|
1928
|
-
};
|
|
1929
|
-
Transforms.insertNode(board, imageElement, [board.children.length]);
|
|
1930
|
-
Transforms.addSelectionWithTemporaryElements(board, [imageElement]);
|
|
1931
|
-
};
|
|
1932
|
-
|
|
1933
|
-
const resizeLine = (board, options, path) => {
|
|
1934
|
-
Transforms.setNode(board, options, path);
|
|
1935
|
-
};
|
|
1936
|
-
const setLineTexts = (board, element, texts) => {
|
|
1937
|
-
const path = PlaitBoard.findPath(board, element);
|
|
1938
|
-
Transforms.setNode(board, { texts }, path);
|
|
1939
|
-
};
|
|
1940
|
-
const removeLineText = (board, element, index) => {
|
|
1941
|
-
const path = PlaitBoard.findPath(board, element);
|
|
1942
|
-
const texts = element.texts?.length ? [...element.texts] : [];
|
|
1943
|
-
const newTexts = [...texts];
|
|
1944
|
-
newTexts.splice(index, 1);
|
|
1945
|
-
Transforms.setNode(board, { texts: newTexts }, path);
|
|
1946
|
-
};
|
|
1947
|
-
const setLineMark = (board, element, handleKey, marker) => {
|
|
1948
|
-
const path = PlaitBoard.findPath(board, element);
|
|
1949
|
-
let handle = handleKey === LineHandleKey.source ? element.source : element.target;
|
|
1950
|
-
handle = { ...handle, marker };
|
|
1951
|
-
Transforms.setNode(board, { [handleKey]: handle }, path);
|
|
1952
|
-
};
|
|
2230
|
+
StrokeStyle["solid"] = "solid";
|
|
2231
|
+
StrokeStyle["dashed"] = "dashed";
|
|
2232
|
+
})(StrokeStyle || (StrokeStyle = {}));
|
|
1953
2233
|
|
|
1954
|
-
const
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
2234
|
+
const PlaitDrawElement = {
|
|
2235
|
+
isGeometry: (value) => {
|
|
2236
|
+
return value.type === 'geometry';
|
|
2237
|
+
},
|
|
2238
|
+
isLine: (value) => {
|
|
2239
|
+
return value.type === 'line';
|
|
2240
|
+
},
|
|
2241
|
+
isText: (value) => {
|
|
2242
|
+
return value.type === 'geometry' && value.shape === BasicShapes.text;
|
|
2243
|
+
},
|
|
2244
|
+
isImage: (value) => {
|
|
2245
|
+
return value.type === 'image';
|
|
2246
|
+
},
|
|
2247
|
+
isDrawElement: (value) => {
|
|
2248
|
+
if (PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isLine(value) || PlaitDrawElement.isImage(value)) {
|
|
2249
|
+
return true;
|
|
2250
|
+
}
|
|
2251
|
+
else {
|
|
2252
|
+
return false;
|
|
2253
|
+
}
|
|
2254
|
+
},
|
|
2255
|
+
isShape: (value) => {
|
|
2256
|
+
return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value);
|
|
2257
|
+
},
|
|
2258
|
+
isBaseShape: (value) => {
|
|
2259
|
+
return Object.keys(BasicShapes).includes(value.type);
|
|
2260
|
+
},
|
|
2261
|
+
isFlowchart: (value) => {
|
|
2262
|
+
return Object.keys(FlowchartSymbols).includes(value.type);
|
|
2263
|
+
}
|
|
1965
2264
|
};
|
|
1966
2265
|
|
|
1967
2266
|
class GeometryComponent extends CommonPluginElement {
|
|
@@ -2362,172 +2661,6 @@ const withDrawHotkey = (board) => {
|
|
|
2362
2661
|
return board;
|
|
2363
2662
|
};
|
|
2364
2663
|
|
|
2365
|
-
const withGeometryCreateByDrag = (board) => {
|
|
2366
|
-
const { pointerMove, pointerUp } = board;
|
|
2367
|
-
let geometryShapeG = null;
|
|
2368
|
-
board.pointerMove = (event) => {
|
|
2369
|
-
geometryShapeG?.remove();
|
|
2370
|
-
geometryShapeG = createG();
|
|
2371
|
-
const geometryGenerator = new GeometryShapeGenerator(board);
|
|
2372
|
-
const geometryPointers = getGeometryPointers();
|
|
2373
|
-
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
2374
|
-
const dragMode = isGeometryPointer && isDndMode(board);
|
|
2375
|
-
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
2376
|
-
const pointer = PlaitBoard.getPointer(board);
|
|
2377
|
-
if (dragMode) {
|
|
2378
|
-
const points = getDefaultGeometryPoints(pointer, movingPoint);
|
|
2379
|
-
if (pointer === BasicShapes.text) {
|
|
2380
|
-
const textG = getTemporaryTextG(movingPoint);
|
|
2381
|
-
geometryShapeG.appendChild(textG);
|
|
2382
|
-
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
2383
|
-
}
|
|
2384
|
-
else {
|
|
2385
|
-
const temporaryElement = createGeometryElement(pointer, points, '', {
|
|
2386
|
-
strokeColor: DefaultBasicShapeProperty.strokeColor,
|
|
2387
|
-
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
2388
|
-
});
|
|
2389
|
-
geometryGenerator.draw(temporaryElement, geometryShapeG);
|
|
2390
|
-
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
2391
|
-
}
|
|
2392
|
-
}
|
|
2393
|
-
pointerMove(event);
|
|
2394
|
-
};
|
|
2395
|
-
board.pointerUp = (event) => {
|
|
2396
|
-
const pointer = PlaitBoard.getPointer(board);
|
|
2397
|
-
const geometryPointers = getGeometryPointers();
|
|
2398
|
-
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
2399
|
-
const dragMode = isGeometryPointer && isDndMode(board);
|
|
2400
|
-
if (dragMode) {
|
|
2401
|
-
const targetPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
2402
|
-
const points = getDefaultGeometryPoints(pointer, targetPoint);
|
|
2403
|
-
if (pointer === BasicShapes.text) {
|
|
2404
|
-
DrawTransforms.insertText(board, points);
|
|
2405
|
-
}
|
|
2406
|
-
else {
|
|
2407
|
-
DrawTransforms.insertGeometry(board, points, pointer);
|
|
2408
|
-
}
|
|
2409
|
-
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
2410
|
-
}
|
|
2411
|
-
geometryShapeG?.remove();
|
|
2412
|
-
geometryShapeG = null;
|
|
2413
|
-
preventTouchMove(board, event, false);
|
|
2414
|
-
pointerUp(event);
|
|
2415
|
-
};
|
|
2416
|
-
return board;
|
|
2417
|
-
};
|
|
2418
|
-
const withGeometryCreateByDrawing = (board) => {
|
|
2419
|
-
const { pointerDown, pointerMove, pointerUp, keydown, keyup } = board;
|
|
2420
|
-
let start = null;
|
|
2421
|
-
let geometryShapeG = null;
|
|
2422
|
-
let temporaryElement = null;
|
|
2423
|
-
let isShift = false;
|
|
2424
|
-
board.keydown = (event) => {
|
|
2425
|
-
isShift = isKeyHotkey('shift', event);
|
|
2426
|
-
keydown(event);
|
|
2427
|
-
};
|
|
2428
|
-
board.keyup = (event) => {
|
|
2429
|
-
isShift = false;
|
|
2430
|
-
keyup(event);
|
|
2431
|
-
};
|
|
2432
|
-
board.pointerDown = (event) => {
|
|
2433
|
-
const geometryPointers = getGeometryPointers();
|
|
2434
|
-
const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
|
|
2435
|
-
if (isGeometryPointer && isDrawingMode(board)) {
|
|
2436
|
-
const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
2437
|
-
start = point;
|
|
2438
|
-
const pointer = PlaitBoard.getPointer(board);
|
|
2439
|
-
preventTouchMove(board, event, true);
|
|
2440
|
-
if (pointer === BasicShapes.text) {
|
|
2441
|
-
const points = getDefaultGeometryPoints(pointer, point);
|
|
2442
|
-
const textElement = createGeometryElement(BasicShapes.text, points, DefaultTextProperty.text);
|
|
2443
|
-
Transforms.insertNode(board, textElement, [board.children.length]);
|
|
2444
|
-
clearSelectedElement(board);
|
|
2445
|
-
addSelectedElement(board, textElement);
|
|
2446
|
-
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
2447
|
-
start = null;
|
|
2448
|
-
}
|
|
2449
|
-
}
|
|
2450
|
-
pointerDown(event);
|
|
2451
|
-
};
|
|
2452
|
-
board.pointerMove = (event) => {
|
|
2453
|
-
geometryShapeG?.remove();
|
|
2454
|
-
geometryShapeG = createG();
|
|
2455
|
-
const geometryGenerator = new GeometryShapeGenerator(board);
|
|
2456
|
-
const drawMode = !!start;
|
|
2457
|
-
const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
2458
|
-
const pointer = PlaitBoard.getPointer(board);
|
|
2459
|
-
if (drawMode && pointer !== BasicShapes.text) {
|
|
2460
|
-
const points = normalizeShapePoints([start, movingPoint], isShift);
|
|
2461
|
-
temporaryElement = createGeometryElement(pointer, points, '', {
|
|
2462
|
-
strokeColor: DefaultBasicShapeProperty.strokeColor,
|
|
2463
|
-
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
2464
|
-
});
|
|
2465
|
-
geometryGenerator.draw(temporaryElement, geometryShapeG);
|
|
2466
|
-
PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
|
|
2467
|
-
}
|
|
2468
|
-
pointerMove(event);
|
|
2469
|
-
};
|
|
2470
|
-
board.pointerUp = (event) => {
|
|
2471
|
-
const isDrawMode = !!start;
|
|
2472
|
-
if (isDrawMode) {
|
|
2473
|
-
const targetPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
2474
|
-
const { width, height } = RectangleClient.toRectangleClient([start, targetPoint]);
|
|
2475
|
-
if (Math.hypot(width, height) === 0) {
|
|
2476
|
-
const pointer = PlaitBoard.getPointer(board);
|
|
2477
|
-
const points = getDefaultGeometryPoints(pointer, targetPoint);
|
|
2478
|
-
if (pointer !== BasicShapes.text) {
|
|
2479
|
-
temporaryElement = createGeometryElement(pointer, points, '', {
|
|
2480
|
-
strokeColor: DefaultBasicShapeProperty.strokeColor,
|
|
2481
|
-
strokeWidth: DefaultBasicShapeProperty.strokeWidth
|
|
2482
|
-
});
|
|
2483
|
-
}
|
|
2484
|
-
}
|
|
2485
|
-
}
|
|
2486
|
-
if (temporaryElement) {
|
|
2487
|
-
Transforms.insertNode(board, temporaryElement, [board.children.length]);
|
|
2488
|
-
clearSelectedElement(board);
|
|
2489
|
-
addSelectedElement(board, temporaryElement);
|
|
2490
|
-
BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
|
|
2491
|
-
}
|
|
2492
|
-
geometryShapeG?.remove();
|
|
2493
|
-
geometryShapeG = null;
|
|
2494
|
-
start = null;
|
|
2495
|
-
temporaryElement = null;
|
|
2496
|
-
preventTouchMove(board, event, false);
|
|
2497
|
-
pointerUp(event);
|
|
2498
|
-
};
|
|
2499
|
-
return board;
|
|
2500
|
-
};
|
|
2501
|
-
const getDefaultGeometryPoints = (pointer, targetPoint) => {
|
|
2502
|
-
const defaultProperty = getGeometryDefaultProperty(pointer);
|
|
2503
|
-
return getPointsByCenterPoint(targetPoint, defaultProperty.width, defaultProperty.height);
|
|
2504
|
-
};
|
|
2505
|
-
const getGeometryDefaultProperty = (pointer) => {
|
|
2506
|
-
const isText = pointer === BasicShapes.text;
|
|
2507
|
-
const isFlowChart = getFlowchartPointers().includes(pointer);
|
|
2508
|
-
if (isText) {
|
|
2509
|
-
return DefaultTextProperty;
|
|
2510
|
-
}
|
|
2511
|
-
else if (isFlowChart) {
|
|
2512
|
-
return getDefaultFlowchartProperty(pointer);
|
|
2513
|
-
}
|
|
2514
|
-
else {
|
|
2515
|
-
return DefaultBasicShapeProperty;
|
|
2516
|
-
}
|
|
2517
|
-
};
|
|
2518
|
-
const getTemporaryTextG = (movingPoint) => {
|
|
2519
|
-
const textG = createG();
|
|
2520
|
-
const width = DefaultTextProperty.width - ShapeDefaultSpace.rectangleAndText * 2;
|
|
2521
|
-
const foreignObject = createForeignObject(movingPoint[0] - width / 2, movingPoint[1] - DefaultTextProperty.height / 2, width, DefaultTextProperty.height);
|
|
2522
|
-
const richtext = document.createElement('div');
|
|
2523
|
-
richtext.textContent = DefaultTextProperty.text;
|
|
2524
|
-
richtext.style.fontSize = `${DEFAULT_FONT_SIZE}px`;
|
|
2525
|
-
richtext.style.cursor = 'default';
|
|
2526
|
-
foreignObject.appendChild(richtext);
|
|
2527
|
-
textG.appendChild(foreignObject);
|
|
2528
|
-
return textG;
|
|
2529
|
-
};
|
|
2530
|
-
|
|
2531
2664
|
const buildClipboardData = (board, elements, startPoint) => {
|
|
2532
2665
|
return elements.map(element => {
|
|
2533
2666
|
if (PlaitDrawElement.isGeometry(element) || PlaitDrawElement.isImage(element)) {
|
|
@@ -2618,13 +2751,13 @@ const withDrawFragment = (baseBoard) => {
|
|
|
2618
2751
|
};
|
|
2619
2752
|
board.insertFragment = (data, targetPoint) => {
|
|
2620
2753
|
const elements = getDataFromClipboard(data);
|
|
2754
|
+
const selectedElements = getSelectedElements(board);
|
|
2621
2755
|
const drawElements = elements.filter(value => PlaitDrawElement.isDrawElement(value));
|
|
2622
2756
|
if (elements.length > 0 && drawElements.length > 0) {
|
|
2623
2757
|
insertClipboardData(board, drawElements, targetPoint);
|
|
2624
2758
|
}
|
|
2625
2759
|
else if (elements.length === 0) {
|
|
2626
2760
|
const text = getTextFromClipboard(data);
|
|
2627
|
-
const selectedElements = getSelectedElements(board);
|
|
2628
2761
|
// (* ̄︶ ̄)
|
|
2629
2762
|
const insertAsChildren = selectedElements.length === 1 && selectedElements[0].children;
|
|
2630
2763
|
const insertAsFreeText = !insertAsChildren;
|
|
@@ -2636,7 +2769,8 @@ const withDrawFragment = (baseBoard) => {
|
|
|
2636
2769
|
}
|
|
2637
2770
|
if (data?.files.length) {
|
|
2638
2771
|
const acceptImageArray = acceptImageTypes.map(type => 'image/' + type);
|
|
2639
|
-
|
|
2772
|
+
const canInsertionImage = !getElementOfFocusedImage(board) && !(selectedElements.length === 1 && board.isImageBindingAllowed(selectedElements[0]));
|
|
2773
|
+
if (acceptImageArray.includes(data?.files[0].type) && canInsertionImage) {
|
|
2640
2774
|
const imageFile = data.files[0];
|
|
2641
2775
|
buildImage(board, imageFile, DEFAULT_IMAGE_WIDTH, imageItem => {
|
|
2642
2776
|
DrawTransforms.insertImage(board, imageItem, targetPoint);
|
|
@@ -2653,11 +2787,6 @@ const getBoundedLineElements = (board, plaitShapes) => {
|
|
|
2653
2787
|
return lines.filter(line => plaitShapes.find(shape => PlaitLine.isBoundElementOfSource(line, shape) || PlaitLine.isBoundElementOfTarget(line, shape)));
|
|
2654
2788
|
};
|
|
2655
2789
|
|
|
2656
|
-
const DefaultLineStyle = {
|
|
2657
|
-
strokeWidth: 2,
|
|
2658
|
-
strokeColor: '#000'
|
|
2659
|
-
};
|
|
2660
|
-
|
|
2661
2790
|
const getHitGeometryResizeHandleRef = (board, element, point) => {
|
|
2662
2791
|
const rectangle = getRectangleByPoints(element.points);
|
|
2663
2792
|
const resizeHandleRefs = getRectangleResizeHandleRefs(rectangle, RESIZE_HANDLE_DIAMETER);
|
|
@@ -2714,7 +2843,7 @@ const withLineCreateByDraw = (board) => {
|
|
|
2714
2843
|
targetRef.boundId = hitElement ? hitElement.id : undefined;
|
|
2715
2844
|
const lineGenerator = new LineShapeGenerator(board);
|
|
2716
2845
|
const lineShape = PlaitBoard.getPointer(board);
|
|
2717
|
-
temporaryElement = createLineElement(lineShape, [start, movingPoint], { marker: LineMarkerType.none, connection: sourceRef.connection, boundId: sourceRef?.boundId }, { marker: LineMarkerType.arrow, connection: targetRef.connection, boundId: targetRef?.boundId }, {
|
|
2846
|
+
temporaryElement = createLineElement(lineShape, [start, movingPoint], { marker: LineMarkerType.none, connection: sourceRef.connection, boundId: sourceRef?.boundId }, { marker: LineMarkerType.arrow, connection: targetRef.connection, boundId: targetRef?.boundId }, [], {
|
|
2718
2847
|
strokeColor: DefaultLineStyle.strokeColor,
|
|
2719
2848
|
strokeWidth: DefaultLineStyle.strokeWidth
|
|
2720
2849
|
});
|
|
@@ -2781,24 +2910,31 @@ const withGeometryResize = (board) => {
|
|
|
2781
2910
|
let points = [...resizeRef.element.points];
|
|
2782
2911
|
const rectangle = getRectangleByPoints(resizeRef.element.points);
|
|
2783
2912
|
const ratio = rectangle.height / rectangle.width;
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
if (resizeRef.handle === ResizeHandle.ne) {
|
|
2788
|
-
points = [resizeState.endTransformPoint, [resizeRef.element.points[0][0], resizeRef.element.points[1][1]]];
|
|
2789
|
-
}
|
|
2790
|
-
if (resizeRef.handle === ResizeHandle.se) {
|
|
2791
|
-
points = [resizeState.endTransformPoint, resizeRef.element.points[0]];
|
|
2792
|
-
}
|
|
2793
|
-
if (resizeRef.handle === ResizeHandle.sw) {
|
|
2794
|
-
points = [resizeState.endTransformPoint, [resizeRef.element.points[1][0], resizeRef.element.points[0][1]]];
|
|
2795
|
-
}
|
|
2796
|
-
if (isShift || PlaitDrawElement.isImage(resizeRef.element)) {
|
|
2913
|
+
const isCornerHandle = [ResizeHandle.nw, ResizeHandle.ne, ResizeHandle.se, ResizeHandle.sw].includes(resizeRef.handle);
|
|
2914
|
+
points = getPointsByResizeHandle(resizeState.endTransformPoint, resizeRef.element.points, resizeRef.handle);
|
|
2915
|
+
if ((isShift || PlaitDrawElement.isImage(resizeRef.element)) && isCornerHandle) {
|
|
2797
2916
|
const rectangle = getRectangleByPoints(points);
|
|
2798
2917
|
const factor = points[0][1] > points[1][1] ? 1 : -1;
|
|
2799
2918
|
const height = rectangle.width * ratio * factor;
|
|
2800
2919
|
points = [[resizeState.endTransformPoint[0], points[1][1] + height], points[1]];
|
|
2801
2920
|
}
|
|
2921
|
+
if ((isShift || PlaitDrawElement.isImage(resizeRef.element)) && !isCornerHandle) {
|
|
2922
|
+
const rectangle = getRectangleByPoints(points);
|
|
2923
|
+
if (resizeRef.handle === ResizeHandle.n || resizeRef.handle === ResizeHandle.s) {
|
|
2924
|
+
const newWidth = rectangle.height / ratio;
|
|
2925
|
+
const offset = (newWidth - rectangle.width) / 2;
|
|
2926
|
+
const newRectangle = RectangleClient.expand(rectangle, offset, 0);
|
|
2927
|
+
const cornerPoints = RectangleClient.getCornerPoints(newRectangle);
|
|
2928
|
+
points = [cornerPoints[0], cornerPoints[2]];
|
|
2929
|
+
}
|
|
2930
|
+
if (resizeRef.handle === ResizeHandle.e || resizeRef.handle === ResizeHandle.w) {
|
|
2931
|
+
const newHeight = rectangle.width * ratio;
|
|
2932
|
+
const offset = (newHeight - rectangle.height) / 2;
|
|
2933
|
+
const newRectangle = RectangleClient.expand(rectangle, 0, offset);
|
|
2934
|
+
const cornerPoints = RectangleClient.getCornerPoints(newRectangle);
|
|
2935
|
+
points = [cornerPoints[0], cornerPoints[2]];
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2802
2938
|
if (PlaitDrawElement.isGeometry(resizeRef.element)) {
|
|
2803
2939
|
const { height: textHeight } = PlaitGeometry.getTextManage(resizeRef.element).getSize();
|
|
2804
2940
|
DrawTransforms.resizeGeometry(board, points, textHeight, resizeRef.path);
|
|
@@ -2812,6 +2948,34 @@ const withGeometryResize = (board) => {
|
|
|
2812
2948
|
withResize(board, options);
|
|
2813
2949
|
return board;
|
|
2814
2950
|
};
|
|
2951
|
+
const getPointsByResizeHandle = (movingPoint, elementPoints, handle) => {
|
|
2952
|
+
switch (handle) {
|
|
2953
|
+
case ResizeHandle.nw: {
|
|
2954
|
+
return [movingPoint, elementPoints[1]];
|
|
2955
|
+
}
|
|
2956
|
+
case ResizeHandle.ne: {
|
|
2957
|
+
return [movingPoint, [elementPoints[0][0], elementPoints[1][1]]];
|
|
2958
|
+
}
|
|
2959
|
+
case ResizeHandle.se: {
|
|
2960
|
+
return [movingPoint, elementPoints[0]];
|
|
2961
|
+
}
|
|
2962
|
+
case ResizeHandle.sw: {
|
|
2963
|
+
return [movingPoint, [elementPoints[1][0], elementPoints[0][1]]];
|
|
2964
|
+
}
|
|
2965
|
+
case ResizeHandle.n: {
|
|
2966
|
+
return [[elementPoints[0][0], movingPoint[1]], elementPoints[1]];
|
|
2967
|
+
}
|
|
2968
|
+
case ResizeHandle.s: {
|
|
2969
|
+
return [elementPoints[0], [elementPoints[1][0], movingPoint[1]]];
|
|
2970
|
+
}
|
|
2971
|
+
case ResizeHandle.w: {
|
|
2972
|
+
return [[movingPoint[0], elementPoints[0][1]], elementPoints[1]];
|
|
2973
|
+
}
|
|
2974
|
+
default: {
|
|
2975
|
+
return [elementPoints[0], [movingPoint[0], elementPoints[1][1]]];
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
};
|
|
2815
2979
|
|
|
2816
2980
|
var LineResizeHandle;
|
|
2817
2981
|
(function (LineResizeHandle) {
|
|
@@ -2882,17 +3046,23 @@ const withLineResize = (board) => {
|
|
|
2882
3046
|
let points = [...resizeRef.element.points];
|
|
2883
3047
|
let source = { ...resizeRef.element.source };
|
|
2884
3048
|
let target = { ...resizeRef.element.target };
|
|
2885
|
-
if (resizeRef.handle === LineResizeHandle.source) {
|
|
3049
|
+
if (resizeRef.handle === LineResizeHandle.source || resizeRef.handle === LineResizeHandle.target) {
|
|
3050
|
+
const object = resizeRef.handle === LineResizeHandle.source ? source : target;
|
|
2886
3051
|
points[pointIndex] = resizeState.endTransformPoint;
|
|
2887
3052
|
const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, -4);
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
3053
|
+
if (hitElement) {
|
|
3054
|
+
object.connection = transformPointToConnection(board, resizeState.endTransformPoint, hitElement);
|
|
3055
|
+
object.boundId = hitElement.id;
|
|
3056
|
+
}
|
|
3057
|
+
else {
|
|
3058
|
+
object.connection = undefined;
|
|
3059
|
+
object.boundId = undefined;
|
|
3060
|
+
if (points.length === 2) {
|
|
3061
|
+
let movingPoint = points[pointIndex];
|
|
3062
|
+
const otherPoint = points[Number(!pointIndex)];
|
|
3063
|
+
points[pointIndex] = alignPoints(otherPoint, movingPoint);
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
2896
3066
|
}
|
|
2897
3067
|
else if (resizeRef.handle === LineResizeHandle.addHandle) {
|
|
2898
3068
|
points.splice(pointIndex + 1, 0, resizeState.endTransformPoint);
|
|
@@ -2906,6 +3076,17 @@ const withLineResize = (board) => {
|
|
|
2906
3076
|
withResize(board, options);
|
|
2907
3077
|
return board;
|
|
2908
3078
|
};
|
|
3079
|
+
const alignPoints = (basePoint, movingPoint) => {
|
|
3080
|
+
const offset = 3;
|
|
3081
|
+
const newPoint = [...movingPoint];
|
|
3082
|
+
if (Point.isVerticalAlign(newPoint, basePoint, offset)) {
|
|
3083
|
+
newPoint[0] = basePoint[0];
|
|
3084
|
+
}
|
|
3085
|
+
if (Point.isHorizontalAlign(newPoint, basePoint, offset)) {
|
|
3086
|
+
newPoint[1] = basePoint[1];
|
|
3087
|
+
}
|
|
3088
|
+
return newPoint;
|
|
3089
|
+
};
|
|
2909
3090
|
|
|
2910
3091
|
const withLineBoundReaction = (board) => {
|
|
2911
3092
|
const { pointerMove, pointerUp } = board;
|
|
@@ -2953,9 +3134,9 @@ const withLineText = (board) => {
|
|
|
2953
3134
|
const { dblclick } = board;
|
|
2954
3135
|
board.dblclick = (event) => {
|
|
2955
3136
|
const clickPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
|
|
2956
|
-
const hitTarget =
|
|
3137
|
+
const hitTarget = getHitElementByPoint(board, clickPoint, (element) => {
|
|
2957
3138
|
return PlaitDrawElement.isLine(element);
|
|
2958
|
-
})
|
|
3139
|
+
});
|
|
2959
3140
|
if (hitTarget) {
|
|
2960
3141
|
const points = getLinePoints(board, hitTarget);
|
|
2961
3142
|
const point = getNearestPointBetweenPointAndSegments(clickPoint, points);
|
|
@@ -3064,7 +3245,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
3064
3245
|
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
|
|
3065
3246
|
|
|
3066
3247
|
const withDraw = (board) => {
|
|
3067
|
-
const { drawElement, getRectangle,
|
|
3248
|
+
const { drawElement, getRectangle, isRectangleHit, isHit, isMovable, isAlign } = board;
|
|
3068
3249
|
board.drawElement = (context) => {
|
|
3069
3250
|
if (PlaitDrawElement.isGeometry(context.element)) {
|
|
3070
3251
|
return GeometryComponent;
|
|
@@ -3090,34 +3271,19 @@ const withDraw = (board) => {
|
|
|
3090
3271
|
}
|
|
3091
3272
|
return getRectangle(element);
|
|
3092
3273
|
};
|
|
3093
|
-
board.
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
if (element.textHeight > client.height) {
|
|
3098
|
-
const textClient = getTextRectangle(element);
|
|
3099
|
-
return RectangleClient.isHit(rangeRectangle, client) || RectangleClient.isHit(rangeRectangle, textClient);
|
|
3100
|
-
}
|
|
3101
|
-
return RectangleClient.isHit(rangeRectangle, client);
|
|
3102
|
-
}
|
|
3103
|
-
if (PlaitDrawElement.isImage(element)) {
|
|
3104
|
-
const client = getRectangleByPoints(element.points);
|
|
3105
|
-
const rangeRectangle = RectangleClient.toRectangleClient([range.anchor, range.focus]);
|
|
3106
|
-
return RectangleClient.isHit(rangeRectangle, client);
|
|
3274
|
+
board.isRectangleHit = (element, selection) => {
|
|
3275
|
+
const result = isRectangleHitDrawElement(board, element, selection);
|
|
3276
|
+
if (result !== null) {
|
|
3277
|
+
return result;
|
|
3107
3278
|
}
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
const isContainPolyLinePoint = points.some(point => {
|
|
3115
|
-
return RectangleClient.isHit(rangeRectangle, RectangleClient.toRectangleClient([point, point]));
|
|
3116
|
-
});
|
|
3117
|
-
const isIntersect = range.anchor === range.focus ? isHit : isPolylineHitRectangle(points, rangeRectangle);
|
|
3118
|
-
return isContainPolyLinePoint || isIntersect;
|
|
3279
|
+
return isRectangleHit(element, selection);
|
|
3280
|
+
};
|
|
3281
|
+
board.isHit = (element, point) => {
|
|
3282
|
+
const result = isHitDrawElement(board, element, point);
|
|
3283
|
+
if (result !== null) {
|
|
3284
|
+
return result;
|
|
3119
3285
|
}
|
|
3120
|
-
return
|
|
3286
|
+
return isHit(element, point);
|
|
3121
3287
|
};
|
|
3122
3288
|
board.isMovable = (element) => {
|
|
3123
3289
|
if (PlaitDrawElement.isGeometry(element)) {
|
|
@@ -3152,5 +3318,5 @@ const withDraw = (board) => {
|
|
|
3152
3318
|
* Generated bundle index. Do not edit.
|
|
3153
3319
|
*/
|
|
3154
3320
|
|
|
3155
|
-
export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultBasicShapeProperty, DefaultConnectorProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultGeometryActiveStyle, DefaultGeometryStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultTextProperty, DrawTransforms, FlowchartSymbols, GeometryComponent, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, ShapeDefaultSpace, StrokeStyle, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getBasicPointers, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getEdgeOnPolygonByPoint, getElbowPoints, getExtendPoint, getFillByElement, getFlowchartPointers, getGeometryPointers, getHitConnectorPoint, getHitLineTextIndex, getLineDashByElement, getLineHandleRefPair, getLinePointers, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getVectorByConnection, isHitLineText, isHitPolyLine,
|
|
3321
|
+
export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultBasicShapeProperty, DefaultConnectorProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultGeometryActiveStyle, DefaultGeometryStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultTextProperty, DrawTransforms, FlowchartSymbols, GeometryComponent, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, ShapeDefaultSpace, StrokeStyle, createDefaultFlowchart, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getBasicPointers, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getEdgeOnPolygonByPoint, getElbowPoints, getExtendPoint, getFillByElement, getFlowchartPointers, getGeometryPointers, getHitConnectorPoint, getHitLineTextIndex, getLineDashByElement, getLineHandleRefPair, getLinePointers, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getVectorByConnection, isHitDrawElement, isHitLineText, isHitPolyLine, isRectangleHitDrawElement, transformOpsToPoints, transformPointToConnection, withDraw };
|
|
3156
3322
|
//# sourceMappingURL=plait-draw.mjs.map
|