orcasvn-react-diagrams 0.1.53 → 0.1.55

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 (27) hide show
  1. package/dist/cjs/index.js +1712 -1564
  2. package/dist/cjs/types/components/paper.d.ts +12 -12
  3. package/dist/cjs/types/components/shapes/rectangle.d.ts +1 -0
  4. package/dist/cjs/types/components/shapes/rectangularFrame.d.ts +1 -0
  5. package/dist/cjs/types/contexts/editorConfigurationContext.d.ts +4 -0
  6. package/dist/cjs/types/contexts/zoomContext.d.ts +1 -0
  7. package/dist/cjs/types/models/IEditorConfiguration.d.ts +3 -0
  8. package/dist/cjs/types/models/IEditorContext.d.ts +13 -11
  9. package/dist/cjs/types/models/IElementSelectorProps.d.ts +1 -0
  10. package/dist/cjs/types/models/implementations/EditorContext.d.ts +11 -8
  11. package/dist/cjs/types/models/implementations/Element.d.ts +1 -1
  12. package/dist/cjs/types/utils/positionUtil.d.ts +1 -1
  13. package/dist/esm/index.js +1713 -1565
  14. package/dist/esm/index.js.map +1 -1
  15. package/dist/esm/types/components/paper.d.ts +12 -12
  16. package/dist/esm/types/components/shapes/rectangle.d.ts +1 -0
  17. package/dist/esm/types/components/shapes/rectangularFrame.d.ts +1 -0
  18. package/dist/esm/types/contexts/editorConfigurationContext.d.ts +4 -0
  19. package/dist/esm/types/contexts/zoomContext.d.ts +1 -0
  20. package/dist/esm/types/models/IEditorConfiguration.d.ts +3 -0
  21. package/dist/esm/types/models/IEditorContext.d.ts +13 -11
  22. package/dist/esm/types/models/IElementSelectorProps.d.ts +1 -0
  23. package/dist/esm/types/models/implementations/EditorContext.d.ts +11 -8
  24. package/dist/esm/types/models/implementations/Element.d.ts +1 -1
  25. package/dist/esm/types/utils/positionUtil.d.ts +1 -1
  26. package/dist/index.d.ts +33 -23
  27. package/package.json +1 -1
package/dist/cjs/index.js CHANGED
@@ -819,7 +819,7 @@ var EVENT_ELEMENT_MOUSE_DOWN = 'elementMouseDown';
819
819
  var EVENT_LINK_SELECTED = 'linkSelected';
820
820
  var EVENT_TEXT_SELECTED = 'textSelected';
821
821
  var EditorContext = /** @class */ (function () {
822
- function EditorContext(elements, links, texts) {
822
+ function EditorContext(elements, links, texts, configuration) {
823
823
  var _this = this;
824
824
  /** @internal */
825
825
  this.onEditorContextUpdated = function (callback) {
@@ -832,6 +832,7 @@ var EditorContext = /** @class */ (function () {
832
832
  this._elements = elements;
833
833
  this._links = links;
834
834
  this._texts = texts;
835
+ this._configuration = configuration || {};
835
836
  this._eventEmitter = new EventEmitter();
836
837
  }
837
838
  EditorContext.prototype.addEventListener = function (event, callback) {
@@ -872,6 +873,13 @@ var EditorContext = /** @class */ (function () {
872
873
  enumerable: false,
873
874
  configurable: true
874
875
  });
876
+ Object.defineProperty(EditorContext.prototype, "configuration", {
877
+ get: function () {
878
+ return this._configuration;
879
+ },
880
+ enumerable: false,
881
+ configurable: true
882
+ });
875
883
  EditorContext.prototype.getElement = function (elementId) {
876
884
  return this._elements.find(function (e) { return e.id === elementId; });
877
885
  };
@@ -949,15 +957,15 @@ var EditorContext = /** @class */ (function () {
949
957
  return this.addEventListener(EVENT_PORT_MOUSE_DOWN, callback);
950
958
  };
951
959
  /** @internal */
952
- EditorContext.prototype.onPortMouseDownHandler = function (port, element) {
953
- this._eventEmitter.emit(EVENT_PORT_MOUSE_DOWN, port, element);
960
+ EditorContext.prototype.onPortMouseDownHandler = function (port, element, paperPosition) {
961
+ this._eventEmitter.emit(EVENT_PORT_MOUSE_DOWN, port, element, paperPosition);
954
962
  };
955
963
  EditorContext.prototype.onPortMouseUp = function (callback) {
956
964
  return this.addEventListener(EVENT_PORT_MOUSE_UP, callback);
957
965
  };
958
966
  /** @internal */
959
- EditorContext.prototype.onPortMouseUpHandler = function (port, element) {
960
- this._eventEmitter.emit(EVENT_PORT_MOUSE_UP, port, element);
967
+ EditorContext.prototype.onPortMouseUpHandler = function (port, element, paperPosition) {
968
+ this._eventEmitter.emit(EVENT_PORT_MOUSE_UP, port, element, paperPosition);
961
969
  };
962
970
  EditorContext.prototype.onPortMoved = function (callback) {
963
971
  return this.addEventListener(EVENT_PORT_MOVED, callback);
@@ -984,8 +992,8 @@ var EditorContext = /** @class */ (function () {
984
992
  return this.addEventListener(EVENT_ELEMENT_MOVED, callback);
985
993
  };
986
994
  /** @internal */
987
- EditorContext.prototype.onElementMovedHandler = function (position, element) {
988
- this._eventEmitter.emit(EVENT_ELEMENT_MOVED, position, element);
995
+ EditorContext.prototype.onElementMovedHandler = function (relativePosition, element) {
996
+ this._eventEmitter.emit(EVENT_ELEMENT_MOVED, relativePosition, element);
989
997
  };
990
998
  EditorContext.prototype.onElementResized = function (callback) {
991
999
  return this.addEventListener(EVENT_ELEMENT_RESIZED, callback);
@@ -1005,29 +1013,29 @@ var EditorContext = /** @class */ (function () {
1005
1013
  return this.addEventListener(EVENT_ELEMENT_MOUSE_MOVE, callback);
1006
1014
  };
1007
1015
  /** @internal */
1008
- EditorContext.prototype.onElementMouseMoveHandler = function (ev, element) {
1009
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_MOVE, ev, element);
1016
+ EditorContext.prototype.onElementMouseMoveHandler = function (ev, element, paperPosition) {
1017
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_MOVE, ev, element, paperPosition);
1010
1018
  };
1011
1019
  EditorContext.prototype.onElementMouseLeave = function (callback) {
1012
1020
  return this.addEventListener(EVENT_ELEMENT_MOUSE_LEAVE, callback);
1013
1021
  };
1014
1022
  /** @internal */
1015
- EditorContext.prototype.onElementMouseLeaveHandler = function (ev, element) {
1016
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_LEAVE, ev, element);
1023
+ EditorContext.prototype.onElementMouseLeaveHandler = function (ev, element, paperPosition) {
1024
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_LEAVE, ev, element, paperPosition);
1017
1025
  };
1018
1026
  EditorContext.prototype.onElementMouseUp = function (callback) {
1019
1027
  return this.addEventListener(EVENT_ELEMENT_MOUSE_UP, callback);
1020
1028
  };
1021
1029
  /** @internal */
1022
- EditorContext.prototype.onElementMouseUpHandler = function (ev, element) {
1023
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_UP, ev, element);
1030
+ EditorContext.prototype.onElementMouseUpHandler = function (ev, element, paperPosition) {
1031
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_UP, ev, element, paperPosition);
1024
1032
  };
1025
1033
  EditorContext.prototype.onElementMouseDown = function (callback) {
1026
1034
  return this.addEventListener(EVENT_ELEMENT_MOUSE_DOWN, callback);
1027
1035
  };
1028
1036
  /** @internal */
1029
- EditorContext.prototype.onElementMouseDownHandler = function (ev, element) {
1030
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_DOWN, ev, element);
1037
+ EditorContext.prototype.onElementMouseDownHandler = function (ev, element, paperPosition) {
1038
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_DOWN, ev, element, paperPosition);
1031
1039
  };
1032
1040
  EditorContext.prototype.onLinkSelected = function (callback) {
1033
1041
  return this.addEventListener(EVENT_LINK_SELECTED, callback);
@@ -1110,8 +1118,20 @@ var Rectangle = React.forwardRef(function (props, ref) {
1110
1118
  scaledWidth = scaledWidth / heightRatio;
1111
1119
  }
1112
1120
  var sw = props.stroke ? (props.strokeWidth || 1) : 0;
1121
+ var strokeDasharray;
1122
+ var strokeLinecap = undefined;
1123
+ if (props.strokeStyle === 'dashed') {
1124
+ strokeDasharray = '8, 4';
1125
+ }
1126
+ else if (props.strokeStyle === 'dotted') {
1127
+ strokeDasharray = '0, 4';
1128
+ strokeLinecap = 'round';
1129
+ }
1130
+ else {
1131
+ strokeDasharray = undefined;
1132
+ }
1113
1133
  return (React.createElement(ShapeWrapper, __assign({}, props, { ref: ref, height: props.height, width: props.width }),
1114
- React.createElement("rect", { className: "rect-border ".concat(props.portMoveableAreaCssClass), vectorEffect: "non-scaling-stroke", width: scaledWidth, height: scaledHeight, fill: props.fill || "transparent", stroke: props.stroke || "none", strokeWidth: sw }),
1134
+ React.createElement("rect", { className: "rect-border ".concat(props.portMoveableAreaCssClass), vectorEffect: "non-scaling-stroke", width: scaledWidth, height: scaledHeight, fill: props.fill || "transparent", stroke: props.stroke || "none", strokeWidth: sw, strokeDasharray: strokeDasharray, strokeLinecap: strokeLinecap }),
1115
1135
  props.children));
1116
1136
  });
1117
1137
 
@@ -1133,10 +1153,22 @@ var RectangularFrame = React.forwardRef(function (props, ref) {
1133
1153
  var fw = props.frameColor ? (props.frameWidth || 1) : 0;
1134
1154
  var scaledFw = scaledWidth / props.width * fw;
1135
1155
  var sw = props.stroke ? (props.strokeWidth || 1) : 0;
1156
+ var strokeDasharray;
1157
+ var strokeLinecap = undefined;
1158
+ if (props.strokeStyle === 'dashed') {
1159
+ strokeDasharray = '8, 4';
1160
+ }
1161
+ else if (props.strokeStyle === 'dotted') {
1162
+ strokeDasharray = '0, 4';
1163
+ strokeLinecap = 'round';
1164
+ }
1165
+ else {
1166
+ strokeDasharray = undefined;
1167
+ }
1136
1168
  return (React.createElement(ShapeWrapper, __assign({}, props, { ref: ref, height: props.height, width: props.width }),
1137
- React.createElement("rect", { vectorEffect: "non-scaling-stroke", className: "rectangular-frame-outer-border ".concat(props.portMoveableAreaCssClass), x: vbX, y: vbY, width: scaledWidth, height: scaledHeight, fill: "none", stroke: props.stroke || "none", strokeWidth: sw }),
1169
+ React.createElement("rect", { vectorEffect: "non-scaling-stroke", className: "rectangular-frame-outer-border ".concat(props.portMoveableAreaCssClass), x: vbX, y: vbY, width: scaledWidth, height: scaledHeight, fill: "none", stroke: props.stroke || "none", strokeWidth: sw, strokeDasharray: strokeDasharray, strokeLinecap: strokeLinecap }),
1138
1170
  React.createElement("rect", { vectorEffect: "non-scaling-stroke", className: 'rectangular-frame-hallway', x: vbX + scaledFw / 2, y: vbY + scaledFw / 2, width: scaledWidth - scaledFw, height: scaledHeight - scaledFw, stroke: props.frameColor || "none", strokeWidth: fw, fill: props.fill || "transparent" }),
1139
- React.createElement("rect", { vectorEffect: "non-scaling-stroke", className: 'rectangular-frame-inner-border', x: vbX + scaledFw, y: vbY + scaledFw, width: scaledWidth - scaledFw * 2, height: scaledHeight - scaledFw * 2, stroke: props.stroke || "none", strokeWidth: sw, fill: props.fill || "transparent" }),
1171
+ React.createElement("rect", { vectorEffect: "non-scaling-stroke", className: 'rectangular-frame-inner-border', x: vbX + scaledFw, y: vbY + scaledFw, width: scaledWidth - scaledFw * 2, height: scaledHeight - scaledFw * 2, stroke: props.stroke || "none", strokeWidth: sw, fill: props.fill || "transparent", strokeDasharray: strokeDasharray, strokeLinecap: strokeLinecap }),
1140
1172
  props.children));
1141
1173
  });
1142
1174
 
@@ -1273,762 +1305,179 @@ var Logger = /** @class */ (function () {
1273
1305
  }());
1274
1306
  var logger = new Logger();
1275
1307
 
1276
- var SelectionFrame = function (props) {
1277
- var propTargetSVGElement = props.targetSVGElement, propWidth = props.width, propHeight = props.height, propFramePadding = props.framePadding, objectX = props.objectX, objectY = props.objectY,
1278
- // movingOffsetThreshold: propMovingOffsetThreshold,
1279
- propMovingRate = props.movingRate, propOnMouseDown = props.onMouseDown, propOnMouseUp = props.onMouseUp, propOnMove = props.onMove, propContainer = props.container, propResizability = props.resizability, propOnResize = props.onResize, PropDragDropHandlerElement = props.dragDropHandlerElement, propStrokeWidth = props.strokeWidth, propAnchor = props.anchor;
1280
- var bbox = propTargetSVGElement === null || propTargetSVGElement === void 0 ? void 0 : propTargetSVGElement.getBBox();
1281
- var _a = React.useState(propWidth || (bbox === null || bbox === void 0 ? void 0 : bbox.width) || MIN_ELEMENT_SIZE), width = _a[0], setWidth = _a[1];
1282
- var _b = React.useState(propHeight || (bbox === null || bbox === void 0 ? void 0 : bbox.height) || MIN_ELEMENT_SIZE), height = _b[0], setHeight = _b[1];
1283
- React.useEffect(function () {
1284
- if (propWidth) {
1285
- setWidth(propWidth);
1286
- }
1287
- }, [objectX, propWidth]);
1288
- var _c = React.useState(objectX !== null && objectX !== void 0 ? objectX : 0), curX = _c[0], setCurX = _c[1];
1289
- var _d = React.useState(objectY !== null && objectY !== void 0 ? objectY : 0), curY = _d[0], setCurY = _d[1];
1290
- React.useEffect(function () {
1291
- if (objectX) {
1292
- setCurX(objectX);
1293
- }
1294
- }, [objectX]);
1295
- React.useEffect(function () {
1296
- if (objectY) {
1297
- setCurY(objectY);
1308
+ /**
1309
+ * Created by Alex Bol on 2/18/2017.
1310
+ */
1311
+
1312
+ /**
1313
+ * Global constant DP_TOL is used for comparison of floating point numbers.
1314
+ * It is set to 0.000001.
1315
+ * @type {number}
1316
+ */
1317
+ const DP_TOL = 0.000001;
1318
+
1319
+ var utils = {
1320
+ DP_TOL: DP_TOL,
1321
+ /**
1322
+ * Returns *true* if value comparable to zero
1323
+ * @return {boolean}
1324
+ */
1325
+ EQ_0: function(x) {
1326
+ return ( (x) < DP_TOL && (x) > -DP_TOL );
1327
+ },
1328
+ /**
1329
+ * Returns *true* if two values are equal up to DP_TOL
1330
+ * @return {boolean}
1331
+ */
1332
+ EQ: function(x,y) {
1333
+ return ( (x)-(y) < DP_TOL && (x)-(y) > -DP_TOL );
1334
+ },
1335
+ /**
1336
+ * Returns *true* if first argument greater than second argument up to DP_TOL
1337
+ * @return {boolean}
1338
+ */
1339
+ GT: (x,y) => {
1340
+ return ( (x)-(y) > DP_TOL );
1341
+ },
1342
+ /**
1343
+ * Returns *true* if first argument greater than or equal to second argument up to DP_TOL
1344
+ * @return {boolean}
1345
+ */
1346
+ GE: (x,y) => {
1347
+ return ( (x)-(y) > -DP_TOL );
1348
+ },
1349
+ /**
1350
+ * Returns *true* if first argument less than second argument up to DP_TOL
1351
+ * @return {boolean}
1352
+ */
1353
+ LT: (x,y) => {
1354
+ return ( (x)-(y) < -DP_TOL )
1355
+ },
1356
+ /**
1357
+ * Returns *true* if first argument less than or equal to second argument up to DP_TOL
1358
+ * @return {boolean}
1359
+ */
1360
+ LE: (x,y) => {
1361
+ return ( (x)-(y) < DP_TOL );
1362
+ }
1363
+ };
1364
+
1365
+ /**
1366
+ * Created by Alex Bol on 2/19/2017.
1367
+ */
1368
+
1369
+ var errors = {
1370
+ ILLEGAL_PARAMETERS: new ReferenceError('Illegal Parameters'),
1371
+ ZERO_DIVISION: new Error('Zero division')
1372
+ };
1373
+
1374
+ var matrix = function(Flatten) {
1375
+ /**
1376
+ * Class representing an affine transformation 3x3 matrix:
1377
+ * <pre>
1378
+ * [ a c tx
1379
+ * A = b d ty
1380
+ * 0 0 1 ]
1381
+ * </pre
1382
+ * @type {Matrix}
1383
+ */
1384
+ Flatten.Matrix = class Matrix {
1385
+ /**
1386
+ * Construct new instance of affine transformation matrix <br/>
1387
+ * If parameters omitted, construct identity matrix a = 1, d = 1
1388
+ * @param {number} a - position(0,0) sx*cos(alpha)
1389
+ * @param {number} b - position (0,1) sx*sin(alpha)
1390
+ * @param {number} c - position (1,0) -sy*sin(alpha)
1391
+ * @param {number} d - position (1,1) sy*cos(alpha)
1392
+ * @param {number} tx - position (2,0) translation by x
1393
+ * @param {number} ty - position (2,1) translation by y
1394
+ */
1395
+ constructor(a=1,b=0,c=0,d=1,tx=0,ty=0) {
1396
+ this.a = a;
1397
+ this.b = b;
1398
+ this.c = c;
1399
+ this.d = d;
1400
+ this.tx = tx;
1401
+ this.ty = ty;
1298
1402
  }
1299
- }, [objectY]);
1300
- var framePadding = propFramePadding || 0;
1301
- var r = 5;
1302
- var _e = React.useState(false), draggingRect = _e[0], setDraggingRect = _e[1];
1303
- var _f = React.useState(false), draggingCircle = _f[0], setDraggingCircle = _f[1];
1304
- var _g = React.useState(0), startX = _g[0], setStartX = _g[1];
1305
- var _h = React.useState(0), startY = _h[0], setStartY = _h[1];
1306
- var _j = React.useState(0), xFromMouse = _j[0], setXFromMouse = _j[1];
1307
- var _k = React.useState(0), yFromMouse = _k[0], setYFromMouse = _k[1];
1308
- var _l = React.useState(0), lastMoveTime = _l[0], setLastMoveTime = _l[1];
1309
- //set x by props.x
1310
- var getMousePosition = function (event) {
1311
- var elementBounding = propContainer.getBoundingClientRect();
1312
- //Coordinates of mouse on paper.
1313
- var mousePosition = {
1314
- x: event.clientX - elementBounding.left,
1315
- y: event.clientY - elementBounding.top
1403
+
1404
+ /**
1405
+ * Returns a clone of the Matrix instance.
1406
+ * @return {Matrix}
1407
+ **/
1408
+ clone() {
1409
+ return new Matrix(this.a, this.b, this.c, this.d, this.tx, this.ty);
1316
1410
  };
1317
- return mousePosition;
1318
- };
1319
- var addRectHandleMouseDown = function (event) {
1320
- event.stopPropagation();
1321
- if (!draggingCircle) {
1322
- setDraggingRect(true);
1323
- setStartX(event.clientX);
1324
- setStartY(event.clientY);
1325
- var mousePosition = getMousePosition(event);
1326
- var xFromMouse_1 = (curX || 0) - mousePosition.x;
1327
- var yFromMouse_1 = (curY || 0) - mousePosition.y;
1328
- setXFromMouse(xFromMouse_1);
1329
- setYFromMouse(yFromMouse_1);
1330
- }
1331
- if (propOnMouseDown) {
1332
- propOnMouseDown(event);
1333
- }
1334
- };
1335
- var rectHandleMouseMove = React.useCallback(function (event) {
1336
- var mouseEvent = event;
1337
- if (draggingRect) {
1338
- //Coordinates of mouse on paper.
1339
- var mousePosition = getMousePosition(mouseEvent);
1340
- var newX = mousePosition.x + xFromMouse;
1341
- var newY = mousePosition.y + yFromMouse;
1342
- if (propOnMove) {
1343
- setCurX(newX);
1344
- setCurY(newY);
1345
- propOnMove(newX, newY);
1346
- setLastMoveTime(Date.now());
1347
- setStartX(mouseEvent.clientX);
1348
- setStartY(mouseEvent.clientY);
1411
+
1412
+ /**
1413
+ * Transform vector [x,y] using transformation matrix. <br/>
1414
+ * Vector [x,y] is an abstract array[2] of numbers and not a FlattenJS object <br/>
1415
+ * The result is also an abstract vector [x',y'] = A * [x,y]:
1416
+ * <code>
1417
+ * [x' [ ax + by + tx
1418
+ * y' = cx + dy + ty
1419
+ * 1] 1 ]
1420
+ * </code>
1421
+ * @param {number[]} vector - array[2] of numbers
1422
+ * @returns {number[]} transformation result - array[2] of numbers
1423
+ */
1424
+ transform(vector) {
1425
+ return [
1426
+ vector[0]*this.a+vector[1]*this.c+this.tx,
1427
+ vector[0]*this.b+vector[1]*this.d+this.ty
1428
+ ]
1429
+ };
1430
+
1431
+ /**
1432
+ * Returns result of multiplication of this matrix by other matrix
1433
+ * @param {Matrix} other_matrix - matrix to multiply by
1434
+ * @returns {Matrix}
1435
+ */
1436
+ multiply(other_matrix) {
1437
+ return new Matrix(
1438
+ this.a*other_matrix.a + this.c*other_matrix.b,
1439
+ this.b*other_matrix.a + this.d*other_matrix.b,
1440
+ this.a*other_matrix.c + this.c*other_matrix.d,
1441
+ this.b*other_matrix.c + this.d*other_matrix.d,
1442
+ this.a*other_matrix.tx + this.c*other_matrix.ty + this.tx,
1443
+ this.b*other_matrix.tx + this.d*other_matrix.ty + this.ty
1444
+ )
1445
+ };
1446
+
1447
+ /**
1448
+ * Return new matrix as a result of multiplication of the current matrix
1449
+ * by the matrix(1,0,0,1,tx,ty)
1450
+ * @param {number} tx - translation by x
1451
+ * @param {number} ty - translation by y
1452
+ * @returns {Matrix}
1453
+ */
1454
+ translate(...args) {
1455
+ let tx, ty;
1456
+ if (args.length == 1 && (args[0] instanceof Flatten.Vector)) {
1457
+ tx = args[0].x;
1458
+ ty = args[0].y;
1349
1459
  }
1350
- }
1351
- }, [draggingRect, propOnMove, propMovingRate, startX, startY, lastMoveTime, xFromMouse, yFromMouse]);
1352
- React.useEffect(function () {
1353
- var addRectHandleMouseUp = function () {
1354
- setDraggingRect(false);
1355
- setXFromMouse(0);
1356
- setYFromMouse(0);
1460
+ else if (args.length == 2 && typeof(args[0]) == "number" && typeof(args[1]) == "number") {
1461
+ tx = args[0];
1462
+ ty = args[1];
1463
+ }
1464
+ else {
1465
+ throw Flatten.Errors.ILLEGAL_PARAMETERS;
1466
+ }
1467
+ return this.multiply(new Matrix(1,0,0,1,tx,ty))
1357
1468
  };
1358
- propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mousemove', rectHandleMouseMove);
1359
- propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mouseup', addRectHandleMouseUp);
1360
- return function () {
1361
- propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mousemove', rectHandleMouseMove);
1362
- propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mouseup', addRectHandleMouseUp);
1363
- };
1364
- }, [propContainer, rectHandleMouseMove]);
1365
- var circleHandleMouseDown = function (event) {
1366
- event.stopPropagation();
1367
- if (!draggingRect) {
1368
- setStartX(event.clientX);
1369
- setStartY(event.clientY);
1370
- setDraggingCircle(true);
1371
- }
1372
- };
1373
- React.useEffect(function () {
1374
- logger.debug('SelectionFrame: circleHandleMouseDown triggered', {
1375
- draggingCircle: draggingCircle,
1376
- startX: startX,
1377
- startY: startY,
1378
- width: width,
1379
- height: height,
1380
- propMovingRate: propMovingRate
1381
- });
1382
- var circleHandleMouseMove = function (event) {
1383
- var mouseEvent = event;
1384
- if (draggingCircle) {
1385
- var offsetX = mouseEvent.clientX - startX;
1386
- var offsetY = mouseEvent.clientY - startY;
1387
- if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
1388
- return;
1389
- }
1390
- setStartX(mouseEvent.clientX);
1391
- setStartY(mouseEvent.clientY);
1392
- setLastMoveTime(Date.now());
1393
- var newWidth = width;
1394
- var newHeight = height;
1395
- if (propResizability.keepRatio) {
1396
- var resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
1397
- var increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
1398
- offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
1399
- offsetY = increasing ? resizingRatio * height : -resizingRatio * height;
1400
- }
1401
- newWidth += offsetX;
1402
- newHeight += offsetY;
1403
- if (newWidth < MIN_ELEMENT_SIZE) {
1404
- newWidth = MIN_ELEMENT_SIZE;
1405
- }
1406
- if (newHeight < MIN_ELEMENT_SIZE) {
1407
- newHeight = MIN_ELEMENT_SIZE;
1408
- }
1409
- setWidth(newWidth);
1410
- setHeight(newHeight);
1411
- if (propOnResize) {
1412
- propOnResize(newWidth, newHeight);
1413
- }
1414
- }
1415
- };
1416
- var circleHandleMouseUp = function () {
1417
- setDraggingCircle(false);
1418
- };
1419
- var container = propContainer;
1420
- container.addEventListener('mousemove', circleHandleMouseMove);
1421
- container.addEventListener('mouseup', circleHandleMouseUp);
1422
- //logging the start of the circle handle mouse move
1423
- logger.debug('SelectionFrame: circleHandleMouseMove started', container);
1424
- return function () {
1425
- container.removeEventListener('mousemove', circleHandleMouseMove);
1426
- container.removeEventListener('mouseup', circleHandleMouseUp);
1427
- //logging the end of the circle handle mouse move
1428
- logger.debug('SelectionFrame: circleHandleMouseMove ended', container);
1429
- };
1430
- }, [draggingCircle, width, height, curX, curY, lastMoveTime, propContainer, propMovingRate, propOnResize, propResizability, startX, startY]);
1431
- var rectangleSize = Math.max(width, height);
1432
- var leftX = framePadding;
1433
- var topY = framePadding;
1434
- if (propAnchor === exports.PositioningAnchor.Center) {
1435
- leftX -= rectangleSize / 2;
1436
- topY -= rectangleSize / 2;
1437
- }
1438
- return (React.createElement(React.Fragment, null,
1439
- PropDragDropHandlerElement && React.createElement(PropDragDropHandlerElement, { dragging: draggingRect, onMouseDown: addRectHandleMouseDown }),
1440
- React.createElement("rect", { vectorEffect: "non-scaling-stroke", x: leftX, y: topY, width: width, height: height, fill: 'none', stroke: 'blue', strokeWidth: propStrokeWidth || 5, cursor: draggingRect ? 'grabbing' : 'grab', onMouseDown: addRectHandleMouseDown, onMouseUp: propOnMouseUp }),
1441
- propResizability.enabled ?
1442
- (React.createElement("circle", { cursor: 'se-resize', cx: leftX + width, cy: topY + height, r: r, fill: 'blue', stroke: 'blue', onMouseDown: circleHandleMouseDown })) : null));
1443
- };
1444
-
1445
- var useSelectionFrame = function (props) {
1446
- React.useEffect(function () {
1447
- //log selection frame rendering
1448
- if (props.targetSVGElement) {
1449
- console.debug('Rendering SelectionFrame for targetSVGElement:', props.targetSVGElement);
1450
- }
1451
- else {
1452
- console.warn('No targetSVGElement provided for SelectionFrame.');
1453
- }
1454
- if (props.targetSVGElement && props.container) {
1455
- //render SelectionFrame component to the parent element of the targetSVGElement
1456
- if (props.container) {
1457
- var svg_1 = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
1458
- svg_1.style.overflow = 'visible';
1459
- svg_1.style.outline = 'none';
1460
- props.targetSVGElement.appendChild(svg_1);
1461
- var root_1 = createRoot(svg_1);
1462
- root_1.render(React.createElement(SelectionFrame, __assign({}, props, { container: props.container })));
1463
- return function () {
1464
- root_1.unmount();
1465
- if (props.targetSVGElement) {
1466
- props.targetSVGElement.removeChild(svg_1);
1467
- }
1468
- };
1469
- }
1470
- }
1471
- }, [props]);
1472
- };
1473
-
1474
- var eventEmitter = new EventEmitter();
1475
- var emitPaperClicked = function (ev) {
1476
- eventEmitter.emit(EVENT_NAME.PAPER_CLICK, ev);
1477
- };
1478
- var onPaperClicked = function (callback) {
1479
- eventEmitter.on(EVENT_NAME.PAPER_CLICK, callback);
1480
- var off = function () {
1481
- eventEmitter.off(EVENT_NAME.PAPER_CLICK, callback);
1482
- };
1483
- return {
1484
- off: off
1485
- };
1486
- };
1487
- var emitPortMouseUp = function (ev, port, elementId) {
1488
- eventEmitter.emit(EVENT_NAME.PORT_MOUSE_UP, ev, port, elementId);
1489
- };
1490
- var onPortMouseUp = function (callback) {
1491
- eventEmitter.on(EVENT_NAME.PORT_MOUSE_UP, callback);
1492
- var off = function () {
1493
- eventEmitter.off(EVENT_NAME.PORT_MOUSE_UP, callback);
1494
- };
1495
- return {
1496
- off: off
1497
- };
1498
- };
1499
- var emitPortMouseDown = function (ev, port, elementId) {
1500
- eventEmitter.emit(EVENT_NAME.PORT_MOUSE_DOWN, ev, port, elementId);
1501
- };
1502
- var onPortMouseDown = function (callback) {
1503
- eventEmitter.on(EVENT_NAME.PORT_MOUSE_DOWN, callback);
1504
- var off = function () {
1505
- eventEmitter.off(EVENT_NAME.PORT_MOUSE_DOWN, callback);
1506
- };
1507
- return {
1508
- off: off
1509
- };
1510
- };
1511
- var emitPortMoved = function (port, elementId, oldPosition, newPosition) {
1512
- eventEmitter.emit(EVENT_NAME.PORT_MOVED, port, elementId, oldPosition, newPosition);
1513
- };
1514
- var onPortMoved = function (callback) {
1515
- eventEmitter.on(EVENT_NAME.PORT_MOVED, callback);
1516
- var off = function () {
1517
- eventEmitter.off(EVENT_NAME.PORT_MOVED, callback);
1518
- };
1519
- return {
1520
- off: off
1521
- };
1522
- };
1523
- var emitElementMoved = function (element, oldPosition, newPosition) {
1524
- eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(element.id));
1525
- };
1526
- var onElementMoved = function (elementId, callback) {
1527
- eventEmitter.on("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
1528
- var off = function () {
1529
- eventEmitter.off("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
1530
- };
1531
- return {
1532
- off: off
1533
- };
1534
- };
1535
- var emitElementResized = function (element, oldSize, newSize) {
1536
- eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(element.id), oldSize, newSize);
1537
- };
1538
- var onElementResized = function (elementId, callback) {
1539
- eventEmitter.on("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
1540
- var off = function () {
1541
- eventEmitter.off("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
1542
- };
1543
- return {
1544
- off: off
1545
- };
1546
- };
1547
- var emitCommandDeleteSelectedPort = function () {
1548
- eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT);
1549
- };
1550
- var onCommandDeleteSelectedPort = function (callback) {
1551
- eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
1552
- var off = function () {
1553
- eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
1554
- };
1555
- return {
1556
- off: off
1557
- };
1558
- };
1559
- var emitCommandDeleteSelectedElement = function () {
1560
- eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT);
1561
- };
1562
- var onCommandDeleteSelectedElement = function (callback) {
1563
- eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
1564
- var off = function () {
1565
- eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
1566
- };
1567
- return {
1568
- off: off
1569
- };
1570
- };
1571
- var emitCommandDeleteSelectedLink = function () {
1572
- eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK);
1573
- };
1574
- var onCommandDeleteSelectedLink = function (callback) {
1575
- eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
1576
- var off = function () {
1577
- eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
1578
- };
1579
- return {
1580
- off: off
1581
- };
1582
- };
1583
- var emitCommandDeleteSelectedText = function () {
1584
- eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT);
1585
- };
1586
- var onCommandDeleteSelectedText = function (callback) {
1587
- eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
1588
- var off = function () {
1589
- eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
1590
- };
1591
- return {
1592
- off: off
1593
- };
1594
- };
1595
- var emitElementLinkStarted = function (elementLink) {
1596
- eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_STARTED, elementLink);
1597
- };
1598
- var onElementLinkStarted = function (callback) {
1599
- eventEmitter.on(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
1600
- var off = function () {
1601
- eventEmitter.off(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
1602
- };
1603
- return {
1604
- off: off
1605
- };
1606
- };
1607
- var emitElementLinkEnded = function (elementLink) {
1608
- eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_ENDED, elementLink);
1609
- };
1610
- var onElementLinkEnded = function (callback) {
1611
- eventEmitter.on(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
1612
- var off = function () {
1613
- eventEmitter.off(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
1614
- };
1615
- return {
1616
- off: off
1617
- };
1618
- };
1619
- var emitElementSelected = function (element) {
1620
- eventEmitter.emit(EVENT_NAME.ELEMENT_SELECTED, element);
1621
- };
1622
- var onElementSelected = function (callback) {
1623
- eventEmitter.on(EVENT_NAME.ELEMENT_SELECTED, callback);
1624
- var off = function () {
1625
- eventEmitter.off(EVENT_NAME.ELEMENT_SELECTED, callback);
1626
- };
1627
- return {
1628
- off: off
1629
- };
1630
- };
1631
- var emitCommandRenderElement = function (elementId) {
1632
- eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_ELEMENT, elementId);
1633
- };
1634
- var onCommandRenderElement = function (callback) {
1635
- eventEmitter.on(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
1636
- var off = function () {
1637
- eventEmitter.off(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
1638
- };
1639
- return {
1640
- off: off
1641
- };
1642
- };
1643
- var emitPortSelected = function (port, elementId) {
1644
- eventEmitter.emit(EVENT_NAME.PORT_SELECTED, port, elementId);
1645
- };
1646
- var onPortSelected = function (callback) {
1647
- eventEmitter.on(EVENT_NAME.PORT_SELECTED, callback);
1648
- var off = function () {
1649
- eventEmitter.off(EVENT_NAME.PORT_SELECTED, callback);
1650
- };
1651
- return {
1652
- off: off
1653
- };
1654
- };
1655
- var emitCommandRenderPort = function (portId, elementId) {
1656
- eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_PORT, portId, elementId);
1657
- };
1658
- var onCommandRenderPort = function (callback) {
1659
- eventEmitter.on(EVENT_NAME.COMMAND_RENDER_PORT, callback);
1660
- var off = function () {
1661
- eventEmitter.off(EVENT_NAME.COMMAND_RENDER_PORT, callback);
1662
- };
1663
- return {
1664
- off: off
1665
- };
1666
- };
1667
- var emitTextSelected = function (text) {
1668
- eventEmitter.emit(EVENT_NAME.TEXT_SELECTED, text);
1669
- };
1670
- var onTextSelected = function (callback) {
1671
- eventEmitter.on(EVENT_NAME.TEXT_SELECTED, callback);
1672
- var off = function () {
1673
- eventEmitter.off(EVENT_NAME.TEXT_SELECTED, callback);
1674
- };
1675
- return {
1676
- off: off
1677
- };
1678
- };
1679
- var paperEventEmitterContext = React.createContext({
1680
- emitter: eventEmitter,
1681
- emitPaperClicked: emitPaperClicked,
1682
- onPaperClicked: onPaperClicked,
1683
- emitPortMouseUp: emitPortMouseUp,
1684
- onPortMouseUp: onPortMouseUp,
1685
- emitPortMouseDown: emitPortMouseDown,
1686
- onPortMouseDown: onPortMouseDown,
1687
- emitPortMoved: emitPortMoved,
1688
- onPortMoved: onPortMoved,
1689
- emitPortSelected: emitPortSelected,
1690
- onPortSelected: onPortSelected,
1691
- emitElementMoved: emitElementMoved,
1692
- onElementMoved: onElementMoved,
1693
- emitElementResized: emitElementResized,
1694
- onElementResized: onElementResized,
1695
- emitElementSelected: emitElementSelected,
1696
- onElementSelected: onElementSelected,
1697
- emitCommandRenderElement: emitCommandRenderElement,
1698
- onCommandRenderElement: onCommandRenderElement,
1699
- emitCommandDeleteSelectedPort: emitCommandDeleteSelectedPort,
1700
- onCommandDeleteSelectedPort: onCommandDeleteSelectedPort,
1701
- emitCommandDeleteSelectedElement: emitCommandDeleteSelectedElement,
1702
- onCommandDeleteSelectedElement: onCommandDeleteSelectedElement,
1703
- emitCommandDeleteSelectedLink: emitCommandDeleteSelectedLink,
1704
- onCommandDeleteSelectedLink: onCommandDeleteSelectedLink,
1705
- emitCommandDeleteSelectedText: emitCommandDeleteSelectedText,
1706
- onCommandDeleteSelectedText: onCommandDeleteSelectedText,
1707
- emitElementLinkStarted: emitElementLinkStarted,
1708
- onElementLinkStarted: onElementLinkStarted,
1709
- emitElementLinkEnded: emitElementLinkEnded,
1710
- onElementLinkEnded: onElementLinkEnded,
1711
- emitTextSelected: emitTextSelected,
1712
- onTextSelected: onTextSelected,
1713
- emitCommandRenderPort: emitCommandRenderPort,
1714
- onCommandRenderPort: onCommandRenderPort,
1715
- });
1716
-
1717
- var Text = React.forwardRef(function (_a, ref) {
1718
- var id = _a.id, content = _a.content, x = _a.x, y = _a.y, width = _a.width, height = _a.height, editable = _a.editable, _b = _a.selectable, selectable = _b === void 0 ? true : _b, _c = _a.align, align = _c === void 0 ? exports.TextAlign.left : _c, fontSizeProp = _a.fontSize, border = _a.border, container = _a.container, parentAbsolutePosition = _a.parentAbsolutePosition, onSelected = _a.onSelected, onMoved = _a.onMoved, onResized = _a.onResized, onContentChanged = _a.onContentChanged;
1719
- var _d = React.useState(false), isSelected = _d[0], setIsSelected = _d[1];
1720
- var _e = React.useState(false), isEditing = _e[0], setIsEditing = _e[1];
1721
- var absolutePosition = React.useMemo(function () {
1722
- var _a, _b;
1723
- return {
1724
- x: ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0) + x,
1725
- y: ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0) + y,
1726
- };
1727
- }, [x, y, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y]);
1728
- var svgRef = React.useRef();
1729
- var _f = React.useContext(paperEventEmitterContext), onPaperClicked = _f.onPaperClicked, emitTextSelected = _f.emitTextSelected, onPortSelected = _f.onPortSelected, onElementSelected = _f.onElementSelected, onTextSelected = _f.onTextSelected;
1730
- React.useEffect(function () {
1731
- var paperClickListener = onPaperClicked(function (ev) {
1732
- var _a;
1733
- var textareaELe = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('textarea');
1734
- if (ev.target !== textareaELe) {
1735
- setIsSelected(false);
1736
- setIsEditing(false);
1737
- }
1738
- });
1739
- var portSelectedListener = onPortSelected(function (port) {
1740
- setIsSelected(false);
1741
- setIsEditing(false);
1742
- });
1743
- var elementSelectedListener = onElementSelected(function (element) {
1744
- setIsSelected(false);
1745
- setIsEditing(false);
1746
- });
1747
- var textSelectedListener = onTextSelected(function (text) {
1748
- if (text.id !== id) {
1749
- setIsSelected(false);
1750
- setIsEditing(false);
1751
- }
1752
- });
1753
- return function () {
1754
- paperClickListener.off();
1755
- portSelectedListener.off();
1756
- elementSelectedListener.off();
1757
- textSelectedListener.off();
1758
- };
1759
- }, []);
1760
- //Handle click on svg element
1761
- var handleClick = function (ev) {
1762
- if (!selectable)
1763
- return;
1764
- ev.stopPropagation();
1765
- var position = {
1766
- x: x,
1767
- y: y,
1768
- };
1769
- var text = {
1770
- id: id,
1771
- content: content,
1772
- position: position,
1773
- size: {
1774
- width: width,
1775
- height: height,
1776
- },
1777
- editable: editable
1778
- };
1779
- setIsSelected(true);
1780
- onSelected && onSelected(text);
1781
- emitTextSelected(text);
1782
- };
1783
- var handleChangeText = function (ev) {
1784
- if (!editable)
1785
- return;
1786
- onContentChanged === null || onContentChanged === void 0 ? void 0 : onContentChanged(ev, ev.target.value);
1787
- };
1788
- useSelectionFrame({
1789
- objectX: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.x,
1790
- objectY: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.y,
1791
- container: container,
1792
- targetSVGElement: (isSelected && svgRef.current) ? svgRef.current : undefined,
1793
- resizability: {
1794
- enabled: onResized ? true : false,
1795
- keepRatio: false,
1796
- },
1797
- onMove: onMoved,
1798
- onResize: onResized,
1799
- strokeWidth: 3,
1800
- });
1801
- var textAlign = React.useMemo(function () {
1802
- switch (align) {
1803
- case exports.TextAlign.left:
1804
- return 'left';
1805
- case exports.TextAlign.right:
1806
- return 'right';
1807
- case exports.TextAlign.center:
1808
- return 'center';
1809
- default:
1810
- return 'left';
1811
- }
1812
- }, [align]);
1813
- var fontSize = fontSizeProp || TEXT_FONT_SIZE;
1814
- var borderStyle = border || 'none';
1815
- return (React.createElement("svg", { style: { overflow: "visible" }, x: x, y: y, ref: function (node) {
1816
- svgRef.current = node;
1817
- if (typeof ref === 'function') {
1818
- ref(node);
1819
- }
1820
- else if (ref) {
1821
- ref.current = node;
1822
- }
1823
- }, onClick: handleClick },
1824
- React.createElement("foreignObject", { width: width, height: height, style: {
1825
- overflow: 'visible',
1826
- userSelect: 'none',
1827
- WebkitUserSelect: 'none',
1828
- msUserSelect: 'none'
1829
- } },
1830
- React.createElement("div", { style: {
1831
- width: '100%',
1832
- height: '100%',
1833
- borderWidth: '1px',
1834
- borderColor: '#ccc',
1835
- borderStyle: borderStyle,
1836
- // whiteSpace: 'pre-wrap',
1837
- boxSizing: 'border-box',
1838
- } },
1839
- React.createElement("textarea", { style: {
1840
- fontFamily: 'initial',
1841
- display: 'inline-block',
1842
- width: '100%',
1843
- height: '100%',
1844
- overflow: 'hidden',
1845
- border: 'none',
1846
- background: 'transparent',
1847
- outline: 'none',
1848
- resize: 'none',
1849
- textAlign: textAlign,
1850
- fontSize: fontSize,
1851
- }, readOnly: !isEditing, onDoubleClick: function () {
1852
- if (editable) {
1853
- setIsEditing(true);
1854
- }
1855
- }, value: content, onChange: handleChangeText })))));
1856
- });
1857
- var Text$1 = React.memo(Text);
1858
-
1859
- /**
1860
- * Created by Alex Bol on 2/18/2017.
1861
- */
1862
-
1863
- /**
1864
- * Global constant DP_TOL is used for comparison of floating point numbers.
1865
- * It is set to 0.000001.
1866
- * @type {number}
1867
- */
1868
- const DP_TOL = 0.000001;
1869
-
1870
- var utils = {
1871
- DP_TOL: DP_TOL,
1872
- /**
1873
- * Returns *true* if value comparable to zero
1874
- * @return {boolean}
1875
- */
1876
- EQ_0: function(x) {
1877
- return ( (x) < DP_TOL && (x) > -DP_TOL );
1878
- },
1879
- /**
1880
- * Returns *true* if two values are equal up to DP_TOL
1881
- * @return {boolean}
1882
- */
1883
- EQ: function(x,y) {
1884
- return ( (x)-(y) < DP_TOL && (x)-(y) > -DP_TOL );
1885
- },
1886
- /**
1887
- * Returns *true* if first argument greater than second argument up to DP_TOL
1888
- * @return {boolean}
1889
- */
1890
- GT: (x,y) => {
1891
- return ( (x)-(y) > DP_TOL );
1892
- },
1893
- /**
1894
- * Returns *true* if first argument greater than or equal to second argument up to DP_TOL
1895
- * @return {boolean}
1896
- */
1897
- GE: (x,y) => {
1898
- return ( (x)-(y) > -DP_TOL );
1899
- },
1900
- /**
1901
- * Returns *true* if first argument less than second argument up to DP_TOL
1902
- * @return {boolean}
1903
- */
1904
- LT: (x,y) => {
1905
- return ( (x)-(y) < -DP_TOL )
1906
- },
1907
- /**
1908
- * Returns *true* if first argument less than or equal to second argument up to DP_TOL
1909
- * @return {boolean}
1910
- */
1911
- LE: (x,y) => {
1912
- return ( (x)-(y) < DP_TOL );
1913
- }
1914
- };
1915
-
1916
- /**
1917
- * Created by Alex Bol on 2/19/2017.
1918
- */
1919
-
1920
- var errors = {
1921
- ILLEGAL_PARAMETERS: new ReferenceError('Illegal Parameters'),
1922
- ZERO_DIVISION: new Error('Zero division')
1923
- };
1924
-
1925
- var matrix = function(Flatten) {
1926
- /**
1927
- * Class representing an affine transformation 3x3 matrix:
1928
- * <pre>
1929
- * [ a c tx
1930
- * A = b d ty
1931
- * 0 0 1 ]
1932
- * </pre
1933
- * @type {Matrix}
1934
- */
1935
- Flatten.Matrix = class Matrix {
1936
- /**
1937
- * Construct new instance of affine transformation matrix <br/>
1938
- * If parameters omitted, construct identity matrix a = 1, d = 1
1939
- * @param {number} a - position(0,0) sx*cos(alpha)
1940
- * @param {number} b - position (0,1) sx*sin(alpha)
1941
- * @param {number} c - position (1,0) -sy*sin(alpha)
1942
- * @param {number} d - position (1,1) sy*cos(alpha)
1943
- * @param {number} tx - position (2,0) translation by x
1944
- * @param {number} ty - position (2,1) translation by y
1945
- */
1946
- constructor(a=1,b=0,c=0,d=1,tx=0,ty=0) {
1947
- this.a = a;
1948
- this.b = b;
1949
- this.c = c;
1950
- this.d = d;
1951
- this.tx = tx;
1952
- this.ty = ty;
1953
- }
1954
-
1955
- /**
1956
- * Returns a clone of the Matrix instance.
1957
- * @return {Matrix}
1958
- **/
1959
- clone() {
1960
- return new Matrix(this.a, this.b, this.c, this.d, this.tx, this.ty);
1961
- };
1962
-
1963
- /**
1964
- * Transform vector [x,y] using transformation matrix. <br/>
1965
- * Vector [x,y] is an abstract array[2] of numbers and not a FlattenJS object <br/>
1966
- * The result is also an abstract vector [x',y'] = A * [x,y]:
1967
- * <code>
1968
- * [x' [ ax + by + tx
1969
- * y' = cx + dy + ty
1970
- * 1] 1 ]
1971
- * </code>
1972
- * @param {number[]} vector - array[2] of numbers
1973
- * @returns {number[]} transformation result - array[2] of numbers
1974
- */
1975
- transform(vector) {
1976
- return [
1977
- vector[0]*this.a+vector[1]*this.c+this.tx,
1978
- vector[0]*this.b+vector[1]*this.d+this.ty
1979
- ]
1980
- };
1981
-
1982
- /**
1983
- * Returns result of multiplication of this matrix by other matrix
1984
- * @param {Matrix} other_matrix - matrix to multiply by
1985
- * @returns {Matrix}
1986
- */
1987
- multiply(other_matrix) {
1988
- return new Matrix(
1989
- this.a*other_matrix.a + this.c*other_matrix.b,
1990
- this.b*other_matrix.a + this.d*other_matrix.b,
1991
- this.a*other_matrix.c + this.c*other_matrix.d,
1992
- this.b*other_matrix.c + this.d*other_matrix.d,
1993
- this.a*other_matrix.tx + this.c*other_matrix.ty + this.tx,
1994
- this.b*other_matrix.tx + this.d*other_matrix.ty + this.ty
1995
- )
1996
- };
1997
-
1998
- /**
1999
- * Return new matrix as a result of multiplication of the current matrix
2000
- * by the matrix(1,0,0,1,tx,ty)
2001
- * @param {number} tx - translation by x
2002
- * @param {number} ty - translation by y
2003
- * @returns {Matrix}
2004
- */
2005
- translate(...args) {
2006
- let tx, ty;
2007
- if (args.length == 1 && (args[0] instanceof Flatten.Vector)) {
2008
- tx = args[0].x;
2009
- ty = args[0].y;
2010
- }
2011
- else if (args.length == 2 && typeof(args[0]) == "number" && typeof(args[1]) == "number") {
2012
- tx = args[0];
2013
- ty = args[1];
2014
- }
2015
- else {
2016
- throw Flatten.Errors.ILLEGAL_PARAMETERS;
2017
- }
2018
- return this.multiply(new Matrix(1,0,0,1,tx,ty))
2019
- };
2020
-
2021
- /**
2022
- * Return new matrix as a result of multiplication of the current matrix
2023
- * by the matrix that defines rotation by given angle (in radians) around
2024
- * point (0,0) in counter clockwise direction
2025
- * @param angle
2026
- * @returns {Matrix}
2027
- */
2028
- rotate(angle) {
2029
- let cos = Math.cos(angle);
2030
- let sin = Math.sin(angle);
2031
- return this.multiply(new Matrix(cos,sin,-sin,cos,0,0));
1469
+
1470
+ /**
1471
+ * Return new matrix as a result of multiplication of the current matrix
1472
+ * by the matrix that defines rotation by given angle (in radians) around
1473
+ * point (0,0) in counter clockwise direction
1474
+ * @param angle
1475
+ * @returns {Matrix}
1476
+ */
1477
+ rotate(angle) {
1478
+ let cos = Math.cos(angle);
1479
+ let sin = Math.sin(angle);
1480
+ return this.multiply(new Matrix(cos,sin,-sin,cos,0,0));
2032
1481
  };
2033
1482
 
2034
1483
  /**
@@ -7396,43 +6845,6 @@ var checkPositionOnLine = function (position, line) {
7396
6845
  return _line.contains(point);
7397
6846
  };
7398
6847
 
7399
- // Calculate the position of the 4 vertices of a rectangle relative to its parent svg
7400
- var getRectangleCorners = function (rectSVG) {
7401
- var ownerSVG = rectSVG.ownerSVGElement;
7402
- var rectStrokeWidth = Number(rectSVG.getAttribute('stroke-width')) || 0;
7403
- var strokeWidthOffset = rectStrokeWidth / 2;
7404
- if (!ownerSVG) {
7405
- throw new Error('Rectangle does not wrapper by svg.');
7406
- }
7407
- var ownerX = ownerSVG.x.baseVal.value;
7408
- var ownerY = ownerSVG.y.baseVal.value;
7409
- var ownerWidth = ownerSVG.width.baseVal.value;
7410
- var ownerHeight = ownerSVG.height.baseVal.value;
7411
- var a = { x: ownerX + strokeWidthOffset, y: ownerY + strokeWidthOffset };
7412
- var b = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + strokeWidthOffset };
7413
- var c = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7414
- var d = { x: ownerX + strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7415
- return [a, b, c, d];
7416
- };
7417
- //find rotation angle of svg element on g element
7418
- var getElementRotationInfo = function (element) {
7419
- var gElement = element;
7420
- var rotationAngle = 0;
7421
- while (!(gElement instanceof SVGGElement)) {
7422
- gElement = gElement.parentElement;
7423
- }
7424
- var transform = gElement.getAttribute('transform');
7425
- if (transform) {
7426
- // Match the rotation value using a regular expression
7427
- var rotateMatch = transform.match(/rotate\(([-\d.]+)(?:\s+[-\d.]+\s+[-\d.]+)?\)/);
7428
- if (rotateMatch) {
7429
- // The first capture group is the rotation angle
7430
- rotationAngle = parseFloat(rotateMatch[1]);
7431
- }
7432
- }
7433
- return rotationAngle;
7434
- };
7435
-
7436
6848
  // const topLeftOffsetOfSquareHoldingRect = (x: number, y: number, rectWidth: number, rectHeight: number, rotation?: number): IPosition => {
7437
6849
  // rotation = rotation || 0;
7438
6850
  // const rotationInRadians = rotation * Math.PI / 180;
@@ -7486,8 +6898,213 @@ function calculateAngleWithOx(pStart, pEnd) {
7486
6898
  if (angleInDegrees < 0) {
7487
6899
  angleInDegrees += 360;
7488
6900
  }
7489
- return angleInDegrees;
7490
- }
6901
+ return angleInDegrees;
6902
+ }
6903
+
6904
+ // Render the svg <path> element
6905
+ function getCurvePathData(points, smoothing, closed) {
6906
+ if (smoothing === void 0) { smoothing = 0.2; }
6907
+ // append first 2 points for closed paths
6908
+ if (closed) {
6909
+ points = points.concat(points.slice(0, 2));
6910
+ }
6911
+ // Properties of a line
6912
+ var line = function (pointA, pointB) {
6913
+ var lengthX = pointB.x - pointA.x;
6914
+ var lengthY = pointB.y - pointA.y;
6915
+ return {
6916
+ length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
6917
+ angle: Math.atan2(lengthY, lengthX)
6918
+ };
6919
+ };
6920
+ // Position of a control point
6921
+ var controlPoint = function (current, previous, next, reverse) {
6922
+ var p = previous || current;
6923
+ var n = next || current;
6924
+ var o = line(p, n);
6925
+ var angle = o.angle + (reverse ? Math.PI : 0);
6926
+ var length = o.length * smoothing;
6927
+ var x = current.x + Math.cos(angle) * length;
6928
+ var y = current.y + Math.sin(angle) * length;
6929
+ return { x: x, y: y };
6930
+ };
6931
+ var pathData = [];
6932
+ pathData.push({ type: "M", values: [points[0].x, points[0].y] });
6933
+ for (var i = 1; i < points.length; i++) {
6934
+ var point = points[i];
6935
+ var cp1 = controlPoint(points[i - 1], points[i - 2], point);
6936
+ var cp2 = controlPoint(point, points[i - 1], points[i + 1], true);
6937
+ var command = {
6938
+ type: "C",
6939
+ values: [cp1.x, cp1.y, cp2.x, cp2.y, point.x, point.y]
6940
+ };
6941
+ pathData.push(command);
6942
+ }
6943
+ // copy last commands 1st controlpoint to first curveto
6944
+ if (closed) {
6945
+ var comLast = pathData[pathData.length - 1];
6946
+ var valuesLastC = comLast.values;
6947
+ var valuesFirstC = pathData[1].values;
6948
+ pathData[1] = {
6949
+ type: "C",
6950
+ values: [valuesLastC[0], valuesLastC[1], valuesFirstC.slice(2)].flat()
6951
+ };
6952
+ // delete last curveto
6953
+ pathData = pathData.slice(0, pathData.length - 1);
6954
+ }
6955
+ return pathData;
6956
+ }
6957
+ // convert pathdata to d attribute string
6958
+ function pathDataToD(pathData, decimals) {
6959
+ if (decimals === void 0) { decimals = 3; }
6960
+ var d = pathData
6961
+ .map(function (com) {
6962
+ return "".concat(com.type).concat(com.values.map(function (value) { return +value.toFixed(decimals); }).join(" "));
6963
+ })
6964
+ .join(" ");
6965
+ return d;
6966
+ }
6967
+ function createSmoothPathString(points, smoothing, close) {
6968
+ var pathData = getCurvePathData(points, smoothing, close);
6969
+ var pathString = pathDataToD(pathData);
6970
+ return pathString;
6971
+ }
6972
+ // a helper function to measure the distance between 2 points
6973
+ function dist(p1, p2) {
6974
+ var dx = p2.x - p1.x;
6975
+ var dy = p2.y - p1.y;
6976
+ return Math.sqrt(dx * dx + dy * dy);
6977
+ }
6978
+ //find distance from starting point of path to a point
6979
+ function getLengthForPoint(p, thePath, precision) {
6980
+ if (precision === void 0) { precision = 50; }
6981
+ var pathLength = thePath.getTotalLength();
6982
+ var theRecord = pathLength; //length of path
6983
+ var division = pathLength / precision;
6984
+ var theSegment;
6985
+ for (var i = 0; i < precision; i++) {
6986
+ // get a point on the path for thia distance
6987
+ var _p = thePath.getPointAtLength(i * division);
6988
+ // get the distance between the new point _p and the point p
6989
+ var theDistance = dist(_p, p);
6990
+ if (theDistance < theRecord) {
6991
+ // if the distance is smaller than the record set the new record
6992
+ theRecord = theDistance;
6993
+ theSegment = i;
6994
+ }
6995
+ }
6996
+ return (theSegment * division);
6997
+ }
6998
+ //Add points to the list of points in the correct position
6999
+ function addPointToList(point, listPoints, path) {
7000
+ var getAddIndex = function (startIndex, endIndex) {
7001
+ //Add in the middle if there are only 2 points
7002
+ if ((endIndex - startIndex) === 1) {
7003
+ return startIndex + 1;
7004
+ }
7005
+ var middleIndex = Math.ceil((startIndex + endIndex) / 2);
7006
+ var lengthOfMiddlePoint = getLengthForPoint(listPoints[middleIndex], path); //distance from start point to mid point
7007
+ var lengthOfAddedPoint = getLengthForPoint(point, path); //distance from adding point to mid point
7008
+ //compare if lengthOfMiddlePoint is less than lengthOfAddedPoint,
7009
+ //then new point can be added in the range of mid point to end point,
7010
+ //otherwise it can be added in the range of start point to middle point.
7011
+ if (lengthOfAddedPoint < lengthOfMiddlePoint) {
7012
+ return getAddIndex(startIndex, middleIndex);
7013
+ }
7014
+ else {
7015
+ return getAddIndex(middleIndex, endIndex);
7016
+ }
7017
+ };
7018
+ var addedIndex = getAddIndex(0, listPoints.length - 1);
7019
+ listPoints.splice(addedIndex, 0, point);
7020
+ return __spreadArray([], listPoints, true);
7021
+ }
7022
+ // Parse the d attribute of a path element and extract points from path commands
7023
+ function getPointsFromPathData(dAttribute) {
7024
+ var points = [];
7025
+ // Remove extra whitespace and split by command letters
7026
+ var cleanD = dAttribute.replace(/\s+/g, ' ').trim();
7027
+ // Regular expression to match path commands (M, L, C, etc.) and their values
7028
+ var commandRegex = /([MLCZmlcz])\s*([^MLCZmlcz]*)/g;
7029
+ var match;
7030
+ while ((match = commandRegex.exec(cleanD)) !== null) {
7031
+ var command = match[1].toUpperCase();
7032
+ var values = match[2].trim();
7033
+ if (values) {
7034
+ var coords = values.split(/[\s,]+/).map(Number).filter(function (num) { return !isNaN(num); });
7035
+ switch (command) {
7036
+ case 'M': // Move to
7037
+ if (coords.length >= 2) {
7038
+ points.push({ x: coords[0], y: coords[1] });
7039
+ }
7040
+ break;
7041
+ case 'L': // Line to
7042
+ if (coords.length >= 2) {
7043
+ points.push({ x: coords[0], y: coords[1] });
7044
+ }
7045
+ break;
7046
+ case 'C': // Cubic bezier curve
7047
+ // For cubic curves, we take the end point (last 2 coordinates)
7048
+ if (coords.length >= 6) {
7049
+ points.push({ x: coords[4], y: coords[5] });
7050
+ }
7051
+ break;
7052
+ case 'Q': // Quadratic bezier curve
7053
+ // For quadratic curves, we take the end point (last 2 coordinates)
7054
+ if (coords.length >= 4) {
7055
+ points.push({ x: coords[2], y: coords[3] });
7056
+ }
7057
+ break;
7058
+ }
7059
+ }
7060
+ }
7061
+ return points;
7062
+ }
7063
+ // Get points from a path element's d attribute
7064
+ function getPointsFromPathElement(pathElement) {
7065
+ var dAttribute = pathElement.getAttribute('d');
7066
+ if (!dAttribute) {
7067
+ return [];
7068
+ }
7069
+ return getPointsFromPathData(dAttribute);
7070
+ }
7071
+
7072
+ // Calculate the position of the 4 vertices of a rectangle relative to its parent svg
7073
+ var getRectangleCorners = function (rectSVG) {
7074
+ var ownerSVG = rectSVG.ownerSVGElement;
7075
+ var rectStrokeWidth = Number(rectSVG.getAttribute('stroke-width')) || 0;
7076
+ var strokeWidthOffset = rectStrokeWidth / 2;
7077
+ if (!ownerSVG) {
7078
+ throw new Error('Rectangle does not wrapper by svg.');
7079
+ }
7080
+ var ownerX = ownerSVG.x.baseVal.value;
7081
+ var ownerY = ownerSVG.y.baseVal.value;
7082
+ var ownerWidth = ownerSVG.width.baseVal.value;
7083
+ var ownerHeight = ownerSVG.height.baseVal.value;
7084
+ var a = { x: ownerX + strokeWidthOffset, y: ownerY + strokeWidthOffset };
7085
+ var b = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + strokeWidthOffset };
7086
+ var c = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7087
+ var d = { x: ownerX + strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7088
+ return [a, b, c, d];
7089
+ };
7090
+ //find rotation angle of svg element on g element
7091
+ var getElementRotationInfo = function (element) {
7092
+ var gElement = element;
7093
+ var rotationAngle = 0;
7094
+ while (!(gElement instanceof SVGGElement)) {
7095
+ gElement = gElement.parentElement;
7096
+ }
7097
+ var transform = gElement.getAttribute('transform');
7098
+ if (transform) {
7099
+ // Match the rotation value using a regular expression
7100
+ var rotateMatch = transform.match(/rotate\(([-\d.]+)(?:\s+[-\d.]+\s+[-\d.]+)?\)/);
7101
+ if (rotateMatch) {
7102
+ // The first capture group is the rotation angle
7103
+ rotationAngle = parseFloat(rotateMatch[1]);
7104
+ }
7105
+ }
7106
+ return rotationAngle;
7107
+ };
7491
7108
 
7492
7109
  /**
7493
7110
  * Check if position 1 is within the radius r of position 2
@@ -7515,603 +7132,1189 @@ var findNearestPosition = function (listPositions, targetPosition) {
7515
7132
  }
7516
7133
  return nearestPoint;
7517
7134
  };
7518
- /**
7519
- * From one point find projected Point on the line segment.
7520
- * @param position
7521
- * @param linePoints
7522
- * @returns
7523
- */
7524
- var findNearestPointOnSegment = function (position, linePoints) {
7525
- var beginPosition = linePoints[0], endPosition = linePoints[1];
7526
- var point = Flatten$1.point(position.x, position.y);
7527
- var segment = Flatten$1.segment(Flatten$1.point(beginPosition.x, beginPosition.y), Flatten$1.point(endPosition.x, endPosition.y));
7528
- var _a = point.distanceTo(segment); _a[0]; var segmentFromPointToSegment = _a[1];
7135
+ /**
7136
+ * From one point find projected Point on the line segment.
7137
+ * @param position
7138
+ * @param linePoints
7139
+ * @returns
7140
+ */
7141
+ var findNearestPointOnSegment = function (position, linePoints) {
7142
+ var beginPosition = linePoints[0], endPosition = linePoints[1];
7143
+ var point = Flatten$1.point(position.x, position.y);
7144
+ var segment = Flatten$1.segment(Flatten$1.point(beginPosition.x, beginPosition.y), Flatten$1.point(endPosition.x, endPosition.y));
7145
+ var _a = point.distanceTo(segment); _a[0]; var segmentFromPointToSegment = _a[1];
7146
+ return {
7147
+ x: segmentFromPointToSegment.pe.x,
7148
+ y: segmentFromPointToSegment.pe.y
7149
+ };
7150
+ };
7151
+ /**
7152
+ * From 1 point find projected Point on the line segments so that the distance between 2 points is shortest.
7153
+ * @param position
7154
+ * @param lines
7155
+ * @returns
7156
+ */
7157
+ var findNearestProjectedPoint = function (position, lines) {
7158
+ var possiblePoints = lines.map(function (p) { return findNearestPointOnSegment(position, p); });
7159
+ var nearestPoint = findNearestPosition(possiblePoints, position);
7160
+ return nearestPoint;
7161
+ };
7162
+ /**
7163
+ * Check if a point is inside a polygon
7164
+ * @param position
7165
+ * @param polygonPoints
7166
+ * @returns
7167
+ */
7168
+ var checkPointContainsPolygon = function (position, polygonPoints) {
7169
+ var polygon = new Flatten$1.Polygon();
7170
+ polygon.addFace(polygonPoints.map(function (p) { return Flatten$1.point(p.x, p.y); }));
7171
+ return polygon.contains(Flatten$1.point(position.x, position.y));
7172
+ };
7173
+ /**
7174
+ * @param ele : IElement
7175
+ * @returns Flatten.Polygon
7176
+ */
7177
+ var makePolygonOfElement = function (ele) {
7178
+ var polygon = new Flatten$1.Polygon();
7179
+ var vertexes = getFourVertexesOfBBoxFromElement(ele);
7180
+ polygon.addFace([
7181
+ Flatten$1.point(vertexes[0].x, vertexes[0].y),
7182
+ Flatten$1.point(vertexes[1].x, vertexes[1].y),
7183
+ Flatten$1.point(vertexes[2].x, vertexes[2].y),
7184
+ Flatten$1.point(vertexes[3].x, vertexes[3].y),
7185
+ ]);
7186
+ return polygon;
7187
+ };
7188
+ var getIntersectionPositions = function (pointStart, pointEnd, ele) {
7189
+ var segment = Flatten$1.segment(Flatten$1.point(pointStart.x, pointStart.y), Flatten$1.point(pointEnd.x, pointEnd.y));
7190
+ var polygonOfEle = makePolygonOfElement(ele);
7191
+ /* Remove duplicate positions from the result of finding the intersection points between a segment and a polygon.
7192
+ It then maps the intersection points to objects with rounded x and y coordinates. */
7193
+ return removeDuplicatePosition(segment.intersect(polygonOfEle).map(function (p) { return ({ x: Math.round(p.x), y: Math.round(p.y) }); }));
7194
+ };
7195
+ //Find the first intersection point of the line starting from startPosition to endPosition on the elements
7196
+ var getFirstIntersection = function (startPosition, endPosition, elements) {
7197
+ if (!endPosition)
7198
+ return undefined;
7199
+ var result;
7200
+ for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
7201
+ var element = elements_1[_i];
7202
+ //Find intersection positions on element
7203
+ var intersectionPoints = getIntersectionPositions(startPosition, endPosition, element);
7204
+ //If the line intersects at 1 point (can be the starting point or the ending point) or no point then ignore
7205
+ if (intersectionPoints.length <= 1) {
7206
+ continue;
7207
+ }
7208
+ var selectablePointsList = __spreadArray([], intersectionPoints, true);
7209
+ //If a point is found on a previous element, add it to the list of intersection points on the current element.
7210
+ if (result === null || result === void 0 ? void 0 : result.nearestIntersection) {
7211
+ selectablePointsList.push(result.nearestIntersection);
7212
+ }
7213
+ var nearest = findNearestPosition(selectablePointsList, startPosition);
7214
+ //If the closest intersection point to the starting point is not found or the new point is different from the previously found point, set a new value.
7215
+ if (!(result === null || result === void 0 ? void 0 : result.nearestIntersection) || !checkSamePosition(nearest, result.nearestIntersection)) {
7216
+ result = {
7217
+ element: element,
7218
+ intersectionPointsList: intersectionPoints,
7219
+ nearestIntersection: nearest,
7220
+ };
7221
+ }
7222
+ }
7223
+ return result;
7224
+ };
7225
+ //Find a point next to an element from a point on the element
7226
+ var generateSubstitutePosition = function (intersectedPosition, targetPosition, ele) {
7227
+ var translationOffset = 20;
7228
+ var _a = getFourVertexesOfBBoxFromElement(ele), vertex1Position = _a[0], vertex2Position = _a[1], vertex3Position = _a[2], vertex4Position = _a[3];
7229
+ var replacementPosition = null;
7230
+ if (checkSamePosition(vertex1Position, intersectedPosition, 0)) {
7231
+ //Cut at vertex 1 of bbox, move out a distance x,y
7232
+ replacementPosition = {
7233
+ x: vertex1Position.x - translationOffset,
7234
+ y: vertex1Position.y - translationOffset,
7235
+ };
7236
+ }
7237
+ else if (checkSamePosition(vertex2Position, intersectedPosition, 0)) {
7238
+ //Cut at vertex 2 of bbox, move out a distance x,y
7239
+ replacementPosition = {
7240
+ x: vertex2Position.x + translationOffset,
7241
+ y: vertex2Position.y - translationOffset,
7242
+ };
7243
+ }
7244
+ else if (checkSamePosition(vertex3Position, intersectedPosition, 0)) {
7245
+ //Cut at vertex 3 of bbox, move out a distance x,y
7246
+ replacementPosition = {
7247
+ x: vertex3Position.x + translationOffset,
7248
+ y: vertex3Position.y + translationOffset,
7249
+ };
7250
+ }
7251
+ else if (checkSamePosition(vertex4Position, intersectedPosition, 0)) {
7252
+ //Cut at vertex 4 of bbox, move out a distance x,y
7253
+ replacementPosition = {
7254
+ x: vertex4Position.x - translationOffset,
7255
+ y: vertex4Position.y + translationOffset,
7256
+ };
7257
+ }
7258
+ else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex2Position])) {
7259
+ //cut top edge, move left or right
7260
+ var lineOfVertex12 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex2Position.x, vertex2Position.y));
7261
+ //Check if the line lies on the edge of the bbox then move the starting point out 1 distance perpendicular to the edge.
7262
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex12)[0] === 0 &&
7263
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex12)[0] === 0) {
7264
+ //lie on a straight line 1-2
7265
+ replacementPosition = {
7266
+ x: intersectedPosition.x,
7267
+ y: intersectedPosition.y - translationOffset,
7268
+ };
7269
+ }
7270
+ else {
7271
+ //Translate to the left of vertex 1
7272
+ var leftPosition = {
7273
+ x: vertex1Position.x - translationOffset,
7274
+ y: vertex1Position.y,
7275
+ };
7276
+ //Translate to the right of vertex 2
7277
+ var rightPosition = {
7278
+ x: vertex2Position.x + translationOffset,
7279
+ y: vertex2Position.y,
7280
+ };
7281
+ replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7282
+ }
7283
+ }
7284
+ else if (checkPositionOnLine(intersectedPosition, [vertex3Position, vertex4Position])) {
7285
+ //cut bottom edge, move left or right
7286
+ var lineOfVertex34 = Flatten$1.line(Flatten$1.point(vertex3Position.x, vertex3Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7287
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex34)[0] === 0 &&
7288
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex34)[0] === 0) {
7289
+ //lie on a straight line 3-4
7290
+ replacementPosition = {
7291
+ x: intersectedPosition.x,
7292
+ y: intersectedPosition.y + translationOffset,
7293
+ };
7294
+ }
7295
+ else {
7296
+ //Translate to the left of vertex 4
7297
+ var leftPosition = {
7298
+ x: vertex4Position.x - translationOffset,
7299
+ y: vertex4Position.y,
7300
+ };
7301
+ //Translate to the right of vertex 3
7302
+ var rightPosition = {
7303
+ x: vertex3Position.x + translationOffset,
7304
+ y: vertex3Position.y,
7305
+ };
7306
+ replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7307
+ }
7308
+ }
7309
+ else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex4Position])) {
7310
+ //cut left edge, move up or down
7311
+ var lineOfVertex14 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7312
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex14)[0] === 0 &&
7313
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex14)[0] === 0) {
7314
+ //lie on a straight line 1-4
7315
+ replacementPosition = {
7316
+ x: intersectedPosition.x - translationOffset,
7317
+ y: intersectedPosition.y,
7318
+ };
7319
+ }
7320
+ else {
7321
+ //Translate to the top of vertex 1
7322
+ var topPosition = {
7323
+ x: vertex1Position.x,
7324
+ y: vertex1Position.y - translationOffset,
7325
+ };
7326
+ //Translate to the bottom of vertex 4
7327
+ var bottomPosition = {
7328
+ x: vertex4Position.x,
7329
+ y: vertex4Position.y + translationOffset,
7330
+ };
7331
+ replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7332
+ }
7333
+ }
7334
+ else if (checkPositionOnLine(intersectedPosition, [vertex2Position, vertex3Position])) {
7335
+ //cut right edge, move up or down
7336
+ var lineOfVertex23 = Flatten$1.line(Flatten$1.point(vertex2Position.x, vertex2Position.y), Flatten$1.point(vertex3Position.x, vertex3Position.y));
7337
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex23)[0] === 0 &&
7338
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex23)[0] === 0) {
7339
+ //lie on a straight line 2-3
7340
+ replacementPosition = {
7341
+ x: intersectedPosition.x + translationOffset,
7342
+ y: intersectedPosition.y,
7343
+ };
7344
+ }
7345
+ else {
7346
+ //Translate to the top of vertex 2
7347
+ var topPosition = {
7348
+ x: vertex2Position.x,
7349
+ y: vertex2Position.y - translationOffset,
7350
+ };
7351
+ //Translate to the bottom of vertex 3
7352
+ var bottomPosition = {
7353
+ x: vertex3Position.x,
7354
+ y: vertex3Position.y + translationOffset,
7355
+ };
7356
+ replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7357
+ }
7358
+ }
7359
+ return replacementPosition;
7360
+ };
7361
+ // export const getRelativePosition = (clientPosition: IPosition, relativeElement: Element): IPosition => {
7362
+ // const relativeRect = relativeElement.getBoundingClientRect();
7363
+ // return {
7364
+ // x: clientPosition.x - relativeRect.left,
7365
+ // y: clientPosition.y - relativeRect.top,
7366
+ // }
7367
+ // }
7368
+ var getFourVertexesOfBBoxFromElement = function (element) {
7369
+ var absolutePosition = getAbsolutePosition(element);
7370
+ var vertex1Position = {
7371
+ x: absolutePosition.x,
7372
+ y: absolutePosition.y
7373
+ };
7374
+ var vertex2Position = {
7375
+ x: absolutePosition.x + element.size.width,
7376
+ y: absolutePosition.y
7377
+ };
7378
+ var vertex3Position = {
7379
+ x: absolutePosition.x + element.size.width,
7380
+ y: absolutePosition.y + element.size.height
7381
+ };
7382
+ var vertex4Position = {
7383
+ x: absolutePosition.x,
7384
+ y: absolutePosition.y + element.size.height
7385
+ };
7386
+ return [vertex1Position, vertex2Position, vertex3Position, vertex4Position];
7387
+ };
7388
+ //get absolute position of element
7389
+ var getAbsolutePosition = function (element) {
7390
+ var parentElement = element.parentElement;
7391
+ var elemenetPositionWithTopLeftAnchor = {
7392
+ x: element.position.x,
7393
+ y: element.position.y,
7394
+ };
7395
+ if (element.positionAnchor === exports.PositioningAnchor.Center) {
7396
+ elemenetPositionWithTopLeftAnchor.x -= element.size.width / 2;
7397
+ elemenetPositionWithTopLeftAnchor.y -= element.size.height / 2;
7398
+ }
7399
+ if (!parentElement) {
7400
+ return __assign({}, elemenetPositionWithTopLeftAnchor);
7401
+ }
7402
+ var absoluteParentElement = getAbsolutePosition(parentElement);
7403
+ var x = elemenetPositionWithTopLeftAnchor.x + absoluteParentElement.x;
7404
+ var y = elemenetPositionWithTopLeftAnchor.y + absoluteParentElement.y;
7529
7405
  return {
7530
- x: segmentFromPointToSegment.pe.x,
7531
- y: segmentFromPointToSegment.pe.y
7406
+ x: x,
7407
+ y: y,
7532
7408
  };
7533
7409
  };
7534
- /**
7535
- * From 1 point find projected Point on the line segments so that the distance between 2 points is shortest.
7536
- * @param position
7537
- * @param lines
7538
- * @returns
7539
- */
7540
- var findNearestProjectedPoint = function (position, lines) {
7541
- var possiblePoints = lines.map(function (p) { return findNearestPointOnSegment(position, p); });
7542
- var nearestPoint = findNearestPosition(possiblePoints, position);
7543
- return nearestPoint;
7544
- };
7545
- /**
7546
- * Check if a point is inside a polygon
7547
- * @param position
7548
- * @param polygonPoints
7549
- * @returns
7550
- */
7551
- var checkPointContainsPolygon = function (position, polygonPoints) {
7552
- var polygon = new Flatten$1.Polygon();
7553
- polygon.addFace(polygonPoints.map(function (p) { return Flatten$1.point(p.x, p.y); }));
7554
- return polygon.contains(Flatten$1.point(position.x, position.y));
7410
+ //get absolute position of element
7411
+ var getPortAbsolutePosition = function (port, element) {
7412
+ var elementAbsolutePosition = getAbsolutePosition(element);
7413
+ return {
7414
+ x: elementAbsolutePosition.x + port.position.x,
7415
+ y: elementAbsolutePosition.y + port.position.y,
7416
+ };
7555
7417
  };
7556
- /**
7557
- * @param ele : IElement
7558
- * @returns Flatten.Polygon
7559
- */
7560
- var makePolygonOfElement = function (ele) {
7561
- var polygon = new Flatten$1.Polygon();
7562
- var vertexes = getFourVertexesOfBBoxFromElement(ele);
7563
- polygon.addFace([
7564
- Flatten$1.point(vertexes[0].x, vertexes[0].y),
7565
- Flatten$1.point(vertexes[1].x, vertexes[1].y),
7566
- Flatten$1.point(vertexes[2].x, vertexes[2].y),
7567
- Flatten$1.point(vertexes[3].x, vertexes[3].y),
7568
- ]);
7569
- return polygon;
7418
+ var transformAbsPositionToElementRelativePosition = function (position, element) {
7419
+ var parentElement = element.parentElement;
7420
+ if (!parentElement) {
7421
+ return position;
7422
+ }
7423
+ var absoluteParentElement = getAbsolutePosition(parentElement);
7424
+ var result = {
7425
+ x: position.x - absoluteParentElement.x,
7426
+ y: position.y - absoluteParentElement.y,
7427
+ };
7428
+ if (element.positionAnchor === exports.PositioningAnchor.Center) {
7429
+ result.x += element.size.width / 2;
7430
+ result.y += element.size.height / 2;
7431
+ }
7432
+ return result;
7570
7433
  };
7571
- var getIntersectionPositions = function (pointStart, pointEnd, ele) {
7572
- var segment = Flatten$1.segment(Flatten$1.point(pointStart.x, pointStart.y), Flatten$1.point(pointEnd.x, pointEnd.y));
7573
- var polygonOfEle = makePolygonOfElement(ele);
7574
- /* Remove duplicate positions from the result of finding the intersection points between a segment and a polygon.
7575
- It then maps the intersection points to objects with rounded x and y coordinates. */
7576
- return removeDuplicatePosition(segment.intersect(polygonOfEle).map(function (p) { return ({ x: Math.round(p.x), y: Math.round(p.y) }); }));
7434
+ var transformAbsPositionToRelativePositionInsideElement = function (absolutePosition, parentAbsolutePosition) {
7435
+ var _a, _b;
7436
+ var position = {
7437
+ x: absolutePosition.x - ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0),
7438
+ y: absolutePosition.y - ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0),
7439
+ };
7440
+ return position;
7577
7441
  };
7578
- //Find the first intersection point of the line starting from startPosition to endPosition on the elements
7579
- var getFirstIntersection = function (startPosition, endPosition, elements) {
7580
- if (!endPosition)
7581
- return undefined;
7582
- var result;
7583
- for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
7584
- var element = elements_1[_i];
7585
- //Find intersection positions on element
7586
- var intersectionPoints = getIntersectionPositions(startPosition, endPosition, element);
7587
- //If the line intersects at 1 point (can be the starting point or the ending point) or no point then ignore
7588
- if (intersectionPoints.length <= 1) {
7589
- continue;
7442
+ var correctPortPositionInElement = function (elementRelativePosition, elementWidth, elementHeight, portMoveableAreas, portSlideRailSVGClassName, element) {
7443
+ //Normalize a point so that it can lie exactly on an area
7444
+ var normalizePortPositionOnMoveableAreas = function (moveableAreas, position) {
7445
+ var lines = moveableAreas.filter(function (area) { return area.length === 2; });
7446
+ var polygons = moveableAreas.filter(function (area) { return area.length >= 3; });
7447
+ var normalizedPosition;
7448
+ //If moveableAreas is lines
7449
+ if (lines.length > 0) {
7450
+ var newPosition_1 = findNearestProjectedPoint({ x: position.x, y: position.y }, lines);
7451
+ if (newPosition_1) {
7452
+ normalizedPosition = newPosition_1;
7453
+ }
7590
7454
  }
7591
- var selectablePointsList = __spreadArray([], intersectionPoints, true);
7592
- //If a point is found on a previous element, add it to the list of intersection points on the current element.
7593
- if (result === null || result === void 0 ? void 0 : result.nearestIntersection) {
7594
- selectablePointsList.push(result.nearestIntersection);
7455
+ //If moveableAreas is polygons
7456
+ else if (polygons.length > 0) {
7457
+ var newPosition_2 = { x: position.x, y: position.y };
7458
+ var isContainsInPolygons = polygons.some(function (p) { return checkPointContainsPolygon(newPosition_2, p); });
7459
+ if (isContainsInPolygons) {
7460
+ normalizedPosition = newPosition_2;
7461
+ }
7595
7462
  }
7596
- var nearest = findNearestPosition(selectablePointsList, startPosition);
7597
- //If the closest intersection point to the starting point is not found or the new point is different from the previously found point, set a new value.
7598
- if (!(result === null || result === void 0 ? void 0 : result.nearestIntersection) || !checkSamePosition(nearest, result.nearestIntersection)) {
7599
- result = {
7600
- element: element,
7601
- intersectionPointsList: intersectionPoints,
7602
- nearestIntersection: nearest,
7603
- };
7463
+ return normalizedPosition;
7464
+ };
7465
+ var getSlideRailSVG = function (portSlideRailSVGClassName) {
7466
+ if (!element)
7467
+ return;
7468
+ var slideRailSVG = element.querySelector(".".concat(portSlideRailSVGClassName));
7469
+ return slideRailSVG;
7470
+ };
7471
+ //Calculate the position of the 4 vertices of a rectangle relative to element
7472
+ var calculateSlideRailRectSVGPositions = function (slideRailSVG) {
7473
+ var coordinates = getRectangleCorners(slideRailSVG);
7474
+ var ownerSVG = slideRailSVG.ownerSVGElement;
7475
+ var rotationAngle = getElementRotationInfo(ownerSVG);
7476
+ if (rotationAngle !== 0) {
7477
+ var rotationCenterX = elementWidth / 2;
7478
+ var rotationCenterY = elementHeight / 2;
7479
+ coordinates = getRotatedRectangleCoordinates(coordinates, rotationCenterX, rotationCenterY, rotationAngle);
7480
+ }
7481
+ return coordinates;
7482
+ };
7483
+ var normalizePortPositionOnSlideRailSVG = function (portSlideRailSVGClassName, position) {
7484
+ var slideRailSVG = getSlideRailSVG(portSlideRailSVGClassName);
7485
+ if (!slideRailSVG)
7486
+ return;
7487
+ var moveTo;
7488
+ //check and get new position if Rect element
7489
+ if (slideRailSVG instanceof SVGRectElement) {
7490
+ var _a = calculateSlideRailRectSVGPositions(slideRailSVG), a = _a[0], b = _a[1], c = _a[2], d = _a[3]; //Get 4 vertices of rect element
7491
+ var moveableAreas = [
7492
+ [a, b],
7493
+ [b, c],
7494
+ [c, d],
7495
+ [d, a]
7496
+ ];
7497
+ logger.info("Port's moveable areas parsed from svg ".concat(portSlideRailSVGClassName), moveableAreas);
7498
+ var newPosition_3 = normalizePortPositionOnMoveableAreas(moveableAreas, position);
7499
+ if (newPosition_3) {
7500
+ moveTo = newPosition_3;
7501
+ }
7502
+ }
7503
+ else if (slideRailSVG instanceof SVGCircleElement) { //check and get new position if circle element
7504
+ var cx = Number(slideRailSVG.getAttribute('cx'));
7505
+ var cy = Number(slideRailSVG.getAttribute('cy'));
7506
+ var r = Number(slideRailSVG.getAttribute('r'));
7507
+ var circle = Flatten$1.circle(Flatten$1.point(cx, cy), r);
7508
+ var _b = circle.distanceTo(Flatten$1.point(position.x, position.y)), num = _b[0], segment = _b[1];
7509
+ if (num <= r) {
7510
+ moveTo = {
7511
+ x: segment.ps.x,
7512
+ y: segment.ps.y,
7513
+ };
7514
+ }
7604
7515
  }
7516
+ return moveTo;
7517
+ };
7518
+ var newPosition;
7519
+ if (portMoveableAreas && portMoveableAreas.length > 0) { //If moveable areas is defined
7520
+ newPosition = normalizePortPositionOnMoveableAreas(portMoveableAreas, elementRelativePosition);
7605
7521
  }
7606
- return result;
7522
+ else if (portSlideRailSVGClassName) { //If port slide rail svg classname is defined
7523
+ newPosition = normalizePortPositionOnSlideRailSVG(portSlideRailSVGClassName, elementRelativePosition);
7524
+ }
7525
+ return newPosition || elementRelativePosition;
7607
7526
  };
7608
- //Find a point next to an element from a point on the element
7609
- var generateSubstitutePosition = function (intersectedPosition, targetPosition, ele) {
7610
- var translationOffset = 20;
7611
- var _a = getFourVertexesOfBBoxFromElement(ele), vertex1Position = _a[0], vertex2Position = _a[1], vertex3Position = _a[2], vertex4Position = _a[3];
7612
- var replacementPosition = null;
7613
- if (checkSamePosition(vertex1Position, intersectedPosition, 0)) {
7614
- //Cut at vertex 1 of bbox, move out a distance x,y
7615
- replacementPosition = {
7616
- x: vertex1Position.x - translationOffset,
7617
- y: vertex1Position.y - translationOffset,
7527
+ var windowsPositionToPaperPosition = function (clientPosition, paperElement, zoom) {
7528
+ var paperRect = paperElement.getBoundingClientRect();
7529
+ // Calculate the position relative to the paper element
7530
+ var xPosOnPaper = (clientPosition.x - paperRect.left) / zoom;
7531
+ var yPosOnPaper = (clientPosition.y - paperRect.top) / zoom;
7532
+ return {
7533
+ x: Math.round(xPosOnPaper),
7534
+ y: Math.round(yPosOnPaper),
7535
+ };
7536
+ };
7537
+
7538
+ var getSVGBBoxOutsideTransformedParent = function (svgElement) {
7539
+ var bbox = svgElement.getBBox(); // Get bounding box of the element
7540
+ var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
7541
+ // Define the four corners of the bounding box
7542
+ var corners = [
7543
+ { x: bbox.x, y: bbox.y },
7544
+ { x: bbox.x + bbox.width, y: bbox.y },
7545
+ { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
7546
+ { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
7547
+ ];
7548
+ // Function to apply the transformation matrix to a point
7549
+ function transformPoint(x, y, matrix) {
7550
+ return {
7551
+ x: matrix.a * x + matrix.c * y + matrix.e,
7552
+ y: matrix.b * x + matrix.d * y + matrix.f
7618
7553
  };
7619
7554
  }
7620
- else if (checkSamePosition(vertex2Position, intersectedPosition, 0)) {
7621
- //Cut at vertex 2 of bbox, move out a distance x,y
7622
- replacementPosition = {
7623
- x: vertex2Position.x + translationOffset,
7624
- y: vertex2Position.y - translationOffset,
7625
- };
7555
+ // Transform each corner according to the matrix
7556
+ if (matrix) {
7557
+ return corners.map(function (corner) {
7558
+ return transformPoint(corner.x, corner.y, matrix);
7559
+ });
7560
+ }
7561
+ else {
7562
+ return corners;
7626
7563
  }
7627
- else if (checkSamePosition(vertex3Position, intersectedPosition, 0)) {
7628
- //Cut at vertex 3 of bbox, move out a distance x,y
7629
- replacementPosition = {
7630
- x: vertex3Position.x + translationOffset,
7631
- y: vertex3Position.y + translationOffset,
7564
+ };
7565
+ //function returns the array of corners of the bbox of the element after applying the transformation matrix of the parent element
7566
+ var getRotatedSVGBBox = function (svgElement) {
7567
+ var bbox = svgElement.getBBox(); // Get bounding box of the element
7568
+ var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
7569
+ // Define the four corners of the bounding box
7570
+ var corners = [
7571
+ { x: bbox.x, y: bbox.y },
7572
+ { x: bbox.x + bbox.width, y: bbox.y },
7573
+ { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
7574
+ { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
7575
+ ];
7576
+ // Function to apply the transformation matrix to a point
7577
+ function transformPoint(x, y, matrix) {
7578
+ return {
7579
+ x: matrix.a * x + matrix.c * y,
7580
+ y: matrix.b * x + matrix.d * y // + matrix.f
7632
7581
  };
7633
7582
  }
7634
- else if (checkSamePosition(vertex4Position, intersectedPosition, 0)) {
7635
- //Cut at vertex 4 of bbox, move out a distance x,y
7636
- replacementPosition = {
7637
- x: vertex4Position.x - translationOffset,
7638
- y: vertex4Position.y + translationOffset,
7639
- };
7583
+ // Transform each corner according to the matrix
7584
+ if (matrix) {
7585
+ return corners.map(function (corner) {
7586
+ return transformPoint(corner.x, corner.y, matrix);
7587
+ });
7640
7588
  }
7641
- else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex2Position])) {
7642
- //cut top edge, move left or right
7643
- var lineOfVertex12 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex2Position.x, vertex2Position.y));
7644
- //Check if the line lies on the edge of the bbox then move the starting point out 1 distance perpendicular to the edge.
7645
- if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex12)[0] === 0 &&
7646
- Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex12)[0] === 0) {
7647
- //lie on a straight line 1-2
7648
- replacementPosition = {
7649
- x: intersectedPosition.x,
7650
- y: intersectedPosition.y - translationOffset,
7651
- };
7589
+ else {
7590
+ return corners;
7591
+ }
7592
+ };
7593
+
7594
+ var SelectionFrame = function (props) {
7595
+ var propTargetSVGElement = props.targetSVGElement, propWidth = props.width, propHeight = props.height, propFramePadding = props.framePadding, objectX = props.objectX, objectY = props.objectY,
7596
+ // movingOffsetThreshold: propMovingOffsetThreshold,
7597
+ propMovingRate = props.movingRate, propOnMouseDown = props.onMouseDown, propOnMouseUp = props.onMouseUp, propOnMove = props.onMove, propContainer = props.container, propResizability = props.resizability, propOnResize = props.onResize, PropDragDropHandlerElement = props.dragDropHandlerElement, propStrokeWidth = props.strokeWidth, propAnchor = props.anchor, zoom = props.zoom;
7598
+ var bbox = propTargetSVGElement === null || propTargetSVGElement === void 0 ? void 0 : propTargetSVGElement.getBBox();
7599
+ var _a = React.useState(propWidth || (bbox === null || bbox === void 0 ? void 0 : bbox.width) || MIN_ELEMENT_SIZE), width = _a[0], setWidth = _a[1];
7600
+ var _b = React.useState(propHeight || (bbox === null || bbox === void 0 ? void 0 : bbox.height) || MIN_ELEMENT_SIZE), height = _b[0], setHeight = _b[1];
7601
+ React.useEffect(function () {
7602
+ if (propWidth) {
7603
+ setWidth(propWidth);
7652
7604
  }
7653
- else {
7654
- //Translate to the left of vertex 1
7655
- var leftPosition = {
7656
- x: vertex1Position.x - translationOffset,
7657
- y: vertex1Position.y,
7658
- };
7659
- //Translate to the right of vertex 2
7660
- var rightPosition = {
7661
- x: vertex2Position.x + translationOffset,
7662
- y: vertex2Position.y,
7663
- };
7664
- replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7605
+ }, [objectX, propWidth]);
7606
+ React.useEffect(function () {
7607
+ if (propHeight) {
7608
+ setHeight(propHeight);
7665
7609
  }
7666
- }
7667
- else if (checkPositionOnLine(intersectedPosition, [vertex3Position, vertex4Position])) {
7668
- //cut bottom edge, move left or right
7669
- var lineOfVertex34 = Flatten$1.line(Flatten$1.point(vertex3Position.x, vertex3Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7670
- if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex34)[0] === 0 &&
7671
- Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex34)[0] === 0) {
7672
- //lie on a straight line 3-4
7673
- replacementPosition = {
7674
- x: intersectedPosition.x,
7675
- y: intersectedPosition.y + translationOffset,
7676
- };
7610
+ }, [objectY, propHeight]);
7611
+ var _c = React.useState(objectX !== null && objectX !== void 0 ? objectX : 0), curX = _c[0], setCurX = _c[1];
7612
+ var _d = React.useState(objectY !== null && objectY !== void 0 ? objectY : 0), curY = _d[0], setCurY = _d[1];
7613
+ React.useEffect(function () {
7614
+ if (objectX) {
7615
+ setCurX(objectX);
7677
7616
  }
7678
- else {
7679
- //Translate to the left of vertex 4
7680
- var leftPosition = {
7681
- x: vertex4Position.x - translationOffset,
7682
- y: vertex4Position.y,
7683
- };
7684
- //Translate to the right of vertex 3
7685
- var rightPosition = {
7686
- x: vertex3Position.x + translationOffset,
7687
- y: vertex3Position.y,
7688
- };
7689
- replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7617
+ }, [objectX]);
7618
+ React.useEffect(function () {
7619
+ if (objectY) {
7620
+ setCurY(objectY);
7690
7621
  }
7691
- }
7692
- else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex4Position])) {
7693
- //cut left edge, move up or down
7694
- var lineOfVertex14 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7695
- if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex14)[0] === 0 &&
7696
- Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex14)[0] === 0) {
7697
- //lie on a straight line 1-4
7698
- replacementPosition = {
7699
- x: intersectedPosition.x - translationOffset,
7700
- y: intersectedPosition.y,
7701
- };
7622
+ }, [objectY]);
7623
+ var framePadding = propFramePadding || 0;
7624
+ var r = 5;
7625
+ var _e = React.useState(false), draggingRect = _e[0], setDraggingRect = _e[1];
7626
+ var _f = React.useState(false), draggingCircle = _f[0], setDraggingCircle = _f[1];
7627
+ var _g = React.useState(0), startX = _g[0], setStartX = _g[1];
7628
+ var _h = React.useState(0), startY = _h[0], setStartY = _h[1];
7629
+ var _j = React.useState(0), xFromMouse = _j[0], setXFromMouse = _j[1];
7630
+ var _k = React.useState(0), yFromMouse = _k[0], setYFromMouse = _k[1];
7631
+ var _l = React.useState(0), lastMoveTime = _l[0], setLastMoveTime = _l[1];
7632
+ var getMousePosition = function (event) {
7633
+ var position = windowsPositionToPaperPosition({
7634
+ x: event.clientX,
7635
+ y: event.clientY
7636
+ }, propContainer, zoom);
7637
+ return position;
7638
+ };
7639
+ var addRectHandleMouseDown = function (event) {
7640
+ event.stopPropagation();
7641
+ if (!draggingCircle) {
7642
+ setDraggingRect(true);
7643
+ setStartX(event.clientX);
7644
+ setStartY(event.clientY);
7645
+ var mousePosition = getMousePosition(event);
7646
+ var xFromMouse_1 = (curX || 0) - mousePosition.x;
7647
+ var yFromMouse_1 = (curY || 0) - mousePosition.y;
7648
+ setXFromMouse(xFromMouse_1);
7649
+ setYFromMouse(yFromMouse_1);
7702
7650
  }
7703
- else {
7704
- //Translate to the top of vertex 1
7705
- var topPosition = {
7706
- x: vertex1Position.x,
7707
- y: vertex1Position.y - translationOffset,
7708
- };
7709
- //Translate to the bottom of vertex 4
7710
- var bottomPosition = {
7711
- x: vertex4Position.x,
7712
- y: vertex4Position.y + translationOffset,
7713
- };
7714
- replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7651
+ if (propOnMouseDown) {
7652
+ propOnMouseDown(event);
7653
+ }
7654
+ };
7655
+ var rectHandleMouseMove = React.useCallback(function (event) {
7656
+ var mouseEvent = event;
7657
+ if (draggingRect) {
7658
+ if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
7659
+ return;
7660
+ }
7661
+ //Coordinates of mouse on paper.
7662
+ var mousePosition = getMousePosition(mouseEvent);
7663
+ var newX = mousePosition.x + xFromMouse;
7664
+ var newY = mousePosition.y + yFromMouse;
7665
+ if (propOnMove) {
7666
+ setCurX(newX);
7667
+ setCurY(newY);
7668
+ propOnMove(newX, newY);
7669
+ setLastMoveTime(Date.now());
7670
+ setStartX(mouseEvent.clientX);
7671
+ setStartY(mouseEvent.clientY);
7672
+ }
7673
+ }
7674
+ }, [draggingRect, propOnMove, propMovingRate, startX, startY, lastMoveTime, xFromMouse, yFromMouse, zoom]);
7675
+ React.useEffect(function () {
7676
+ var addRectHandleMouseUp = function () {
7677
+ setDraggingRect(false);
7678
+ setXFromMouse(0);
7679
+ setYFromMouse(0);
7680
+ };
7681
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mousemove', rectHandleMouseMove);
7682
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mouseup', addRectHandleMouseUp);
7683
+ return function () {
7684
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mousemove', rectHandleMouseMove);
7685
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mouseup', addRectHandleMouseUp);
7686
+ };
7687
+ }, [propContainer, rectHandleMouseMove, zoom]);
7688
+ var circleHandleMouseDown = function (event) {
7689
+ event.stopPropagation();
7690
+ if (!draggingRect) {
7691
+ setStartX(event.clientX);
7692
+ setStartY(event.clientY);
7693
+ setDraggingCircle(true);
7715
7694
  }
7695
+ };
7696
+ React.useEffect(function () {
7697
+ logger.debug('SelectionFrame: circleHandleMouseDown triggered', {
7698
+ draggingCircle: draggingCircle,
7699
+ startX: startX,
7700
+ startY: startY,
7701
+ width: width,
7702
+ height: height,
7703
+ propMovingRate: propMovingRate
7704
+ });
7705
+ var circleHandleMouseMove = function (event) {
7706
+ var mouseEvent = event;
7707
+ if (draggingCircle) {
7708
+ var offsetX = mouseEvent.clientX - startX;
7709
+ var offsetY = mouseEvent.clientY - startY;
7710
+ if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
7711
+ return;
7712
+ }
7713
+ setStartX(mouseEvent.clientX);
7714
+ setStartY(mouseEvent.clientY);
7715
+ setLastMoveTime(Date.now());
7716
+ var newWidth = width;
7717
+ var newHeight = height;
7718
+ if (propResizability.keepRatio) {
7719
+ var resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
7720
+ var increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
7721
+ offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
7722
+ offsetY = increasing ? resizingRatio * height : -resizingRatio * height;
7723
+ }
7724
+ newWidth += offsetX;
7725
+ newHeight += offsetY;
7726
+ if (newWidth < MIN_ELEMENT_SIZE) {
7727
+ newWidth = MIN_ELEMENT_SIZE;
7728
+ }
7729
+ if (newHeight < MIN_ELEMENT_SIZE) {
7730
+ newHeight = MIN_ELEMENT_SIZE;
7731
+ }
7732
+ setWidth(newWidth);
7733
+ setHeight(newHeight);
7734
+ if (propOnResize) {
7735
+ propOnResize(newWidth, newHeight);
7736
+ }
7737
+ }
7738
+ };
7739
+ var circleHandleMouseUp = function () {
7740
+ setDraggingCircle(false);
7741
+ };
7742
+ var container = propContainer;
7743
+ container.addEventListener('mousemove', circleHandleMouseMove);
7744
+ container.addEventListener('mouseup', circleHandleMouseUp);
7745
+ //logging the start of the circle handle mouse move
7746
+ logger.debug('SelectionFrame: circleHandleMouseMove started', container);
7747
+ return function () {
7748
+ container.removeEventListener('mousemove', circleHandleMouseMove);
7749
+ container.removeEventListener('mouseup', circleHandleMouseUp);
7750
+ //logging the end of the circle handle mouse move
7751
+ logger.debug('SelectionFrame: circleHandleMouseMove ended', container);
7752
+ };
7753
+ }, [draggingCircle, width, height, curX, curY, lastMoveTime, propContainer, propMovingRate, propOnResize, propResizability, startX, startY]);
7754
+ var rectangleSize = Math.max(width, height);
7755
+ var leftX = framePadding;
7756
+ var topY = framePadding;
7757
+ if (propAnchor === exports.PositioningAnchor.Center) {
7758
+ leftX -= rectangleSize / 2;
7759
+ topY -= rectangleSize / 2;
7716
7760
  }
7717
- else if (checkPositionOnLine(intersectedPosition, [vertex2Position, vertex3Position])) {
7718
- //cut right edge, move up or down
7719
- var lineOfVertex23 = Flatten$1.line(Flatten$1.point(vertex2Position.x, vertex2Position.y), Flatten$1.point(vertex3Position.x, vertex3Position.y));
7720
- if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex23)[0] === 0 &&
7721
- Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex23)[0] === 0) {
7722
- //lie on a straight line 2-3
7723
- replacementPosition = {
7724
- x: intersectedPosition.x + translationOffset,
7725
- y: intersectedPosition.y,
7726
- };
7761
+ return (React.createElement(React.Fragment, null,
7762
+ PropDragDropHandlerElement && React.createElement(PropDragDropHandlerElement, { dragging: draggingRect, onMouseDown: addRectHandleMouseDown }),
7763
+ React.createElement("rect", { vectorEffect: "non-scaling-stroke", x: leftX, y: topY, width: width, height: height, fill: 'none', stroke: 'blue', strokeWidth: propStrokeWidth || 5, cursor: draggingRect ? 'grabbing' : 'grab', onMouseDown: addRectHandleMouseDown, onMouseUp: propOnMouseUp }),
7764
+ propResizability.enabled ?
7765
+ (React.createElement("circle", { cursor: 'se-resize', cx: leftX + width, cy: topY + height, r: r, fill: 'blue', stroke: 'blue', onMouseDown: circleHandleMouseDown })) : null));
7766
+ };
7767
+
7768
+ var useSelectionFrame = function (props) {
7769
+ React.useEffect(function () {
7770
+ //log selection frame rendering
7771
+ if (props.targetSVGElement) {
7772
+ console.debug('Rendering SelectionFrame for targetSVGElement:', props.targetSVGElement);
7727
7773
  }
7728
7774
  else {
7729
- //Translate to the top of vertex 2
7730
- var topPosition = {
7731
- x: vertex2Position.x,
7732
- y: vertex2Position.y - translationOffset,
7733
- };
7734
- //Translate to the bottom of vertex 3
7735
- var bottomPosition = {
7736
- x: vertex3Position.x,
7737
- y: vertex3Position.y + translationOffset,
7738
- };
7739
- replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7775
+ console.warn('No targetSVGElement provided for SelectionFrame.');
7740
7776
  }
7741
- }
7742
- return replacementPosition;
7777
+ if (props.targetSVGElement && props.container) {
7778
+ //render SelectionFrame component to the parent element of the targetSVGElement
7779
+ if (props.container) {
7780
+ var svg_1 = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
7781
+ svg_1.style.overflow = 'visible';
7782
+ svg_1.style.outline = 'none';
7783
+ props.targetSVGElement.appendChild(svg_1);
7784
+ var root_1 = createRoot(svg_1);
7785
+ root_1.render(React.createElement(SelectionFrame, __assign({}, props, { container: props.container })));
7786
+ return function () {
7787
+ root_1.unmount();
7788
+ if (props.targetSVGElement) {
7789
+ props.targetSVGElement.removeChild(svg_1);
7790
+ }
7791
+ };
7792
+ }
7793
+ }
7794
+ }, [props]);
7795
+ };
7796
+
7797
+ var eventEmitter = new EventEmitter();
7798
+ var emitPaperClicked = function (ev) {
7799
+ eventEmitter.emit(EVENT_NAME.PAPER_CLICK, ev);
7743
7800
  };
7744
- var getRelativePosition = function (clientPosition, relativeElement) {
7745
- var relativeRect = relativeElement.getBoundingClientRect();
7801
+ var onPaperClicked = function (callback) {
7802
+ eventEmitter.on(EVENT_NAME.PAPER_CLICK, callback);
7803
+ var off = function () {
7804
+ eventEmitter.off(EVENT_NAME.PAPER_CLICK, callback);
7805
+ };
7746
7806
  return {
7747
- x: clientPosition.x - relativeRect.left,
7748
- y: clientPosition.y - relativeRect.top,
7807
+ off: off
7749
7808
  };
7750
7809
  };
7751
- var getFourVertexesOfBBoxFromElement = function (element) {
7752
- var absolutePosition = getAbsolutePosition(element);
7753
- var vertex1Position = {
7754
- x: absolutePosition.x,
7755
- y: absolutePosition.y
7810
+ var emitPortMouseUp = function (ev, port, elementId) {
7811
+ eventEmitter.emit(EVENT_NAME.PORT_MOUSE_UP, ev, port, elementId);
7812
+ };
7813
+ var onPortMouseUp = function (callback) {
7814
+ eventEmitter.on(EVENT_NAME.PORT_MOUSE_UP, callback);
7815
+ var off = function () {
7816
+ eventEmitter.off(EVENT_NAME.PORT_MOUSE_UP, callback);
7756
7817
  };
7757
- var vertex2Position = {
7758
- x: absolutePosition.x + element.size.width,
7759
- y: absolutePosition.y
7818
+ return {
7819
+ off: off
7760
7820
  };
7761
- var vertex3Position = {
7762
- x: absolutePosition.x + element.size.width,
7763
- y: absolutePosition.y + element.size.height
7821
+ };
7822
+ var emitPortMouseDown = function (ev, port, elementId) {
7823
+ eventEmitter.emit(EVENT_NAME.PORT_MOUSE_DOWN, ev, port, elementId);
7824
+ };
7825
+ var onPortMouseDown = function (callback) {
7826
+ eventEmitter.on(EVENT_NAME.PORT_MOUSE_DOWN, callback);
7827
+ var off = function () {
7828
+ eventEmitter.off(EVENT_NAME.PORT_MOUSE_DOWN, callback);
7764
7829
  };
7765
- var vertex4Position = {
7766
- x: absolutePosition.x,
7767
- y: absolutePosition.y + element.size.height
7830
+ return {
7831
+ off: off
7768
7832
  };
7769
- return [vertex1Position, vertex2Position, vertex3Position, vertex4Position];
7770
7833
  };
7771
- //get absolute position of element
7772
- var getAbsolutePosition = function (element) {
7773
- var parentElement = element.parentElement;
7774
- var elemenetPositionWithTopLeftAnchor = {
7775
- x: element.position.x,
7776
- y: element.position.y,
7834
+ var emitPortMoved = function (port, elementId, oldPosition, newPosition) {
7835
+ eventEmitter.emit(EVENT_NAME.PORT_MOVED, port, elementId, oldPosition, newPosition);
7836
+ };
7837
+ var onPortMoved = function (callback) {
7838
+ eventEmitter.on(EVENT_NAME.PORT_MOVED, callback);
7839
+ var off = function () {
7840
+ eventEmitter.off(EVENT_NAME.PORT_MOVED, callback);
7777
7841
  };
7778
- if (element.positionAnchor === exports.PositioningAnchor.Center) {
7779
- elemenetPositionWithTopLeftAnchor.x -= element.size.width / 2;
7780
- elemenetPositionWithTopLeftAnchor.y -= element.size.height / 2;
7781
- }
7782
- if (!parentElement) {
7783
- return __assign({}, elemenetPositionWithTopLeftAnchor);
7784
- }
7785
- var absoluteParentElement = getAbsolutePosition(parentElement);
7786
- var x = elemenetPositionWithTopLeftAnchor.x + absoluteParentElement.x;
7787
- var y = elemenetPositionWithTopLeftAnchor.y + absoluteParentElement.y;
7788
7842
  return {
7789
- x: x,
7790
- y: y,
7843
+ off: off
7844
+ };
7845
+ };
7846
+ var emitElementMoved = function (element, oldPosition, newPosition) {
7847
+ eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(element.id));
7848
+ };
7849
+ var onElementMoved = function (elementId, callback) {
7850
+ eventEmitter.on("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
7851
+ var off = function () {
7852
+ eventEmitter.off("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
7853
+ };
7854
+ return {
7855
+ off: off
7856
+ };
7857
+ };
7858
+ var emitElementResized = function (element, oldSize, newSize) {
7859
+ eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(element.id), oldSize, newSize);
7860
+ };
7861
+ var onElementResized = function (elementId, callback) {
7862
+ eventEmitter.on("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
7863
+ var off = function () {
7864
+ eventEmitter.off("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
7865
+ };
7866
+ return {
7867
+ off: off
7868
+ };
7869
+ };
7870
+ var emitCommandDeleteSelectedPort = function () {
7871
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT);
7872
+ };
7873
+ var onCommandDeleteSelectedPort = function (callback) {
7874
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
7875
+ var off = function () {
7876
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
7877
+ };
7878
+ return {
7879
+ off: off
7880
+ };
7881
+ };
7882
+ var emitCommandDeleteSelectedElement = function () {
7883
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT);
7884
+ };
7885
+ var onCommandDeleteSelectedElement = function (callback) {
7886
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
7887
+ var off = function () {
7888
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
7889
+ };
7890
+ return {
7891
+ off: off
7892
+ };
7893
+ };
7894
+ var emitCommandDeleteSelectedLink = function () {
7895
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK);
7896
+ };
7897
+ var onCommandDeleteSelectedLink = function (callback) {
7898
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
7899
+ var off = function () {
7900
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
7901
+ };
7902
+ return {
7903
+ off: off
7904
+ };
7905
+ };
7906
+ var emitCommandDeleteSelectedText = function () {
7907
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT);
7908
+ };
7909
+ var onCommandDeleteSelectedText = function (callback) {
7910
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
7911
+ var off = function () {
7912
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
7913
+ };
7914
+ return {
7915
+ off: off
7916
+ };
7917
+ };
7918
+ var emitElementLinkStarted = function (elementLink) {
7919
+ eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_STARTED, elementLink);
7920
+ };
7921
+ var onElementLinkStarted = function (callback) {
7922
+ eventEmitter.on(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
7923
+ var off = function () {
7924
+ eventEmitter.off(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
7925
+ };
7926
+ return {
7927
+ off: off
7928
+ };
7929
+ };
7930
+ var emitElementLinkEnded = function (elementLink) {
7931
+ eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_ENDED, elementLink);
7932
+ };
7933
+ var onElementLinkEnded = function (callback) {
7934
+ eventEmitter.on(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
7935
+ var off = function () {
7936
+ eventEmitter.off(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
7937
+ };
7938
+ return {
7939
+ off: off
7940
+ };
7941
+ };
7942
+ var emitElementSelected = function (element) {
7943
+ eventEmitter.emit(EVENT_NAME.ELEMENT_SELECTED, element);
7944
+ };
7945
+ var onElementSelected = function (callback) {
7946
+ eventEmitter.on(EVENT_NAME.ELEMENT_SELECTED, callback);
7947
+ var off = function () {
7948
+ eventEmitter.off(EVENT_NAME.ELEMENT_SELECTED, callback);
7949
+ };
7950
+ return {
7951
+ off: off
7952
+ };
7953
+ };
7954
+ var emitCommandRenderElement = function (elementId) {
7955
+ eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_ELEMENT, elementId);
7956
+ };
7957
+ var onCommandRenderElement = function (callback) {
7958
+ eventEmitter.on(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
7959
+ var off = function () {
7960
+ eventEmitter.off(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
7961
+ };
7962
+ return {
7963
+ off: off
7964
+ };
7965
+ };
7966
+ var emitPortSelected = function (port, elementId) {
7967
+ eventEmitter.emit(EVENT_NAME.PORT_SELECTED, port, elementId);
7968
+ };
7969
+ var onPortSelected = function (callback) {
7970
+ eventEmitter.on(EVENT_NAME.PORT_SELECTED, callback);
7971
+ var off = function () {
7972
+ eventEmitter.off(EVENT_NAME.PORT_SELECTED, callback);
7973
+ };
7974
+ return {
7975
+ off: off
7791
7976
  };
7792
7977
  };
7793
- //get absolute position of element
7794
- var getPortAbsolutePosition = function (port, element) {
7795
- var elementAbsolutePosition = getAbsolutePosition(element);
7978
+ var emitCommandRenderPort = function (portId, elementId) {
7979
+ eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_PORT, portId, elementId);
7980
+ };
7981
+ var onCommandRenderPort = function (callback) {
7982
+ eventEmitter.on(EVENT_NAME.COMMAND_RENDER_PORT, callback);
7983
+ var off = function () {
7984
+ eventEmitter.off(EVENT_NAME.COMMAND_RENDER_PORT, callback);
7985
+ };
7796
7986
  return {
7797
- x: elementAbsolutePosition.x + port.position.x,
7798
- y: elementAbsolutePosition.y + port.position.y,
7987
+ off: off
7799
7988
  };
7800
7989
  };
7801
- var transformAbsPositionToElementRelativePosition = function (position, element) {
7802
- var parentElement = element.parentElement;
7803
- if (!parentElement) {
7804
- return position;
7805
- }
7806
- var absoluteParentElement = getAbsolutePosition(parentElement);
7807
- var result = {
7808
- x: position.x - absoluteParentElement.x,
7809
- y: position.y - absoluteParentElement.y,
7990
+ var emitTextSelected = function (text) {
7991
+ eventEmitter.emit(EVENT_NAME.TEXT_SELECTED, text);
7992
+ };
7993
+ var onTextSelected = function (callback) {
7994
+ eventEmitter.on(EVENT_NAME.TEXT_SELECTED, callback);
7995
+ var off = function () {
7996
+ eventEmitter.off(EVENT_NAME.TEXT_SELECTED, callback);
7810
7997
  };
7811
- if (element.positionAnchor === exports.PositioningAnchor.Center) {
7812
- result.x += element.size.width / 2;
7813
- result.y += element.size.height / 2;
7998
+ return {
7999
+ off: off
8000
+ };
8001
+ };
8002
+ var paperEventEmitterContext = React.createContext({
8003
+ emitter: eventEmitter,
8004
+ emitPaperClicked: emitPaperClicked,
8005
+ onPaperClicked: onPaperClicked,
8006
+ emitPortMouseUp: emitPortMouseUp,
8007
+ onPortMouseUp: onPortMouseUp,
8008
+ emitPortMouseDown: emitPortMouseDown,
8009
+ onPortMouseDown: onPortMouseDown,
8010
+ emitPortMoved: emitPortMoved,
8011
+ onPortMoved: onPortMoved,
8012
+ emitPortSelected: emitPortSelected,
8013
+ onPortSelected: onPortSelected,
8014
+ emitElementMoved: emitElementMoved,
8015
+ onElementMoved: onElementMoved,
8016
+ emitElementResized: emitElementResized,
8017
+ onElementResized: onElementResized,
8018
+ emitElementSelected: emitElementSelected,
8019
+ onElementSelected: onElementSelected,
8020
+ emitCommandRenderElement: emitCommandRenderElement,
8021
+ onCommandRenderElement: onCommandRenderElement,
8022
+ emitCommandDeleteSelectedPort: emitCommandDeleteSelectedPort,
8023
+ onCommandDeleteSelectedPort: onCommandDeleteSelectedPort,
8024
+ emitCommandDeleteSelectedElement: emitCommandDeleteSelectedElement,
8025
+ onCommandDeleteSelectedElement: onCommandDeleteSelectedElement,
8026
+ emitCommandDeleteSelectedLink: emitCommandDeleteSelectedLink,
8027
+ onCommandDeleteSelectedLink: onCommandDeleteSelectedLink,
8028
+ emitCommandDeleteSelectedText: emitCommandDeleteSelectedText,
8029
+ onCommandDeleteSelectedText: onCommandDeleteSelectedText,
8030
+ emitElementLinkStarted: emitElementLinkStarted,
8031
+ onElementLinkStarted: onElementLinkStarted,
8032
+ emitElementLinkEnded: emitElementLinkEnded,
8033
+ onElementLinkEnded: onElementLinkEnded,
8034
+ emitTextSelected: emitTextSelected,
8035
+ onTextSelected: onTextSelected,
8036
+ emitCommandRenderPort: emitCommandRenderPort,
8037
+ onCommandRenderPort: onCommandRenderPort,
8038
+ });
8039
+
8040
+ var editorConfigurationContext = React.createContext(null);
8041
+ var useEditorConfiguration = function () {
8042
+ var context = React.useContext(editorConfigurationContext);
8043
+ if (!context) {
8044
+ throw new Error("useEditorConfiguration must be used within an EditorConfigurationProvider");
7814
8045
  }
7815
- return result;
8046
+ return context;
7816
8047
  };
7817
- var transformAbsPositionToRelativePositionInsideElement = function (absolutePosition, parentAbsolutePosition) {
7818
- var _a, _b;
7819
- var position = {
7820
- x: absolutePosition.x - ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0),
7821
- y: absolutePosition.y - ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0),
8048
+ var EditorConfigurationContextProvider = editorConfigurationContext.Provider;
8049
+
8050
+ /**
8051
+ * Zoom context to manage zoom level and related state.
8052
+ * This context can be used to provide zoom functionality across the application.
8053
+ */
8054
+ var zoomContext = React.createContext(null);
8055
+ var ZoomContextProvider = function (_a) {
8056
+ var children = _a.children;
8057
+ var _b = React.useState(1), zoom = _b[0], setZoom = _b[1];
8058
+ var _c = React.useState(0), scrollLeft = _c[0], setScrollLeft = _c[1];
8059
+ var _d = React.useState(0), scrollTop = _d[0], setScrollTop = _d[1];
8060
+ var wrapperRef = React.useRef(null);
8061
+ var contentRef = React.useRef(null);
8062
+ var handleWheel = function (e) {
8063
+ // Chỉ zoom khi giữ Ctrl
8064
+ if (!e.ctrlKey)
8065
+ return;
8066
+ e.preventDefault();
8067
+ var delta = -e.deltaY;
8068
+ var zoomFactor = 0.05;
8069
+ var newZoom = zoom + (delta > 0 ? zoomFactor : -zoomFactor);
8070
+ newZoom = Math.max(0.1, Math.min(newZoom, 4));
8071
+ if (!wrapperRef.current || !contentRef.current)
8072
+ return;
8073
+ var wrapper = wrapperRef.current;
8074
+ var content = contentRef.current;
8075
+ // Get bounding rectangle of the content
8076
+ var rect = content.getBoundingClientRect();
8077
+ var offsetX = e.clientX - rect.left;
8078
+ var offsetY = e.clientY - rect.top;
8079
+ var percentX = offsetX / (content.offsetWidth);
8080
+ var percentY = offsetY / (content.offsetHeight);
8081
+ console.log(offsetX, offsetY, content.offsetWidth, content.offsetHeight, percentX, percentY);
8082
+ // Old width and height of content
8083
+ var prevWidth = content.offsetWidth * zoom;
8084
+ var prevHeight = content.offsetHeight * zoom;
8085
+ var newWidth = content.offsetWidth * newZoom;
8086
+ var newHeight = content.offsetHeight * newZoom;
8087
+ var scrollLeft = wrapper.scrollLeft + (percentX * (newWidth - prevWidth));
8088
+ var scrollTop = wrapper.scrollTop + (percentY * (newHeight - prevHeight));
8089
+ setZoom(newZoom);
8090
+ setScrollLeft(scrollLeft);
8091
+ setScrollTop(scrollTop);
7822
8092
  };
7823
- return position;
8093
+ React.useLayoutEffect(function () {
8094
+ var _a;
8095
+ (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({
8096
+ left: scrollLeft,
8097
+ top: scrollTop,
8098
+ });
8099
+ }, [zoom, scrollLeft, scrollTop]);
8100
+ var resetZoom = function () {
8101
+ setZoom(1);
8102
+ };
8103
+ React.useEffect(function () {
8104
+ var preventBrowserZoom = function (e) {
8105
+ if (e.ctrlKey || e.metaKey) {
8106
+ e.preventDefault();
8107
+ }
8108
+ };
8109
+ window.addEventListener("wheel", preventBrowserZoom, { passive: false });
8110
+ return function () {
8111
+ window.removeEventListener("wheel", preventBrowserZoom);
8112
+ };
8113
+ }, []);
8114
+ return (React.createElement(zoomContext.Provider, { value: { zoom: zoom, setZoom: setZoom, resetZoom: resetZoom } },
8115
+ React.createElement("div", { ref: wrapperRef, onWheel: handleWheel, style: {
8116
+ width: "100vw",
8117
+ height: "92vh",
8118
+ overflow: "auto",
8119
+ } },
8120
+ React.createElement("div", { ref: contentRef, style: {
8121
+ transform: "scale(".concat(zoom, ")"),
8122
+ transformOrigin: "top left",
8123
+ // transition: "transform 0.1s linear",
8124
+ } }, children))));
7824
8125
  };
7825
- var correctPortPositionInElement = function (elementRelativePosition, elementWidth, elementHeight, portMoveableAreas, portSlideRailSVGClassName, element) {
7826
- //Normalize a point so that it can lie exactly on an area
7827
- var normalizePortPositionOnMoveableAreas = function (moveableAreas, position) {
7828
- var lines = moveableAreas.filter(function (area) { return area.length === 2; });
7829
- var polygons = moveableAreas.filter(function (area) { return area.length >= 3; });
7830
- var normalizedPosition;
7831
- //If moveableAreas is lines
7832
- if (lines.length > 0) {
7833
- var newPosition_1 = findNearestProjectedPoint({ x: position.x, y: position.y }, lines);
7834
- if (newPosition_1) {
7835
- normalizedPosition = newPosition_1;
8126
+ var useZoomContext = function () {
8127
+ var context = React.useContext(zoomContext);
8128
+ if (!context) {
8129
+ throw new Error("useZoomContext must be used within a ZoomContextProvider");
8130
+ }
8131
+ return context;
8132
+ };
8133
+
8134
+ var Text = React.forwardRef(function (_a, ref) {
8135
+ var id = _a.id, content = _a.content, x = _a.x, y = _a.y, width = _a.width, height = _a.height, editable = _a.editable, _b = _a.selectable, selectable = _b === void 0 ? true : _b, _c = _a.align, align = _c === void 0 ? exports.TextAlign.left : _c, fontSizeProp = _a.fontSize, border = _a.border, container = _a.container, parentAbsolutePosition = _a.parentAbsolutePosition, onSelected = _a.onSelected, onMoved = _a.onMoved, onResized = _a.onResized, onContentChanged = _a.onContentChanged;
8136
+ var _d = React.useState(false), isSelected = _d[0], setIsSelected = _d[1];
8137
+ var _e = React.useState(false), isEditing = _e[0], setIsEditing = _e[1];
8138
+ var textFontSize = useEditorConfiguration().textFontSize;
8139
+ var zoom = useZoomContext().zoom;
8140
+ var absolutePosition = React.useMemo(function () {
8141
+ var _a, _b;
8142
+ return {
8143
+ x: ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0) + x,
8144
+ y: ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0) + y,
8145
+ };
8146
+ }, [x, y, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y]);
8147
+ var svgRef = React.useRef();
8148
+ var _f = React.useContext(paperEventEmitterContext), onPaperClicked = _f.onPaperClicked, emitTextSelected = _f.emitTextSelected, onPortSelected = _f.onPortSelected, onElementSelected = _f.onElementSelected, onTextSelected = _f.onTextSelected;
8149
+ React.useEffect(function () {
8150
+ var paperClickListener = onPaperClicked(function (ev) {
8151
+ var _a;
8152
+ var textareaELe = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('textarea');
8153
+ if (ev.target !== textareaELe) {
8154
+ setIsSelected(false);
8155
+ setIsEditing(false);
7836
8156
  }
7837
- }
7838
- //If moveableAreas is polygons
7839
- else if (polygons.length > 0) {
7840
- var newPosition_2 = { x: position.x, y: position.y };
7841
- var isContainsInPolygons = polygons.some(function (p) { return checkPointContainsPolygon(newPosition_2, p); });
7842
- if (isContainsInPolygons) {
7843
- normalizedPosition = newPosition_2;
8157
+ });
8158
+ var portSelectedListener = onPortSelected(function (port) {
8159
+ setIsSelected(false);
8160
+ setIsEditing(false);
8161
+ });
8162
+ var elementSelectedListener = onElementSelected(function (element) {
8163
+ setIsSelected(false);
8164
+ setIsEditing(false);
8165
+ });
8166
+ var textSelectedListener = onTextSelected(function (text) {
8167
+ if (text.id !== id) {
8168
+ setIsSelected(false);
8169
+ setIsEditing(false);
7844
8170
  }
7845
- }
7846
- return normalizedPosition;
7847
- };
7848
- var getSlideRailSVG = function (portSlideRailSVGClassName) {
7849
- if (!element)
8171
+ });
8172
+ return function () {
8173
+ paperClickListener.off();
8174
+ portSelectedListener.off();
8175
+ elementSelectedListener.off();
8176
+ textSelectedListener.off();
8177
+ };
8178
+ }, []);
8179
+ //Handle click on svg element
8180
+ var handleClick = function (ev) {
8181
+ if (!selectable)
7850
8182
  return;
7851
- var slideRailSVG = element.querySelector(".".concat(portSlideRailSVGClassName));
7852
- return slideRailSVG;
7853
- };
7854
- //Calculate the position of the 4 vertices of a rectangle relative to element
7855
- var calculateSlideRailRectSVGPositions = function (slideRailSVG) {
7856
- var coordinates = getRectangleCorners(slideRailSVG);
7857
- var ownerSVG = slideRailSVG.ownerSVGElement;
7858
- var rotationAngle = getElementRotationInfo(ownerSVG);
7859
- if (rotationAngle !== 0) {
7860
- var rotationCenterX = elementWidth / 2;
7861
- var rotationCenterY = elementHeight / 2;
7862
- coordinates = getRotatedRectangleCoordinates(coordinates, rotationCenterX, rotationCenterY, rotationAngle);
7863
- }
7864
- return coordinates;
8183
+ ev.stopPropagation();
8184
+ var position = {
8185
+ x: x,
8186
+ y: y,
8187
+ };
8188
+ var text = {
8189
+ id: id,
8190
+ content: content,
8191
+ position: position,
8192
+ size: {
8193
+ width: width,
8194
+ height: height,
8195
+ },
8196
+ editable: editable
8197
+ };
8198
+ setIsSelected(true);
8199
+ onSelected && onSelected(text);
8200
+ emitTextSelected(text);
7865
8201
  };
7866
- var normalizePortPositionOnSlideRailSVG = function (portSlideRailSVGClassName, position) {
7867
- var slideRailSVG = getSlideRailSVG(portSlideRailSVGClassName);
7868
- if (!slideRailSVG)
8202
+ var handleChangeText = function (ev) {
8203
+ if (!editable)
7869
8204
  return;
7870
- var moveTo;
7871
- //check and get new position if Rect element
7872
- if (slideRailSVG instanceof SVGRectElement) {
7873
- var _a = calculateSlideRailRectSVGPositions(slideRailSVG), a = _a[0], b = _a[1], c = _a[2], d = _a[3]; //Get 4 vertices of rect element
7874
- var moveableAreas = [
7875
- [a, b],
7876
- [b, c],
7877
- [c, d],
7878
- [d, a]
7879
- ];
7880
- logger.info("Port's moveable areas parsed from svg ".concat(portSlideRailSVGClassName), moveableAreas);
7881
- var newPosition_3 = normalizePortPositionOnMoveableAreas(moveableAreas, position);
7882
- if (newPosition_3) {
7883
- moveTo = newPosition_3;
7884
- }
8205
+ onContentChanged === null || onContentChanged === void 0 ? void 0 : onContentChanged(ev, ev.target.value);
8206
+ };
8207
+ useSelectionFrame({
8208
+ objectX: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.x,
8209
+ objectY: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.y,
8210
+ container: container,
8211
+ targetSVGElement: (isSelected && svgRef.current) ? svgRef.current : undefined,
8212
+ resizability: {
8213
+ enabled: onResized ? true : false,
8214
+ keepRatio: false,
8215
+ },
8216
+ onMove: onMoved,
8217
+ onResize: onResized,
8218
+ strokeWidth: 3,
8219
+ zoom: zoom,
8220
+ });
8221
+ var textAlign = React.useMemo(function () {
8222
+ switch (align) {
8223
+ case exports.TextAlign.left:
8224
+ return 'left';
8225
+ case exports.TextAlign.right:
8226
+ return 'right';
8227
+ case exports.TextAlign.center:
8228
+ return 'center';
8229
+ default:
8230
+ return 'left';
7885
8231
  }
7886
- else if (slideRailSVG instanceof SVGCircleElement) { //check and get new position if circle element
7887
- var cx = Number(slideRailSVG.getAttribute('cx'));
7888
- var cy = Number(slideRailSVG.getAttribute('cy'));
7889
- var r = Number(slideRailSVG.getAttribute('r'));
7890
- var circle = Flatten$1.circle(Flatten$1.point(cx, cy), r);
7891
- var _b = circle.distanceTo(Flatten$1.point(position.x, position.y)), num = _b[0], segment = _b[1];
7892
- if (num <= r) {
7893
- moveTo = {
7894
- x: segment.ps.x,
7895
- y: segment.ps.y,
7896
- };
8232
+ }, [align]);
8233
+ var fontSize = fontSizeProp || textFontSize || TEXT_FONT_SIZE;
8234
+ var borderStyle = border || 'none';
8235
+ return (React.createElement("svg", { style: {
8236
+ overflow: "visible",
8237
+ pointerEvents: selectable ? undefined : 'none',
8238
+ }, x: x, y: y, ref: function (node) {
8239
+ svgRef.current = node;
8240
+ if (typeof ref === 'function') {
8241
+ ref(node);
7897
8242
  }
7898
- }
7899
- return moveTo;
7900
- };
7901
- var newPosition;
7902
- if (portMoveableAreas && portMoveableAreas.length > 0) { //If moveable areas is defined
7903
- newPosition = normalizePortPositionOnMoveableAreas(portMoveableAreas, elementRelativePosition);
7904
- }
7905
- else if (portSlideRailSVGClassName) { //If port slide rail svg classname is defined
7906
- newPosition = normalizePortPositionOnSlideRailSVG(portSlideRailSVGClassName, elementRelativePosition);
7907
- }
7908
- return newPosition || elementRelativePosition;
7909
- };
8243
+ else if (ref) {
8244
+ ref.current = node;
8245
+ }
8246
+ }, onClick: handleClick },
8247
+ React.createElement("foreignObject", { width: width, height: height, style: {
8248
+ overflow: 'visible',
8249
+ userSelect: 'none',
8250
+ WebkitUserSelect: 'none',
8251
+ msUserSelect: 'none'
8252
+ } },
8253
+ React.createElement("div", { style: {
8254
+ width: '100%',
8255
+ height: '100%',
8256
+ borderWidth: '1px',
8257
+ borderColor: '#ccc',
8258
+ borderStyle: borderStyle,
8259
+ // whiteSpace: 'pre-wrap',
8260
+ boxSizing: 'border-box',
8261
+ } },
8262
+ React.createElement("textarea", { style: {
8263
+ fontFamily: 'initial',
8264
+ display: 'inline-block',
8265
+ width: '100%',
8266
+ height: '100%',
8267
+ overflow: 'hidden',
8268
+ border: 'none',
8269
+ background: 'transparent',
8270
+ outline: 'none',
8271
+ resize: 'none',
8272
+ textAlign: textAlign,
8273
+ fontSize: fontSize,
8274
+ }, readOnly: !isEditing, onDoubleClick: function () {
8275
+ if (editable) {
8276
+ setIsEditing(true);
8277
+ }
8278
+ }, value: content, onChange: handleChangeText })))));
8279
+ });
8280
+ var Text$1 = React.memo(Text);
7910
8281
 
7911
8282
  var Port1 = React.forwardRef(function (props, ref) {
7912
8283
  var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, container = props.container, label = props.label, parentAbsolutePosition = props.parentAbsolutePosition, onPortLabelMoved = props.onPortLabelMoved, onPortLabelResized = props.onPortLabelResized, onPortLabelContentChanged = props.onPortLabelContentChanged, onSelected = props.onSelected, onMouseDown = props.onMouseDown, onMouseUp = props.onMouseUp, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, onMouseMove = props.onMouseMove, calculateRotationAngle = props.calculateRotationAngle,
7913
8284
  // onManuallyTriggerRenderHandler,
7914
8285
  renderShape = props.renderShape, children = props.children;
7915
8286
  var textRef = React.useRef(null);
7916
- var rotationAngle = React.useMemo(function () {
7917
- if (!calculateRotationAngle)
7918
- return 0;
7919
- return calculateRotationAngle(x, y);
7920
- }, [calculateRotationAngle, x, y]);
7921
- var renderLabel = function (label) {
7922
- var content = label.content, size = label.size;
7923
- var position = label.position || PORT_LABEL_POSITION;
7924
- return React.createElement(Text$1, { id: label.id, ref: textRef, x: x + position.x, y: y + position.y, parentAbsolutePosition: parentAbsolutePosition, width: size.width, height: size.height, editable: label.editable, selectable: label.selectable, content: content, fontSize: label.fontSize, border: label.border, container: container, onMoved: function (xOnPaper, yOnPaper) {
7925
- if (onPortLabelMoved) {
7926
- var relativePosInSideEle = transformAbsPositionToRelativePositionInsideElement({ x: xOnPaper, y: yOnPaper }, parentAbsolutePosition);
7927
- var newXPort = relativePosInSideEle.x - x;
7928
- var newYPort = relativePosInSideEle.y - y;
7929
- onPortLabelMoved(newXPort, newYPort, id);
7930
- }
7931
- }, onResized: function (width, height) { return onPortLabelResized === null || onPortLabelResized === void 0 ? void 0 : onPortLabelResized(width, height, id); }, onContentChanged: function (ev, newValue) { return onPortLabelContentChanged === null || onPortLabelContentChanged === void 0 ? void 0 : onPortLabelContentChanged(ev, newValue, id); } });
7932
- };
7933
- var renderedShape = React.useMemo(function () {
7934
- if (renderShape) {
7935
- var RenderShape = renderShape;
7936
- return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle }), children));
7937
- }
7938
- else {
7939
- return React.createElement(Circle, { onMouseDown: function (e) { return onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(id, e); }, onMouseUp: function (e) { return onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(id, e); }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseMove: function (e) { return onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(id, e); }, onClick: function (e) { return onSelected === null || onSelected === void 0 ? void 0 : onSelected(id, e); }, ref: ref, x: x, y: y, positioningAnchor: exports.PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" }, children);
7940
- }
7941
- }, [props]);
7942
- return (React.createElement(React.Fragment, null,
7943
- renderedShape,
7944
- label && renderLabel(label)));
7945
- });
7946
- var Port = React.memo(Port1);
7947
-
7948
- // Render the svg <path> element
7949
- function getCurvePathData(points, smoothing, closed) {
7950
- if (smoothing === void 0) { smoothing = 0.2; }
7951
- // append first 2 points for closed paths
7952
- if (closed) {
7953
- points = points.concat(points.slice(0, 2));
7954
- }
7955
- // Properties of a line
7956
- var line = function (pointA, pointB) {
7957
- var lengthX = pointB.x - pointA.x;
7958
- var lengthY = pointB.y - pointA.y;
7959
- return {
7960
- length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
7961
- angle: Math.atan2(lengthY, lengthX)
7962
- };
7963
- };
7964
- // Position of a control point
7965
- var controlPoint = function (current, previous, next, reverse) {
7966
- var p = previous || current;
7967
- var n = next || current;
7968
- var o = line(p, n);
7969
- var angle = o.angle + (reverse ? Math.PI : 0);
7970
- var length = o.length * smoothing;
7971
- var x = current.x + Math.cos(angle) * length;
7972
- var y = current.y + Math.sin(angle) * length;
7973
- return { x: x, y: y };
7974
- };
7975
- var pathData = [];
7976
- pathData.push({ type: "M", values: [points[0].x, points[0].y] });
7977
- for (var i = 1; i < points.length; i++) {
7978
- var point = points[i];
7979
- var cp1 = controlPoint(points[i - 1], points[i - 2], point);
7980
- var cp2 = controlPoint(point, points[i - 1], points[i + 1], true);
7981
- var command = {
7982
- type: "C",
7983
- values: [cp1.x, cp1.y, cp2.x, cp2.y, point.x, point.y]
7984
- };
7985
- pathData.push(command);
7986
- }
7987
- // copy last commands 1st controlpoint to first curveto
7988
- if (closed) {
7989
- var comLast = pathData[pathData.length - 1];
7990
- var valuesLastC = comLast.values;
7991
- var valuesFirstC = pathData[1].values;
7992
- pathData[1] = {
7993
- type: "C",
7994
- values: [valuesLastC[0], valuesLastC[1], valuesFirstC.slice(2)].flat()
7995
- };
7996
- // delete last curveto
7997
- pathData = pathData.slice(0, pathData.length - 1);
7998
- }
7999
- return pathData;
8000
- }
8001
- // convert pathdata to d attribute string
8002
- function pathDataToD(pathData, decimals) {
8003
- if (decimals === void 0) { decimals = 3; }
8004
- var d = pathData
8005
- .map(function (com) {
8006
- return "".concat(com.type).concat(com.values.map(function (value) { return +value.toFixed(decimals); }).join(" "));
8007
- })
8008
- .join(" ");
8009
- return d;
8010
- }
8011
- function createSmoothPathString(points, smoothing, close) {
8012
- var pathData = getCurvePathData(points, smoothing, close);
8013
- var pathString = pathDataToD(pathData);
8014
- return pathString;
8015
- }
8016
- // a helper function to measure the distance between 2 points
8017
- function dist(p1, p2) {
8018
- var dx = p2.x - p1.x;
8019
- var dy = p2.y - p1.y;
8020
- return Math.sqrt(dx * dx + dy * dy);
8021
- }
8022
- //find distance from starting point of path to a point
8023
- function getLengthForPoint(p, thePath, precision) {
8024
- if (precision === void 0) { precision = 50; }
8025
- var pathLength = thePath.getTotalLength();
8026
- var theRecord = pathLength; //length of path
8027
- var division = pathLength / precision;
8028
- var theSegment;
8029
- for (var i = 0; i < precision; i++) {
8030
- // get a point on the path for thia distance
8031
- var _p = thePath.getPointAtLength(i * division);
8032
- // get the distance between the new point _p and the point p
8033
- var theDistance = dist(_p, p);
8034
- if (theDistance < theRecord) {
8035
- // if the distance is smaller than the record set the new record
8036
- theRecord = theDistance;
8037
- theSegment = i;
8038
- }
8039
- }
8040
- return (theSegment * division);
8041
- }
8042
- //Add points to the list of points in the correct position
8043
- function addPointToList(point, listPoints, path) {
8044
- var getAddIndex = function (startIndex, endIndex) {
8045
- //Add in the middle if there are only 2 points
8046
- if ((endIndex - startIndex) === 1) {
8047
- return startIndex + 1;
8048
- }
8049
- var middleIndex = Math.ceil((startIndex + endIndex) / 2);
8050
- var lengthOfMiddlePoint = getLengthForPoint(listPoints[middleIndex], path); //distance from start point to mid point
8051
- var lengthOfAddedPoint = getLengthForPoint(point, path); //distance from adding point to mid point
8052
- //compare if lengthOfMiddlePoint is less than lengthOfAddedPoint,
8053
- //then new point can be added in the range of mid point to end point,
8054
- //otherwise it can be added in the range of start point to middle point.
8055
- if (lengthOfAddedPoint < lengthOfMiddlePoint) {
8056
- return getAddIndex(startIndex, middleIndex);
8287
+ var rotationAngle = React.useMemo(function () {
8288
+ if (!calculateRotationAngle)
8289
+ return 0;
8290
+ return calculateRotationAngle(x, y);
8291
+ }, [calculateRotationAngle, x, y]);
8292
+ var renderLabel = function (label) {
8293
+ var content = label.content, size = label.size;
8294
+ var position = label.position || PORT_LABEL_POSITION;
8295
+ return React.createElement(Text$1, { id: label.id, ref: textRef, x: x + position.x, y: y + position.y, parentAbsolutePosition: parentAbsolutePosition, width: size.width, height: size.height, editable: label.editable, selectable: label.selectable, content: content, fontSize: label.fontSize, border: label.border, container: container, onMoved: function (xOnPaper, yOnPaper) {
8296
+ if (onPortLabelMoved) {
8297
+ var relativePosInSideEle = transformAbsPositionToRelativePositionInsideElement({ x: xOnPaper, y: yOnPaper }, parentAbsolutePosition);
8298
+ var newXPort = relativePosInSideEle.x - x;
8299
+ var newYPort = relativePosInSideEle.y - y;
8300
+ onPortLabelMoved(newXPort, newYPort, id);
8301
+ }
8302
+ }, onResized: function (width, height) { return onPortLabelResized === null || onPortLabelResized === void 0 ? void 0 : onPortLabelResized(width, height, id); }, onContentChanged: function (ev, newValue) { return onPortLabelContentChanged === null || onPortLabelContentChanged === void 0 ? void 0 : onPortLabelContentChanged(ev, newValue, id); } });
8303
+ };
8304
+ var renderedShape = React.useMemo(function () {
8305
+ if (renderShape) {
8306
+ var RenderShape = renderShape;
8307
+ return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle }), children));
8057
8308
  }
8058
8309
  else {
8059
- return getAddIndex(middleIndex, endIndex);
8060
- }
8061
- };
8062
- var addedIndex = getAddIndex(0, listPoints.length - 1);
8063
- listPoints.splice(addedIndex, 0, point);
8064
- return __spreadArray([], listPoints, true);
8065
- }
8066
- // Parse the d attribute of a path element and extract points from path commands
8067
- function getPointsFromPathData(dAttribute) {
8068
- var points = [];
8069
- // Remove extra whitespace and split by command letters
8070
- var cleanD = dAttribute.replace(/\s+/g, ' ').trim();
8071
- // Regular expression to match path commands (M, L, C, etc.) and their values
8072
- var commandRegex = /([MLCZmlcz])\s*([^MLCZmlcz]*)/g;
8073
- var match;
8074
- while ((match = commandRegex.exec(cleanD)) !== null) {
8075
- var command = match[1].toUpperCase();
8076
- var values = match[2].trim();
8077
- if (values) {
8078
- var coords = values.split(/[\s,]+/).map(Number).filter(function (num) { return !isNaN(num); });
8079
- switch (command) {
8080
- case 'M': // Move to
8081
- if (coords.length >= 2) {
8082
- points.push({ x: coords[0], y: coords[1] });
8083
- }
8084
- break;
8085
- case 'L': // Line to
8086
- if (coords.length >= 2) {
8087
- points.push({ x: coords[0], y: coords[1] });
8088
- }
8089
- break;
8090
- case 'C': // Cubic bezier curve
8091
- // For cubic curves, we take the end point (last 2 coordinates)
8092
- if (coords.length >= 6) {
8093
- points.push({ x: coords[4], y: coords[5] });
8094
- }
8095
- break;
8096
- case 'Q': // Quadratic bezier curve
8097
- // For quadratic curves, we take the end point (last 2 coordinates)
8098
- if (coords.length >= 4) {
8099
- points.push({ x: coords[2], y: coords[3] });
8100
- }
8101
- break;
8102
- }
8310
+ return React.createElement(Circle, { onMouseDown: function (e) { return onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(id, e); }, onMouseUp: function (e) { return onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(id, e); }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseMove: function (e) { return onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(id, e); }, onClick: function (e) { return onSelected === null || onSelected === void 0 ? void 0 : onSelected(id, e); }, ref: ref, x: x, y: y, positioningAnchor: exports.PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" }, children);
8103
8311
  }
8104
- }
8105
- return points;
8106
- }
8107
- // Get points from a path element's d attribute
8108
- function getPointsFromPathElement(pathElement) {
8109
- var dAttribute = pathElement.getAttribute('d');
8110
- if (!dAttribute) {
8111
- return [];
8112
- }
8113
- return getPointsFromPathData(dAttribute);
8114
- }
8312
+ }, [props]);
8313
+ return (React.createElement(React.Fragment, null,
8314
+ renderedShape,
8315
+ label && renderLabel(label)));
8316
+ });
8317
+ var Port = React.memo(Port1);
8115
8318
 
8116
8319
  //Defined remove icon for element link, shown when element link is selected.
8117
8320
  function CloseIcon(_a) {
@@ -8140,17 +8343,34 @@ var IElementLink = function (_a) {
8140
8343
  }), selectedLabelRef = _l[0], setSelectedLabelRef = _l[1];
8141
8344
  var _m = React.useState(false), isSelectedLink = _m[0], setIsSelectedLink = _m[1];
8142
8345
  var _o = React.useContext(paperEventEmitterContext), onPaperClicked = _o.onPaperClicked, onElementSelected = _o.onElementSelected;
8346
+ var zoom = useZoomContext().zoom;
8143
8347
  var pathRef = React.useRef(null);
8144
8348
  var labelRef = React.useRef(null);
8145
8349
  var sourceLabelRef = React.useRef(null);
8146
8350
  var targetLabelRef = React.useRef(null);
8147
8351
  var isFirstRender = React.useRef(true);
8148
8352
  var onPointsChangedRef = React.useRef();
8353
+ var lastUpdatedPoints = React.useRef(Date.now());
8149
8354
  var angleMarkerStart = '0';
8150
8355
  var angleMarkerEnd = '0';
8151
8356
  var markerStartPosition;
8152
8357
  var markerEndPosition;
8153
8358
  var centerPathPosition = undefined;
8359
+ // Throttle pointsProp updates to avoid excessive renders
8360
+ React.useEffect(function () {
8361
+ var delay = 100; // 100ms delay
8362
+ var timeoutId = setTimeout(function () {
8363
+ var now = Date.now();
8364
+ if (now - lastUpdatedPoints.current >= delay) {
8365
+ setPoints(pointsProp || []);
8366
+ lastUpdatedPoints.current = now;
8367
+ }
8368
+ }, delay - (Date.now() - lastUpdatedPoints.current));
8369
+ return function () {
8370
+ clearTimeout(timeoutId);
8371
+ };
8372
+ // Use JSON.stringify for deep comparison
8373
+ }, [JSON.stringify(pointsProp)]);
8154
8374
  React.useEffect(function () {
8155
8375
  var paperClickListener = onPaperClicked(function () {
8156
8376
  setSelectedLabelRef({
@@ -8202,10 +8422,13 @@ var IElementLink = function (_a) {
8202
8422
  var handleMouseMove = function (ev) {
8203
8423
  var mouseEvent = ev;
8204
8424
  if (isDragging && draggingPointIndex !== undefined && container) {
8205
- var offset_1 = getRelativePosition({ x: mouseEvent.clientX, y: mouseEvent.clientY }, container);
8425
+ var paperPosition_1 = windowsPositionToPaperPosition({
8426
+ x: mouseEvent.clientX,
8427
+ y: mouseEvent.clientY
8428
+ }, container, zoom);
8206
8429
  setPoints(function (prev) {
8207
8430
  var temp = __spreadArray([], prev, true);
8208
- temp[draggingPointIndex] = offset_1;
8431
+ temp[draggingPointIndex] = paperPosition_1;
8209
8432
  return temp;
8210
8433
  });
8211
8434
  }
@@ -8220,23 +8443,19 @@ var IElementLink = function (_a) {
8220
8443
  container === null || container === void 0 ? void 0 : container.removeEventListener('mousemove', handleMouseMove);
8221
8444
  container === null || container === void 0 ? void 0 : container.removeEventListener('mouseup', mouseUp);
8222
8445
  };
8223
- }, [container, isDragging, draggingPointIndex]);
8446
+ }, [container, isDragging, draggingPointIndex, zoom]);
8224
8447
  var handleMouseDownOnPath = function (ev) {
8225
8448
  ev.preventDefault();
8226
- var svgContainer = ev.target.ownerSVGElement;
8227
8449
  //add point if click on path
8228
8450
  setIsDragging(true);
8229
- var rect = svgContainer.getBoundingClientRect();
8230
- var offsetX = ev.clientX - rect.left;
8231
- var offsetY = ev.clientY - rect.top;
8232
8451
  //Position of the new point on the path
8233
- var newPoint = {
8234
- x: offsetX,
8235
- y: offsetY
8236
- };
8237
- var newPoints = addPointToList(newPoint, __spreadArray(__spreadArray([sourcePosition], points, true), [targetPosition], false), pathRef.current);
8452
+ var paperPosition = windowsPositionToPaperPosition({
8453
+ x: ev.clientX,
8454
+ y: ev.clientY
8455
+ }, container, zoom);
8456
+ var newPoints = addPointToList(paperPosition, __spreadArray(__spreadArray([sourcePosition], points, true), [targetPosition], false), pathRef.current);
8238
8457
  var pointsWithoutStartEndPoint = newPoints.slice(1, newPoints.length - 1);
8239
- var addedIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === newPoint.x && p.y === newPoint.y; });
8458
+ var addedIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === paperPosition.x && p.y === paperPosition.y; });
8240
8459
  var leftPointIndex = addedIndex - 1;
8241
8460
  var rightPointIndex = addedIndex + 1;
8242
8461
  var distFromLeftPoint;
@@ -8275,7 +8494,7 @@ var IElementLink = function (_a) {
8275
8494
  }
8276
8495
  }
8277
8496
  //Find new index of added point
8278
- _draggingPointIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === newPoint.x && p.y === newPoint.y; });
8497
+ _draggingPointIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === paperPosition.x && p.y === paperPosition.y; });
8279
8498
  setDraggingPointIndex(_draggingPointIndex);
8280
8499
  setPoints(pointsWithoutStartEndPoint);
8281
8500
  };
@@ -8390,62 +8609,6 @@ var IElementLink = function (_a) {
8390
8609
  };
8391
8610
  var ElementLink = React.memo(IElementLink);
8392
8611
 
8393
- var getSVGBBoxOutsideTransformedParent = function (svgElement) {
8394
- var bbox = svgElement.getBBox(); // Get bounding box of the element
8395
- var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
8396
- // Define the four corners of the bounding box
8397
- var corners = [
8398
- { x: bbox.x, y: bbox.y },
8399
- { x: bbox.x + bbox.width, y: bbox.y },
8400
- { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
8401
- { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
8402
- ];
8403
- // Function to apply the transformation matrix to a point
8404
- function transformPoint(x, y, matrix) {
8405
- return {
8406
- x: matrix.a * x + matrix.c * y + matrix.e,
8407
- y: matrix.b * x + matrix.d * y + matrix.f
8408
- };
8409
- }
8410
- // Transform each corner according to the matrix
8411
- if (matrix) {
8412
- return corners.map(function (corner) {
8413
- return transformPoint(corner.x, corner.y, matrix);
8414
- });
8415
- }
8416
- else {
8417
- return corners;
8418
- }
8419
- };
8420
- //function returns the array of corners of the bbox of the element after applying the transformation matrix of the parent element
8421
- var getRotatedSVGBBox = function (svgElement) {
8422
- var bbox = svgElement.getBBox(); // Get bounding box of the element
8423
- var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
8424
- // Define the four corners of the bounding box
8425
- var corners = [
8426
- { x: bbox.x, y: bbox.y },
8427
- { x: bbox.x + bbox.width, y: bbox.y },
8428
- { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
8429
- { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
8430
- ];
8431
- // Function to apply the transformation matrix to a point
8432
- function transformPoint(x, y, matrix) {
8433
- return {
8434
- x: matrix.a * x + matrix.c * y,
8435
- y: matrix.b * x + matrix.d * y // + matrix.f
8436
- };
8437
- }
8438
- // Transform each corner according to the matrix
8439
- if (matrix) {
8440
- return corners.map(function (corner) {
8441
- return transformPoint(corner.x, corner.y, matrix);
8442
- });
8443
- }
8444
- else {
8445
- return corners;
8446
- }
8447
- };
8448
-
8449
8612
  function configureLogger(_a) {
8450
8613
  var level = _a.level, customLogger = _a.customLogger;
8451
8614
  if (level !== undefined)
@@ -8502,6 +8665,7 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8502
8665
  var _d = React.useState(false), someElementLinkStarted = _d[0], setSomeElementLinkStarted = _d[1];
8503
8666
  var _e = React.useState(), potentialPortPosition = _e[0], setPotentialPortPosition = _e[1];
8504
8667
  var _paperEventEmitterContext = React.useContext(paperEventEmitterContext);
8668
+ var zoom = useZoomContext().zoom;
8505
8669
  var elementRef = React.useRef(null);
8506
8670
  React.useImperativeHandle(forwardedRef, function () { return elementRef.current; });
8507
8671
  var elementLinkStarted = React.useRef();
@@ -8769,24 +8933,17 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8769
8933
  setPotentialPortPosition(undefined);
8770
8934
  return;
8771
8935
  }
8772
- /* The above code is calculating the relative position of the mouse within a specific
8773
- element on the page. It first gets the bounding rectangle of the element using
8774
- `getBoundingClientRect()` and the bounding box of the element using `getBBox()`. Then,
8775
- it calculates the relative position of the mouse within the element by subtracting the
8776
- element's position from the mouse's position. The result is stored in the
8777
- `mousePositionOnElement` object, which contains the x and y coordinates of the mouse
8778
- relative to the element. */
8779
- var elementBounding = elementRef.current.getBoundingClientRect();
8780
- var elementBBox = elementRef.current.getBBox();
8781
- //Get relative position of mouse on element
8936
+ var paper = windowsPositionToPaperPosition({
8937
+ x: ev.clientX,
8938
+ y: ev.clientY
8939
+ }, container, zoom);
8940
+ var elementAbsPosition_1 = getElementAbsPosition();
8782
8941
  var mousePositionOnElement = {
8783
- x: ev.clientX - (elementBounding.left - elementBBox.x),
8784
- y: ev.clientY - (elementBounding.top - elementBBox.y),
8942
+ x: paper.x - elementAbsPosition_1.x,
8943
+ y: paper.y - elementAbsPosition_1.y,
8785
8944
  };
8786
8945
  var tempPotentialPortPosition = normalizePortPosition(mousePositionOnElement);
8787
- //Kiểm tra điểm potential(Điểm này nằm trên portMoveableAreas) nằm trong phạm vi bán kính của vị trí con trỏ chuột không
8788
- //Nếu có thì cho nó là potentialPortPosition và hiện portPlaceholderShape
8789
- //Nếu không thì bỏ qua hoặc xóa potentialPortPosition.
8946
+ // Ensure the potential port position is within the element
8790
8947
  if (checkSamePosition(mousePositionOnElement, tempPotentialPortPosition, 5)) {
8791
8948
  setPotentialPortPosition(tempPotentialPortPosition);
8792
8949
  }
@@ -8907,11 +9064,11 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8907
9064
  (React.createElement(SelectionFrame, { container: container, targetSVGElement: ((_g = selectedPort === null || selectedPort === void 0 ? void 0 : selectedPort.ref) === null || _g === void 0 ? void 0 : _g.current) || undefined, resizability: {
8908
9065
  enabled: false,
8909
9066
  keepRatio: false
8910
- }, objectX: elementAbsPosition.x + selectedPort.position.x, objectY: elementAbsPosition.y + selectedPort.position.y, onMove: handlePortMove })),
9067
+ }, objectX: elementAbsPosition.x + selectedPort.position.x, objectY: elementAbsPosition.y + selectedPort.position.y, onMove: handlePortMove, zoom: zoom })),
8911
9068
  hoveredPort && hoveredPort.id === p.id && (React.createElement(SelectionFrame, { container: container, targetSVGElement: ((_h = hoveredPort === null || hoveredPort === void 0 ? void 0 : hoveredPort.ref) === null || _h === void 0 ? void 0 : _h.current) || undefined, resizability: {
8912
9069
  enabled: false,
8913
9070
  keepRatio: false
8914
- } })));
9071
+ }, zoom: zoom })));
8915
9072
  }), texts === null || texts === void 0 ? void 0 :
8916
9073
  texts.map(function (t, index) {
8917
9074
  var _a, _b;
@@ -9234,6 +9391,8 @@ var Paper = function (props) {
9234
9391
  var _j = React.useState(null), selectedElementSVG = _j[0], setSelectedElementSVG = _j[1];
9235
9392
  var _k = React.useState(false), mouseDownedOnPaper = _k[0], setMouseDownedOnPaper = _k[1];
9236
9393
  var paperEventEmitter = React.useContext(paperEventEmitterContext);
9394
+ var zoom = useZoomContext().zoom;
9395
+ var zoomRef = React.useRef(zoom);
9237
9396
  var paperContainerRef = React.useRef(null);
9238
9397
  var tempLinkRef = React.useRef(tempLink); //Cache tempLink to avoid re-render when tempLink changed
9239
9398
  var elementsRef = React.useRef(elements); //Cache elements to avoid re-render when elements changed
@@ -9241,6 +9400,9 @@ var Paper = function (props) {
9241
9400
  var textsRef = React.useRef(texts); //Cache texts to avoid re-render when texts changed
9242
9401
  var size = props.size;
9243
9402
  var selectedElementAbsPosition = React.useMemo(function () { return selectedElement ? getAbsolutePosition(selectedElement) : null; }, [selectedElement, selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.position, selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size]);
9403
+ React.useEffect(function () {
9404
+ zoomRef.current = zoom;
9405
+ }, [zoom]);
9244
9406
  React.useEffect(function () {
9245
9407
  setElements(props.elements);
9246
9408
  }, [props.elements]);
@@ -9353,12 +9515,12 @@ var Paper = function (props) {
9353
9515
  updateElementsTree();
9354
9516
  }, [elements]);
9355
9517
  //Get all child elements of the deleted element
9356
- var getDeletedChildElements = function (deletedElement) {
9357
- if (!deletedElement.childrenElementsInTree)
9518
+ var getChildOfElement = function (element) {
9519
+ if (!element.childrenElementsInTree)
9358
9520
  return [];
9359
- var childElms = deletedElement.childrenElementsInTree;
9521
+ var childElms = element.childrenElementsInTree;
9360
9522
  var childOfChildElements = childElms.reduce(function (acc, ele) {
9361
- return __spreadArray(__spreadArray([], acc, true), getDeletedChildElements(ele), true);
9523
+ return __spreadArray(__spreadArray([], acc, true), getChildOfElement(ele), true);
9362
9524
  }, []);
9363
9525
  return __spreadArray(__spreadArray([], childElms, true), childOfChildElements, true);
9364
9526
  };
@@ -9367,7 +9529,8 @@ var Paper = function (props) {
9367
9529
  var _a;
9368
9530
  var listener = paperEventEmitter.onCommandDeleteSelectedElement(function () {
9369
9531
  if (selectedElement) {
9370
- var deletedChildElements = getDeletedChildElements(selectedElement);
9532
+ selectedElement.parentElement = undefined; //Remove parent element to avoid memory leak. This will remove the element from the parent element's childrenElements array.
9533
+ var deletedChildElements = getChildOfElement(selectedElement);
9371
9534
  var deletedElementIds_1 = __spreadArray(__spreadArray([], deletedChildElements, true), [selectedElement], false).map(function (e) { return e.id; });
9372
9535
  var prevElements = elementsRef.current;
9373
9536
  var newElements = prevElements.filter(function (e) { return !deletedElementIds_1.includes(e.id); });
@@ -9441,13 +9604,12 @@ var Paper = function (props) {
9441
9604
  }, [selectedText, props.onTextsChanged]);
9442
9605
  var handlePaperMouseMove = function (ev) {
9443
9606
  var _a;
9607
+ var _b = windowsPositionToPaperPosition({
9608
+ x: ev.clientX,
9609
+ y: ev.clientY
9610
+ }, paperContainerRef.current, zoom), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
9444
9611
  //if there is a temp link, update the temp target point
9445
9612
  if (tempLink) {
9446
- var currentTarget = ev.currentTarget;
9447
- //get offset x,y of the temp target point relative paper container
9448
- var rect = currentTarget.getBoundingClientRect();
9449
- var offsetX = ev.clientX - rect.left;
9450
- var offsetY = ev.clientY - rect.top;
9451
9613
  var sourceElementAbsPosition = getAbsolutePosition(tempLink.sourceElement);
9452
9614
  var sourcePosition = {
9453
9615
  x: sourceElementAbsPosition.x + tempLink.sourcePort.position.x,
@@ -9455,33 +9617,42 @@ var Paper = function (props) {
9455
9617
  };
9456
9618
  //reduce the position of offset to the direction of the source point 1 unit to avoid the link to reach the current mouse position
9457
9619
  var tempTargetPosition_1 = {
9458
- x: offsetX - (offsetX > sourcePosition.x ? 1 : -1),
9459
- y: offsetY - (offsetY > sourcePosition.y ? 1 : -1)
9620
+ x: xPosOnPaper - (xPosOnPaper > sourcePosition.x ? 1 : -1),
9621
+ y: yPosOnPaper - (yPosOnPaper > sourcePosition.y ? 1 : -1)
9460
9622
  };
9461
9623
  setTempLink(function (prev) { return (__assign(__assign({}, prev), { tempTargetPosition: tempTargetPosition_1 })); });
9462
9624
  }
9463
9625
  //broadcast mouse moved position to parent component
9464
9626
  (_a = props.onPaperMouseMoved) === null || _a === void 0 ? void 0 : _a.call(props, {
9465
- x: ev.clientX,
9466
- y: ev.clientY
9627
+ x: xPosOnPaper,
9628
+ y: yPosOnPaper
9467
9629
  });
9468
9630
  };
9469
9631
  var handleMouseDownOnPaper = function (ev) {
9470
9632
  var _a, _b;
9471
- setMouseDownedOnPaper(true);
9472
- (_a = props.onPaperClicked) === null || _a === void 0 ? void 0 : _a.call(props, {
9633
+ var _c = windowsPositionToPaperPosition({
9473
9634
  x: ev.clientX,
9474
9635
  y: ev.clientY
9636
+ }, paperContainerRef.current, zoom), xPosOnPaper = _c.x, yPosOnPaper = _c.y;
9637
+ setMouseDownedOnPaper(true);
9638
+ (_a = props.onPaperClicked) === null || _a === void 0 ? void 0 : _a.call(props, {
9639
+ x: xPosOnPaper,
9640
+ y: yPosOnPaper
9475
9641
  });
9476
9642
  paperEventEmitter.emitPaperClicked(ev);
9477
9643
  //broadcast mouse moved position to parent component
9478
9644
  (_b = props.onPaperMouseDown) === null || _b === void 0 ? void 0 : _b.call(props, {
9479
- x: ev.clientX,
9480
- y: ev.clientY
9645
+ x: xPosOnPaper,
9646
+ y: yPosOnPaper
9481
9647
  });
9482
9648
  };
9483
9649
  var handleMouseUpOnPaper = function (ev) {
9484
9650
  var _a;
9651
+ // Get the mouse position relative to the paper container
9652
+ var _b = windowsPositionToPaperPosition({
9653
+ x: ev.clientX,
9654
+ y: ev.clientY
9655
+ }, paperContainerRef.current, zoom), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
9485
9656
  if (mouseDownedOnPaper) {
9486
9657
  setSelectedElement(undefined);
9487
9658
  setSelectedElementSVG(null);
@@ -9498,8 +9669,8 @@ var Paper = function (props) {
9498
9669
  setMouseDownedOnPaper(false);
9499
9670
  //broadcast mouse moved position to parent component
9500
9671
  (_a = props.onPaperMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, {
9501
- x: ev.clientX,
9502
- y: ev.clientY
9672
+ x: xPosOnPaper,
9673
+ y: yPosOnPaper
9503
9674
  });
9504
9675
  };
9505
9676
  var handlePathChange = React.useCallback(function (path, id) {
@@ -9513,17 +9684,15 @@ var Paper = function (props) {
9513
9684
  props.onLinksChanged(newLinks);
9514
9685
  }
9515
9686
  }, [props.onLinksChanged, links]);
9516
- var handlePointsOfLinkChange = React.useCallback(function (points, id) {
9517
- //Update path of element link, that changed
9518
- // const prevLinks = linksRef.current;
9519
- var updatedLinkIndex = links.findIndex(function (l) { return l.id === id; });
9520
- links[updatedLinkIndex].points = points;
9521
- var newLinks = __spreadArray([], links, true);
9687
+ var handlePointsOfLinkChange = React.useCallback(function (points, linkId) {
9688
+ var newLinks = __spreadArray([], linksRef.current, true);
9689
+ var updatedLinkIndex = newLinks.findIndex(function (l) { return l.id === linkId; });
9690
+ newLinks[updatedLinkIndex].points = points;
9522
9691
  setLinks(newLinks);
9523
9692
  if (props.onLinksChanged) {
9524
9693
  props.onLinksChanged(newLinks);
9525
9694
  }
9526
- }, [props.onLinksChanged, links]);
9695
+ }, [props.onLinksChanged]);
9527
9696
  var handlePortMoved = React.useCallback(function (port, elementId, oldPosition, newPosition) {
9528
9697
  var _a;
9529
9698
  var element = elementsRef.current.find(function (e) { return e.id === elementId; });
@@ -9568,9 +9737,14 @@ var Paper = function (props) {
9568
9737
  var _a;
9569
9738
  ev.stopPropagation();
9570
9739
  var element = elementsRef.current.find(function (e) { return e.id === elementId; });
9740
+ var paperPosition = windowsPositionToPaperPosition({
9741
+ x: ev.clientX,
9742
+ y: ev.clientY
9743
+ }, paperContainerRef.current, zoomRef.current);
9744
+ console.log(paperPosition);
9571
9745
  //broadcast port mouse down to parent component
9572
9746
  if (element) {
9573
- (_a = props.onPortMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, port, element);
9747
+ (_a = props.onPortMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, port, element, paperPosition);
9574
9748
  }
9575
9749
  if (!tempLinkRef.current && element) {
9576
9750
  //handle create temp element link;
@@ -9603,9 +9777,13 @@ var Paper = function (props) {
9603
9777
  var _a;
9604
9778
  ev.stopPropagation();
9605
9779
  var element = elementsRef.current.find(function (e) { return e.id === elementId; });
9780
+ var paperPosition = windowsPositionToPaperPosition({
9781
+ x: ev.clientX,
9782
+ y: ev.clientY
9783
+ }, paperContainerRef.current, zoomRef.current);
9606
9784
  //broadcast port mouse down to parent component
9607
9785
  if (element) {
9608
- (_a = props.onPortMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, port, element);
9786
+ (_a = props.onPortMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, port, element, paperPosition);
9609
9787
  }
9610
9788
  //Create new element link, if has tempLink
9611
9789
  if (tempLinkRef.current) {
@@ -9860,29 +10038,45 @@ var Paper = function (props) {
9860
10038
  var handleMouseUp = React.useCallback(function (ev, elementId) {
9861
10039
  var _a;
9862
10040
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10041
+ var paperPosition = windowsPositionToPaperPosition({
10042
+ x: ev.clientX,
10043
+ y: ev.clientY
10044
+ }, paperContainerRef.current, zoomRef.current);
9863
10045
  if (element) {
9864
- (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10046
+ (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9865
10047
  }
9866
10048
  }, [props.onElementMouseUp]);
9867
10049
  var handleMouseDown = React.useCallback(function (ev, elementId) {
9868
10050
  var _a;
9869
10051
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10052
+ var paperPosition = windowsPositionToPaperPosition({
10053
+ x: ev.clientX,
10054
+ y: ev.clientY
10055
+ }, paperContainerRef.current, zoomRef.current);
9870
10056
  if (element) {
9871
- (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10057
+ (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9872
10058
  }
9873
10059
  }, [props.onElementMouseDown]);
9874
10060
  var handleMouseMove = React.useCallback(function (ev, elementId) {
9875
10061
  var _a;
9876
10062
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10063
+ var paperPosition = windowsPositionToPaperPosition({
10064
+ x: ev.clientX,
10065
+ y: ev.clientY
10066
+ }, paperContainerRef.current, zoomRef.current);
9877
10067
  if (element) {
9878
- (_a = props.onElementMouseMove) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10068
+ (_a = props.onElementMouseMove) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9879
10069
  }
9880
10070
  }, [props.onElementMouseMove]);
9881
10071
  var handleMouseLeave = React.useCallback(function (ev, elementId) {
9882
10072
  var _a;
9883
10073
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10074
+ var paperPosition = windowsPositionToPaperPosition({
10075
+ x: ev.clientX,
10076
+ y: ev.clientY
10077
+ }, paperContainerRef.current, zoomRef.current);
9884
10078
  if (element) {
9885
- (_a = props.onElementMouseLeave) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10079
+ (_a = props.onElementMouseLeave) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9886
10080
  }
9887
10081
  }, [props.onElementMouseLeave]);
9888
10082
  var renderElementInTree = React.useCallback(function (element) {
@@ -9897,22 +10091,32 @@ var Paper = function (props) {
9897
10091
  React.createElement(SelectionFrame, { container: paperContainerRef.current, targetSVGElement: selectedElementSVG || undefined, resizability: (selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.resizability) || {
9898
10092
  enabled: true,
9899
10093
  keepRatio: true
9900
- }, objectX: selectedElementAbsPosition === null || selectedElementAbsPosition === void 0 ? void 0 : selectedElementAbsPosition.x, objectY: selectedElementAbsPosition === null || selectedElementAbsPosition === void 0 ? void 0 : selectedElementAbsPosition.y, width: selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size.width, height: selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size.height,
10094
+ }, objectX: selectedElementAbsPosition === null || selectedElementAbsPosition === void 0 ? void 0 : selectedElementAbsPosition.x, objectY: selectedElementAbsPosition === null || selectedElementAbsPosition === void 0 ? void 0 : selectedElementAbsPosition.y, width: selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size.width, height: selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size.height, zoom: zoom,
9901
10095
  //movingOffsetThreshold: ELEMENT_MOVING_OFFSET_THRESHOLD,
9902
10096
  onMouseDown: function (ev) {
9903
10097
  var _a;
9904
10098
  if (selectedElement) {
9905
- (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement);
10099
+ var paperPosition = windowsPositionToPaperPosition({
10100
+ x: ev.clientX,
10101
+ y: ev.clientY
10102
+ }, paperContainerRef.current, zoomRef.current);
10103
+ (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement, paperPosition);
9906
10104
  }
9907
10105
  }, onMouseUp: function (ev) {
9908
10106
  var _a;
9909
10107
  if (selectedElement) {
9910
- (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement);
10108
+ var paperPosition = windowsPositionToPaperPosition({
10109
+ x: ev.clientX,
10110
+ y: ev.clientY
10111
+ }, paperContainerRef.current, zoomRef.current);
10112
+ (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement, paperPosition);
9911
10113
  }
9912
10114
  }, onMove: function (newX, newY) {
10115
+ var _a;
9913
10116
  if (!selectedElement)
9914
10117
  return;
9915
10118
  var oldPosition = __assign({}, selectedElement.position);
10119
+ // Relative position to the paper container
9916
10120
  var newPosition = {
9917
10121
  x: newX,
9918
10122
  y: newY
@@ -9929,10 +10133,29 @@ var Paper = function (props) {
9929
10133
  //let newElementPosition = updateElementPosition(selectedElement, newPosition.x, newPosition.y, true)
9930
10134
  var indexSelectedElement = elements.findIndex(function (e) { return e.id === selectedElement.id; });
9931
10135
  logger.info("Element ".concat(selectedElement.id, " is moving to relative position ").concat(JSON.stringify(selectedElement.position)));
10136
+ // Start updating the position of links connected to the selected element
10137
+ var childElements = getChildOfElement(selectedElement);
10138
+ var elementIds = __spreadArray(__spreadArray([], childElements.map(function (e) { return e.id; }), true), [selectedElement.id], false);
10139
+ var offsetX = newPosition.x - oldPosition.x;
10140
+ var offsetY = newPosition.y - oldPosition.y;
10141
+ // Update position of all points of links that are connected to the selected element
10142
+ var newLinks = linksRef.current.map(function (link) {
10143
+ var isUpdate = elementIds.includes(link.sourceElement.id) && elementIds.includes(link.targetElement.id);
10144
+ if (link.points && isUpdate) {
10145
+ link.points.forEach(function (p) {
10146
+ p.x += offsetX;
10147
+ p.y += offsetY;
10148
+ });
10149
+ }
10150
+ return link;
10151
+ });
10152
+ (_a = props.onLinksChanged) === null || _a === void 0 ? void 0 : _a.call(props, newLinks);
10153
+ // End updating the position of links connected to the selected element
9932
10154
  //Set state to re-render UI with new position
9933
10155
  setElementsInTree(function (prev) { return __spreadArray([], prev, true); });
9934
10156
  if (props.onElementMoved) {
9935
- props.onElementMoved(selectedElement.position, selectedElement, indexSelectedElement);
10157
+ console.log('onElementMoved', selectedElement.position, newPosition);
10158
+ props.onElementMoved(selectedElement.position, selectedElement, indexSelectedElement, newPosition);
9936
10159
  }
9937
10160
  paperEventEmitter.emitElementMoved(selectedElement, oldPosition, selectedElement.position);
9938
10161
  setMouseDownedOnPaper(false);
@@ -9954,12 +10177,12 @@ var Paper = function (props) {
9954
10177
  paperEventEmitter.emitElementResized(selectedElement, oldSize, newSize);
9955
10178
  setMouseDownedOnPaper(false);
9956
10179
  } }))));
9957
- }, [handlePortsChanged, handleElementClicked, handleContextMenu, handlePortMoved, handlePortMouseDown, handlePortMouseUp, handleMouseUpAtLinkedPortPlaceholder, handleElementTextChange, handleMouseUp, handleMouseMove, handleMouseLeave, selectedElement, selectedElementAbsPosition]);
10180
+ }, [handlePortsChanged, handleElementClicked, handleContextMenu, handlePortMoved, handlePortMouseDown, handlePortMouseUp, handleMouseUpAtLinkedPortPlaceholder, handleElementTextChange, handleMouseUp, handleMouseMove, handleMouseLeave, selectedElement, selectedElementAbsPosition, zoom]);
9958
10181
  var ElementsInTree = React.useMemo(function () {
9959
10182
  return elementsInTree.map(function (element, index) {
9960
10183
  return renderElementInTree(element);
9961
10184
  });
9962
- }, [elementsInTree, renderElementInTree, selectedElement]);
10185
+ }, [elementsInTree, renderElementInTree, selectedElement, zoom]);
9963
10186
  return (React.createElement("div", { style: { position: "relative" } },
9964
10187
  React.createElement(Ruler, { squareSize: 100, border: '1px dashed grey' }),
9965
10188
  React.createElement("svg", { tabIndex: 0, width: size.width, height: size.height, ref: paperContainerRef, id: "paper-container", onMouseMove: handlePaperMouseMove, onMouseDown: handleMouseDownOnPaper, onMouseUp: handleMouseUpOnPaper },
@@ -9987,83 +10210,6 @@ var Paper = function (props) {
9987
10210
  };
9988
10211
  var Paper$1 = React.memo(Paper);
9989
10212
 
9990
- /**
9991
- * Zoom context to manage zoom level and related state.
9992
- * This context can be used to provide zoom functionality across the application.
9993
- */
9994
- var zoomContext = React.createContext(null);
9995
- var ZoomContextProvider = function (_a) {
9996
- var children = _a.children;
9997
- var _b = React.useState(1), zoom = _b[0], setZoom = _b[1];
9998
- var _c = React.useState(0), scrollLeft = _c[0], setScrollLeft = _c[1];
9999
- var _d = React.useState(0), scrollTop = _d[0], setScrollTop = _d[1];
10000
- var wrapperRef = React.useRef(null);
10001
- var contentRef = React.useRef(null);
10002
- var handleWheel = function (e) {
10003
- // Chỉ zoom khi giữ Ctrl
10004
- if (!e.ctrlKey)
10005
- return;
10006
- e.preventDefault();
10007
- var delta = -e.deltaY;
10008
- var zoomFactor = 0.05;
10009
- var newZoom = zoom + (delta > 0 ? zoomFactor : -zoomFactor);
10010
- newZoom = Math.max(0.1, Math.min(newZoom, 4));
10011
- if (!wrapperRef.current || !contentRef.current)
10012
- return;
10013
- var wrapper = wrapperRef.current;
10014
- var content = contentRef.current;
10015
- // Get bounding rectangle of the content
10016
- var rect = content.getBoundingClientRect();
10017
- var offsetX = e.clientX - rect.left;
10018
- var offsetY = e.clientY - rect.top;
10019
- var percentX = offsetX / (content.offsetWidth);
10020
- var percentY = offsetY / (content.offsetHeight);
10021
- console.log(offsetX, offsetY, content.offsetWidth, content.offsetHeight, percentX, percentY);
10022
- // Old width and height of content
10023
- var prevWidth = content.offsetWidth * zoom;
10024
- var prevHeight = content.offsetHeight * zoom;
10025
- var newWidth = content.offsetWidth * newZoom;
10026
- var newHeight = content.offsetHeight * newZoom;
10027
- var scrollLeft = wrapper.scrollLeft + (percentX * (newWidth - prevWidth));
10028
- var scrollTop = wrapper.scrollTop + (percentY * (newHeight - prevHeight));
10029
- setZoom(newZoom);
10030
- setScrollLeft(scrollLeft);
10031
- setScrollTop(scrollTop);
10032
- };
10033
- React.useLayoutEffect(function () {
10034
- var _a;
10035
- (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({
10036
- left: scrollLeft,
10037
- top: scrollTop,
10038
- });
10039
- }, [zoom, scrollLeft, scrollTop]);
10040
- var resetZoom = function () {
10041
- setZoom(1);
10042
- };
10043
- React.useEffect(function () {
10044
- var preventBrowserZoom = function (e) {
10045
- if (e.ctrlKey || e.metaKey) {
10046
- e.preventDefault();
10047
- }
10048
- };
10049
- window.addEventListener("wheel", preventBrowserZoom, { passive: false });
10050
- return function () {
10051
- window.removeEventListener("wheel", preventBrowserZoom);
10052
- };
10053
- }, []);
10054
- return (React.createElement(zoomContext.Provider, { value: { zoom: zoom, setZoom: setZoom, resetZoom: resetZoom } },
10055
- React.createElement("div", { ref: wrapperRef, onWheel: handleWheel, style: {
10056
- width: "100vw",
10057
- height: "92vh",
10058
- overflow: "auto",
10059
- } },
10060
- React.createElement("div", { ref: contentRef, style: {
10061
- transform: "scale(".concat(zoom, ")"),
10062
- transformOrigin: "top left",
10063
- // transition: "transform 0.1s linear",
10064
- } }, children))));
10065
- };
10066
-
10067
10213
  var Editor = function (_a) {
10068
10214
  var editorContext = _a.editorContext, width = _a.width, height = _a.height;
10069
10215
  var _b = React.useState([]), elements = _b[0], setElements = _b[1];
@@ -10100,14 +10246,14 @@ var Editor = function (_a) {
10100
10246
  var handlePaperClicked = React.useCallback(function (position) {
10101
10247
  editorContext.onPaperClickedHandler(position);
10102
10248
  }, [editorContext]);
10103
- var handlePortMouseDown = React.useCallback(function (port, element) {
10104
- editorContext.onPortMouseDownHandler(port, element);
10249
+ var handlePortMouseDown = React.useCallback(function (port, element, paperPosition) {
10250
+ editorContext.onPortMouseDownHandler(port, element, paperPosition);
10105
10251
  }, [editorContext]);
10106
- var handlePortMouseUp = React.useCallback(function (port, element) {
10107
- editorContext.onPortMouseUpHandler(port, element);
10252
+ var handlePortMouseUp = React.useCallback(function (port, element, paperPosition) {
10253
+ editorContext.onPortMouseUpHandler(port, element, paperPosition);
10108
10254
  }, [editorContext]);
10109
- var handlePortMoved = React.useCallback(function (position, port, element) {
10110
- editorContext.onPortMovedHandler(position, port, element);
10255
+ var handlePortMoved = React.useCallback(function (relativePosition, port, element) {
10256
+ editorContext.onPortMovedHandler(relativePosition, port, element);
10111
10257
  }, [editorContext]);
10112
10258
  var handlePortSelected = React.useCallback(function (port, element) {
10113
10259
  editorContext.onPortSelectedHandler(port, element);
@@ -10118,8 +10264,9 @@ var Editor = function (_a) {
10118
10264
  var handleElementContextMenu = React.useCallback(function (element, event) {
10119
10265
  editorContext.onElementContextMenuHandler(element, event);
10120
10266
  }, [editorContext]);
10121
- var handleElementMoved = React.useCallback(function (position, element) {
10122
- editorContext.onElementMovedHandler(position, element);
10267
+ var handleElementMoved = React.useCallback(function (relativePosition, element) {
10268
+ console.count('SelectionFrame: handleElementMoved');
10269
+ editorContext.onElementMovedHandler(relativePosition, element);
10123
10270
  }, [editorContext]);
10124
10271
  var handleElementResized = React.useCallback(function (size, element) {
10125
10272
  editorContext.onElementResizedHandler(size, element);
@@ -10127,17 +10274,17 @@ var Editor = function (_a) {
10127
10274
  var handleElementSelected = React.useCallback(function (element) {
10128
10275
  editorContext.onElementSelectedHandler(element);
10129
10276
  }, [editorContext]);
10130
- var handleElementMouseLeave = React.useCallback(function (ev, element) {
10131
- editorContext.onElementMouseLeaveHandler(ev, element);
10277
+ var handleElementMouseLeave = React.useCallback(function (ev, element, paperPosition) {
10278
+ editorContext.onElementMouseLeaveHandler(ev, element, paperPosition);
10132
10279
  }, [editorContext]);
10133
- var handleElementMouseMove = React.useCallback(function (ev, element) {
10134
- editorContext.onElementMouseMoveHandler(ev, element);
10280
+ var handleElementMouseMove = React.useCallback(function (ev, element, paperPosition) {
10281
+ editorContext.onElementMouseMoveHandler(ev, element, paperPosition);
10135
10282
  }, [editorContext]);
10136
- var handleElementMouseDown = React.useCallback(function (ev, element) {
10137
- editorContext.onElementMouseDownHandler(ev, element);
10283
+ var handleElementMouseDown = React.useCallback(function (ev, element, paperPosition) {
10284
+ editorContext.onElementMouseDownHandler(ev, element, paperPosition);
10138
10285
  }, [editorContext]);
10139
- var handleElementMouseUp = React.useCallback(function (ev, element) {
10140
- editorContext.onElementMouseUpHandler(ev, element);
10286
+ var handleElementMouseUp = React.useCallback(function (ev, element, paperPosition) {
10287
+ editorContext.onElementMouseUpHandler(ev, element, paperPosition);
10141
10288
  }, [editorContext]);
10142
10289
  var handleElementsChanged = React.useCallback(function (elements) {
10143
10290
  editorContext.elements = elements;
@@ -10175,8 +10322,9 @@ var Editor = function (_a) {
10175
10322
  var handlePaperMouseUp = React.useCallback(function (position) {
10176
10323
  editorContext.onPaperMouseUpHandler(position);
10177
10324
  }, [editorContext]);
10178
- return (React.createElement(ZoomContextProvider, null,
10179
- React.createElement(Paper$1, { key: "paper", size: { width: width, height: height }, elements: elements, links: links, texts: texts, onPaperClicked: handlePaperClicked, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortMoved: handlePortMoved, onPortSelected: handlePortSelected, onPortsChanged: handlePortsChanged, onElementContextMenu: handleElementContextMenu, onElementMoved: handleElementMoved, onElementResized: handleElementResized, onElementSelected: handleElementSelected, onElementMouseLeave: handleElementMouseLeave, onElementMouseMove: handleElementMouseMove, onElementMouseDown: handleElementMouseDown, onElementMouseUp: handleElementMouseUp, onElementsChanged: handleElementsChanged, onCreatingLink: handleOnCreatingLink, onCreatingPortByLinking: handleOnCreatingPortByLinking, onLinkSelected: handleLinkSelected, onLinksChanged: handleLinksChanged, onTextSelected: handleTextSelected, onTextsChanged: handleTextsChanged, onPaperMouseMoved: handlePaperMouseMoved, onPaperMouseUp: handlePaperMouseUp, onPaperMouseDown: handlePaperMouseDown, onManuallyTriggerRenderElement: editorContext.onManuallyTriggerRenderElement.bind(editorContext), onManuallyTriggerRenderPort: editorContext.onManuallyTriggerRenderPort.bind(editorContext) })));
10325
+ return (React.createElement(EditorConfigurationContextProvider, { value: editorContext.configuration },
10326
+ React.createElement(ZoomContextProvider, null,
10327
+ React.createElement(Paper$1, { key: "paper", size: { width: width, height: height }, elements: elements, links: links, texts: texts, onPaperClicked: handlePaperClicked, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortMoved: handlePortMoved, onPortSelected: handlePortSelected, onPortsChanged: handlePortsChanged, onElementContextMenu: handleElementContextMenu, onElementMoved: handleElementMoved, onElementResized: handleElementResized, onElementSelected: handleElementSelected, onElementMouseLeave: handleElementMouseLeave, onElementMouseMove: handleElementMouseMove, onElementMouseDown: handleElementMouseDown, onElementMouseUp: handleElementMouseUp, onElementsChanged: handleElementsChanged, onCreatingLink: handleOnCreatingLink, onCreatingPortByLinking: handleOnCreatingPortByLinking, onLinkSelected: handleLinkSelected, onLinksChanged: handleLinksChanged, onTextSelected: handleTextSelected, onTextsChanged: handleTextsChanged, onPaperMouseMoved: handlePaperMouseMoved, onPaperMouseUp: handlePaperMouseUp, onPaperMouseDown: handlePaperMouseDown, onManuallyTriggerRenderElement: editorContext.onManuallyTriggerRenderElement.bind(editorContext), onManuallyTriggerRenderPort: editorContext.onManuallyTriggerRenderPort.bind(editorContext) }))));
10180
10328
  };
10181
10329
 
10182
10330
  exports.CircleRC = Circle;
@@ -10220,7 +10368,6 @@ exports.getPointsFromPathData = getPointsFromPathData;
10220
10368
  exports.getPointsFromPathElement = getPointsFromPathElement;
10221
10369
  exports.getPortAbsolutePosition = getPortAbsolutePosition;
10222
10370
  exports.getRectangleCorners = getRectangleCorners;
10223
- exports.getRelativePosition = getRelativePosition;
10224
10371
  exports.getRotatedRectangleCoordinates = getRotatedRectangleCoordinates;
10225
10372
  exports.getRotatedSVGBBox = getRotatedSVGBBox;
10226
10373
  exports.getSVGBBoxOutsideTransformedParent = getSVGBBoxOutsideTransformedParent;
@@ -10229,3 +10376,4 @@ exports.pathDataToD = pathDataToD;
10229
10376
  exports.removeDuplicatePosition = removeDuplicatePosition;
10230
10377
  exports.transformAbsPositionToElementRelativePosition = transformAbsPositionToElementRelativePosition;
10231
10378
  exports.transformAbsPositionToRelativePositionInsideElement = transformAbsPositionToRelativePositionInsideElement;
10379
+ exports.windowsPositionToPaperPosition = windowsPositionToPaperPosition;