orcasvn-react-diagrams 0.1.54 → 0.1.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -808,6 +808,7 @@ var EVENT_PORT_MOUSE_DOWN = 'portMouseDown';
808
808
  var EVENT_PORT_MOUSE_UP = 'portMouseUp';
809
809
  var EVENT_PORT_MOVED = 'portMoved';
810
810
  var EVENT_PORT_SELECTED = 'portSelected';
811
+ var EVENT_PORT_CONTEXT_MENU = 'portContextMenu';
811
812
  var EVENT_ELEMENT_CONTEXT_MENU = 'elementContextMenu';
812
813
  var EVENT_ELEMENT_MOVED = 'elementMoved';
813
814
  var EVENT_ELEMENT_RESIZED = 'elementResized';
@@ -957,15 +958,15 @@ var EditorContext = /** @class */ (function () {
957
958
  return this.addEventListener(EVENT_PORT_MOUSE_DOWN, callback);
958
959
  };
959
960
  /** @internal */
960
- EditorContext.prototype.onPortMouseDownHandler = function (port, element) {
961
- this._eventEmitter.emit(EVENT_PORT_MOUSE_DOWN, port, element);
961
+ EditorContext.prototype.onPortMouseDownHandler = function (port, element, paperPosition) {
962
+ this._eventEmitter.emit(EVENT_PORT_MOUSE_DOWN, port, element, paperPosition);
962
963
  };
963
964
  EditorContext.prototype.onPortMouseUp = function (callback) {
964
965
  return this.addEventListener(EVENT_PORT_MOUSE_UP, callback);
965
966
  };
966
967
  /** @internal */
967
- EditorContext.prototype.onPortMouseUpHandler = function (port, element) {
968
- this._eventEmitter.emit(EVENT_PORT_MOUSE_UP, port, element);
968
+ EditorContext.prototype.onPortMouseUpHandler = function (port, element, paperPosition) {
969
+ this._eventEmitter.emit(EVENT_PORT_MOUSE_UP, port, element, paperPosition);
969
970
  };
970
971
  EditorContext.prototype.onPortMoved = function (callback) {
971
972
  return this.addEventListener(EVENT_PORT_MOVED, callback);
@@ -981,6 +982,13 @@ var EditorContext = /** @class */ (function () {
981
982
  EditorContext.prototype.onPortSelectedHandler = function (port, element) {
982
983
  this._eventEmitter.emit(EVENT_PORT_SELECTED, port, element);
983
984
  };
985
+ EditorContext.prototype.onPortContextMenu = function (callback) {
986
+ return this.addEventListener(EVENT_PORT_CONTEXT_MENU, callback);
987
+ };
988
+ /** @internal */
989
+ EditorContext.prototype.onPortContextMenuHandler = function (port, element, mouseEvent) {
990
+ this._eventEmitter.emit(EVENT_PORT_CONTEXT_MENU, port, element, mouseEvent);
991
+ };
984
992
  EditorContext.prototype.onElementContextMenu = function (callback) {
985
993
  return this.addEventListener(EVENT_ELEMENT_CONTEXT_MENU, callback);
986
994
  };
@@ -992,8 +1000,8 @@ var EditorContext = /** @class */ (function () {
992
1000
  return this.addEventListener(EVENT_ELEMENT_MOVED, callback);
993
1001
  };
994
1002
  /** @internal */
995
- EditorContext.prototype.onElementMovedHandler = function (position, element) {
996
- this._eventEmitter.emit(EVENT_ELEMENT_MOVED, position, element);
1003
+ EditorContext.prototype.onElementMovedHandler = function (relativePosition, element) {
1004
+ this._eventEmitter.emit(EVENT_ELEMENT_MOVED, relativePosition, element);
997
1005
  };
998
1006
  EditorContext.prototype.onElementResized = function (callback) {
999
1007
  return this.addEventListener(EVENT_ELEMENT_RESIZED, callback);
@@ -1013,29 +1021,29 @@ var EditorContext = /** @class */ (function () {
1013
1021
  return this.addEventListener(EVENT_ELEMENT_MOUSE_MOVE, callback);
1014
1022
  };
1015
1023
  /** @internal */
1016
- EditorContext.prototype.onElementMouseMoveHandler = function (ev, element) {
1017
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_MOVE, ev, element);
1024
+ EditorContext.prototype.onElementMouseMoveHandler = function (ev, element, paperPosition) {
1025
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_MOVE, ev, element, paperPosition);
1018
1026
  };
1019
1027
  EditorContext.prototype.onElementMouseLeave = function (callback) {
1020
1028
  return this.addEventListener(EVENT_ELEMENT_MOUSE_LEAVE, callback);
1021
1029
  };
1022
1030
  /** @internal */
1023
- EditorContext.prototype.onElementMouseLeaveHandler = function (ev, element) {
1024
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_LEAVE, ev, element);
1031
+ EditorContext.prototype.onElementMouseLeaveHandler = function (ev, element, paperPosition) {
1032
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_LEAVE, ev, element, paperPosition);
1025
1033
  };
1026
1034
  EditorContext.prototype.onElementMouseUp = function (callback) {
1027
1035
  return this.addEventListener(EVENT_ELEMENT_MOUSE_UP, callback);
1028
1036
  };
1029
1037
  /** @internal */
1030
- EditorContext.prototype.onElementMouseUpHandler = function (ev, element) {
1031
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_UP, ev, element);
1038
+ EditorContext.prototype.onElementMouseUpHandler = function (ev, element, paperPosition) {
1039
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_UP, ev, element, paperPosition);
1032
1040
  };
1033
1041
  EditorContext.prototype.onElementMouseDown = function (callback) {
1034
1042
  return this.addEventListener(EVENT_ELEMENT_MOUSE_DOWN, callback);
1035
1043
  };
1036
1044
  /** @internal */
1037
- EditorContext.prototype.onElementMouseDownHandler = function (ev, element) {
1038
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_DOWN, ev, element);
1045
+ EditorContext.prototype.onElementMouseDownHandler = function (ev, element, paperPosition) {
1046
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_DOWN, ev, element, paperPosition);
1039
1047
  };
1040
1048
  EditorContext.prototype.onLinkSelected = function (callback) {
1041
1049
  return this.addEventListener(EVENT_LINK_SELECTED, callback);
@@ -1305,667 +1313,70 @@ var Logger = /** @class */ (function () {
1305
1313
  }());
1306
1314
  var logger = new Logger();
1307
1315
 
1308
- var SelectionFrame = function (props) {
1309
- var propTargetSVGElement = props.targetSVGElement, propWidth = props.width, propHeight = props.height, propFramePadding = props.framePadding, objectX = props.objectX, objectY = props.objectY,
1310
- // movingOffsetThreshold: propMovingOffsetThreshold,
1311
- 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;
1312
- var bbox = propTargetSVGElement === null || propTargetSVGElement === void 0 ? void 0 : propTargetSVGElement.getBBox();
1313
- var _a = React.useState(propWidth || (bbox === null || bbox === void 0 ? void 0 : bbox.width) || MIN_ELEMENT_SIZE), width = _a[0], setWidth = _a[1];
1314
- var _b = React.useState(propHeight || (bbox === null || bbox === void 0 ? void 0 : bbox.height) || MIN_ELEMENT_SIZE), height = _b[0], setHeight = _b[1];
1315
- React.useEffect(function () {
1316
- if (propWidth) {
1317
- setWidth(propWidth);
1318
- }
1319
- }, [objectX, propWidth]);
1320
- var _c = React.useState(objectX !== null && objectX !== void 0 ? objectX : 0), curX = _c[0], setCurX = _c[1];
1321
- var _d = React.useState(objectY !== null && objectY !== void 0 ? objectY : 0), curY = _d[0], setCurY = _d[1];
1322
- React.useEffect(function () {
1323
- if (objectX) {
1324
- setCurX(objectX);
1325
- }
1326
- }, [objectX]);
1327
- React.useEffect(function () {
1328
- if (objectY) {
1329
- setCurY(objectY);
1330
- }
1331
- }, [objectY]);
1332
- var framePadding = propFramePadding || 0;
1333
- var r = 5;
1334
- var _e = React.useState(false), draggingRect = _e[0], setDraggingRect = _e[1];
1335
- var _f = React.useState(false), draggingCircle = _f[0], setDraggingCircle = _f[1];
1336
- var _g = React.useState(0), startX = _g[0], setStartX = _g[1];
1337
- var _h = React.useState(0), startY = _h[0], setStartY = _h[1];
1338
- var _j = React.useState(0), xFromMouse = _j[0], setXFromMouse = _j[1];
1339
- var _k = React.useState(0), yFromMouse = _k[0], setYFromMouse = _k[1];
1340
- var _l = React.useState(0), lastMoveTime = _l[0], setLastMoveTime = _l[1];
1341
- //set x by props.x
1342
- var getMousePosition = function (event) {
1343
- var elementBounding = propContainer.getBoundingClientRect();
1344
- //Coordinates of mouse on paper.
1345
- var mousePosition = {
1346
- x: event.clientX - elementBounding.left,
1347
- y: event.clientY - elementBounding.top
1348
- };
1349
- return mousePosition;
1350
- };
1351
- var addRectHandleMouseDown = function (event) {
1352
- event.stopPropagation();
1353
- if (!draggingCircle) {
1354
- setDraggingRect(true);
1355
- setStartX(event.clientX);
1356
- setStartY(event.clientY);
1357
- var mousePosition = getMousePosition(event);
1358
- var xFromMouse_1 = (curX || 0) - mousePosition.x;
1359
- var yFromMouse_1 = (curY || 0) - mousePosition.y;
1360
- setXFromMouse(xFromMouse_1);
1361
- setYFromMouse(yFromMouse_1);
1362
- }
1363
- if (propOnMouseDown) {
1364
- propOnMouseDown(event);
1365
- }
1366
- };
1367
- var rectHandleMouseMove = React.useCallback(function (event) {
1368
- var mouseEvent = event;
1369
- if (draggingRect) {
1370
- //Coordinates of mouse on paper.
1371
- var mousePosition = getMousePosition(mouseEvent);
1372
- var newX = mousePosition.x + xFromMouse;
1373
- var newY = mousePosition.y + yFromMouse;
1374
- if (propOnMove) {
1375
- setCurX(newX);
1376
- setCurY(newY);
1377
- propOnMove(newX, newY);
1378
- setLastMoveTime(Date.now());
1379
- setStartX(mouseEvent.clientX);
1380
- setStartY(mouseEvent.clientY);
1381
- }
1382
- }
1383
- }, [draggingRect, propOnMove, propMovingRate, startX, startY, lastMoveTime, xFromMouse, yFromMouse]);
1384
- React.useEffect(function () {
1385
- var addRectHandleMouseUp = function () {
1386
- setDraggingRect(false);
1387
- setXFromMouse(0);
1388
- setYFromMouse(0);
1389
- };
1390
- propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mousemove', rectHandleMouseMove);
1391
- propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mouseup', addRectHandleMouseUp);
1392
- return function () {
1393
- propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mousemove', rectHandleMouseMove);
1394
- propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mouseup', addRectHandleMouseUp);
1395
- };
1396
- }, [propContainer, rectHandleMouseMove]);
1397
- var circleHandleMouseDown = function (event) {
1398
- event.stopPropagation();
1399
- if (!draggingRect) {
1400
- setStartX(event.clientX);
1401
- setStartY(event.clientY);
1402
- setDraggingCircle(true);
1403
- }
1404
- };
1405
- React.useEffect(function () {
1406
- logger.debug('SelectionFrame: circleHandleMouseDown triggered', {
1407
- draggingCircle: draggingCircle,
1408
- startX: startX,
1409
- startY: startY,
1410
- width: width,
1411
- height: height,
1412
- propMovingRate: propMovingRate
1413
- });
1414
- var circleHandleMouseMove = function (event) {
1415
- var mouseEvent = event;
1416
- if (draggingCircle) {
1417
- var offsetX = mouseEvent.clientX - startX;
1418
- var offsetY = mouseEvent.clientY - startY;
1419
- if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
1420
- return;
1421
- }
1422
- setStartX(mouseEvent.clientX);
1423
- setStartY(mouseEvent.clientY);
1424
- setLastMoveTime(Date.now());
1425
- var newWidth = width;
1426
- var newHeight = height;
1427
- if (propResizability.keepRatio) {
1428
- var resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
1429
- var increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
1430
- offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
1431
- offsetY = increasing ? resizingRatio * height : -resizingRatio * height;
1432
- }
1433
- newWidth += offsetX;
1434
- newHeight += offsetY;
1435
- if (newWidth < MIN_ELEMENT_SIZE) {
1436
- newWidth = MIN_ELEMENT_SIZE;
1437
- }
1438
- if (newHeight < MIN_ELEMENT_SIZE) {
1439
- newHeight = MIN_ELEMENT_SIZE;
1440
- }
1441
- setWidth(newWidth);
1442
- setHeight(newHeight);
1443
- if (propOnResize) {
1444
- propOnResize(newWidth, newHeight);
1445
- }
1446
- }
1447
- };
1448
- var circleHandleMouseUp = function () {
1449
- setDraggingCircle(false);
1450
- };
1451
- var container = propContainer;
1452
- container.addEventListener('mousemove', circleHandleMouseMove);
1453
- container.addEventListener('mouseup', circleHandleMouseUp);
1454
- //logging the start of the circle handle mouse move
1455
- logger.debug('SelectionFrame: circleHandleMouseMove started', container);
1456
- return function () {
1457
- container.removeEventListener('mousemove', circleHandleMouseMove);
1458
- container.removeEventListener('mouseup', circleHandleMouseUp);
1459
- //logging the end of the circle handle mouse move
1460
- logger.debug('SelectionFrame: circleHandleMouseMove ended', container);
1461
- };
1462
- }, [draggingCircle, width, height, curX, curY, lastMoveTime, propContainer, propMovingRate, propOnResize, propResizability, startX, startY]);
1463
- var rectangleSize = Math.max(width, height);
1464
- var leftX = framePadding;
1465
- var topY = framePadding;
1466
- if (propAnchor === exports.PositioningAnchor.Center) {
1467
- leftX -= rectangleSize / 2;
1468
- topY -= rectangleSize / 2;
1316
+ /**
1317
+ * Created by Alex Bol on 2/18/2017.
1318
+ */
1319
+
1320
+ /**
1321
+ * Global constant DP_TOL is used for comparison of floating point numbers.
1322
+ * It is set to 0.000001.
1323
+ * @type {number}
1324
+ */
1325
+ const DP_TOL = 0.000001;
1326
+
1327
+ var utils = {
1328
+ DP_TOL: DP_TOL,
1329
+ /**
1330
+ * Returns *true* if value comparable to zero
1331
+ * @return {boolean}
1332
+ */
1333
+ EQ_0: function(x) {
1334
+ return ( (x) < DP_TOL && (x) > -DP_TOL );
1335
+ },
1336
+ /**
1337
+ * Returns *true* if two values are equal up to DP_TOL
1338
+ * @return {boolean}
1339
+ */
1340
+ EQ: function(x,y) {
1341
+ return ( (x)-(y) < DP_TOL && (x)-(y) > -DP_TOL );
1342
+ },
1343
+ /**
1344
+ * Returns *true* if first argument greater than second argument up to DP_TOL
1345
+ * @return {boolean}
1346
+ */
1347
+ GT: (x,y) => {
1348
+ return ( (x)-(y) > DP_TOL );
1349
+ },
1350
+ /**
1351
+ * Returns *true* if first argument greater than or equal to second argument up to DP_TOL
1352
+ * @return {boolean}
1353
+ */
1354
+ GE: (x,y) => {
1355
+ return ( (x)-(y) > -DP_TOL );
1356
+ },
1357
+ /**
1358
+ * Returns *true* if first argument less than second argument up to DP_TOL
1359
+ * @return {boolean}
1360
+ */
1361
+ LT: (x,y) => {
1362
+ return ( (x)-(y) < -DP_TOL )
1363
+ },
1364
+ /**
1365
+ * Returns *true* if first argument less than or equal to second argument up to DP_TOL
1366
+ * @return {boolean}
1367
+ */
1368
+ LE: (x,y) => {
1369
+ return ( (x)-(y) < DP_TOL );
1469
1370
  }
1470
- return (React.createElement(React.Fragment, null,
1471
- PropDragDropHandlerElement && React.createElement(PropDragDropHandlerElement, { dragging: draggingRect, onMouseDown: addRectHandleMouseDown }),
1472
- 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 }),
1473
- propResizability.enabled ?
1474
- (React.createElement("circle", { cursor: 'se-resize', cx: leftX + width, cy: topY + height, r: r, fill: 'blue', stroke: 'blue', onMouseDown: circleHandleMouseDown })) : null));
1475
1371
  };
1476
1372
 
1477
- var useSelectionFrame = function (props) {
1478
- React.useEffect(function () {
1479
- //log selection frame rendering
1480
- if (props.targetSVGElement) {
1481
- console.debug('Rendering SelectionFrame for targetSVGElement:', props.targetSVGElement);
1482
- }
1483
- else {
1484
- console.warn('No targetSVGElement provided for SelectionFrame.');
1485
- }
1486
- if (props.targetSVGElement && props.container) {
1487
- //render SelectionFrame component to the parent element of the targetSVGElement
1488
- if (props.container) {
1489
- var svg_1 = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
1490
- svg_1.style.overflow = 'visible';
1491
- svg_1.style.outline = 'none';
1492
- props.targetSVGElement.appendChild(svg_1);
1493
- var root_1 = createRoot(svg_1);
1494
- root_1.render(React.createElement(SelectionFrame, __assign({}, props, { container: props.container })));
1495
- return function () {
1496
- root_1.unmount();
1497
- if (props.targetSVGElement) {
1498
- props.targetSVGElement.removeChild(svg_1);
1499
- }
1500
- };
1501
- }
1502
- }
1503
- }, [props]);
1504
- };
1505
-
1506
- var eventEmitter = new EventEmitter();
1507
- var emitPaperClicked = function (ev) {
1508
- eventEmitter.emit(EVENT_NAME.PAPER_CLICK, ev);
1509
- };
1510
- var onPaperClicked = function (callback) {
1511
- eventEmitter.on(EVENT_NAME.PAPER_CLICK, callback);
1512
- var off = function () {
1513
- eventEmitter.off(EVENT_NAME.PAPER_CLICK, callback);
1514
- };
1515
- return {
1516
- off: off
1517
- };
1518
- };
1519
- var emitPortMouseUp = function (ev, port, elementId) {
1520
- eventEmitter.emit(EVENT_NAME.PORT_MOUSE_UP, ev, port, elementId);
1521
- };
1522
- var onPortMouseUp = function (callback) {
1523
- eventEmitter.on(EVENT_NAME.PORT_MOUSE_UP, callback);
1524
- var off = function () {
1525
- eventEmitter.off(EVENT_NAME.PORT_MOUSE_UP, callback);
1526
- };
1527
- return {
1528
- off: off
1529
- };
1530
- };
1531
- var emitPortMouseDown = function (ev, port, elementId) {
1532
- eventEmitter.emit(EVENT_NAME.PORT_MOUSE_DOWN, ev, port, elementId);
1533
- };
1534
- var onPortMouseDown = function (callback) {
1535
- eventEmitter.on(EVENT_NAME.PORT_MOUSE_DOWN, callback);
1536
- var off = function () {
1537
- eventEmitter.off(EVENT_NAME.PORT_MOUSE_DOWN, callback);
1538
- };
1539
- return {
1540
- off: off
1541
- };
1542
- };
1543
- var emitPortMoved = function (port, elementId, oldPosition, newPosition) {
1544
- eventEmitter.emit(EVENT_NAME.PORT_MOVED, port, elementId, oldPosition, newPosition);
1545
- };
1546
- var onPortMoved = function (callback) {
1547
- eventEmitter.on(EVENT_NAME.PORT_MOVED, callback);
1548
- var off = function () {
1549
- eventEmitter.off(EVENT_NAME.PORT_MOVED, callback);
1550
- };
1551
- return {
1552
- off: off
1553
- };
1554
- };
1555
- var emitElementMoved = function (element, oldPosition, newPosition) {
1556
- eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(element.id));
1557
- };
1558
- var onElementMoved = function (elementId, callback) {
1559
- eventEmitter.on("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
1560
- var off = function () {
1561
- eventEmitter.off("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
1562
- };
1563
- return {
1564
- off: off
1565
- };
1566
- };
1567
- var emitElementResized = function (element, oldSize, newSize) {
1568
- eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(element.id), oldSize, newSize);
1569
- };
1570
- var onElementResized = function (elementId, callback) {
1571
- eventEmitter.on("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
1572
- var off = function () {
1573
- eventEmitter.off("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
1574
- };
1575
- return {
1576
- off: off
1577
- };
1578
- };
1579
- var emitCommandDeleteSelectedPort = function () {
1580
- eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT);
1581
- };
1582
- var onCommandDeleteSelectedPort = function (callback) {
1583
- eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
1584
- var off = function () {
1585
- eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
1586
- };
1587
- return {
1588
- off: off
1589
- };
1590
- };
1591
- var emitCommandDeleteSelectedElement = function () {
1592
- eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT);
1593
- };
1594
- var onCommandDeleteSelectedElement = function (callback) {
1595
- eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
1596
- var off = function () {
1597
- eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
1598
- };
1599
- return {
1600
- off: off
1601
- };
1602
- };
1603
- var emitCommandDeleteSelectedLink = function () {
1604
- eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK);
1605
- };
1606
- var onCommandDeleteSelectedLink = function (callback) {
1607
- eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
1608
- var off = function () {
1609
- eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
1610
- };
1611
- return {
1612
- off: off
1613
- };
1614
- };
1615
- var emitCommandDeleteSelectedText = function () {
1616
- eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT);
1617
- };
1618
- var onCommandDeleteSelectedText = function (callback) {
1619
- eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
1620
- var off = function () {
1621
- eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
1622
- };
1623
- return {
1624
- off: off
1625
- };
1626
- };
1627
- var emitElementLinkStarted = function (elementLink) {
1628
- eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_STARTED, elementLink);
1629
- };
1630
- var onElementLinkStarted = function (callback) {
1631
- eventEmitter.on(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
1632
- var off = function () {
1633
- eventEmitter.off(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
1634
- };
1635
- return {
1636
- off: off
1637
- };
1638
- };
1639
- var emitElementLinkEnded = function (elementLink) {
1640
- eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_ENDED, elementLink);
1641
- };
1642
- var onElementLinkEnded = function (callback) {
1643
- eventEmitter.on(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
1644
- var off = function () {
1645
- eventEmitter.off(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
1646
- };
1647
- return {
1648
- off: off
1649
- };
1650
- };
1651
- var emitElementSelected = function (element) {
1652
- eventEmitter.emit(EVENT_NAME.ELEMENT_SELECTED, element);
1653
- };
1654
- var onElementSelected = function (callback) {
1655
- eventEmitter.on(EVENT_NAME.ELEMENT_SELECTED, callback);
1656
- var off = function () {
1657
- eventEmitter.off(EVENT_NAME.ELEMENT_SELECTED, callback);
1658
- };
1659
- return {
1660
- off: off
1661
- };
1662
- };
1663
- var emitCommandRenderElement = function (elementId) {
1664
- eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_ELEMENT, elementId);
1665
- };
1666
- var onCommandRenderElement = function (callback) {
1667
- eventEmitter.on(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
1668
- var off = function () {
1669
- eventEmitter.off(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
1670
- };
1671
- return {
1672
- off: off
1673
- };
1674
- };
1675
- var emitPortSelected = function (port, elementId) {
1676
- eventEmitter.emit(EVENT_NAME.PORT_SELECTED, port, elementId);
1677
- };
1678
- var onPortSelected = function (callback) {
1679
- eventEmitter.on(EVENT_NAME.PORT_SELECTED, callback);
1680
- var off = function () {
1681
- eventEmitter.off(EVENT_NAME.PORT_SELECTED, callback);
1682
- };
1683
- return {
1684
- off: off
1685
- };
1686
- };
1687
- var emitCommandRenderPort = function (portId, elementId) {
1688
- eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_PORT, portId, elementId);
1689
- };
1690
- var onCommandRenderPort = function (callback) {
1691
- eventEmitter.on(EVENT_NAME.COMMAND_RENDER_PORT, callback);
1692
- var off = function () {
1693
- eventEmitter.off(EVENT_NAME.COMMAND_RENDER_PORT, callback);
1694
- };
1695
- return {
1696
- off: off
1697
- };
1698
- };
1699
- var emitTextSelected = function (text) {
1700
- eventEmitter.emit(EVENT_NAME.TEXT_SELECTED, text);
1701
- };
1702
- var onTextSelected = function (callback) {
1703
- eventEmitter.on(EVENT_NAME.TEXT_SELECTED, callback);
1704
- var off = function () {
1705
- eventEmitter.off(EVENT_NAME.TEXT_SELECTED, callback);
1706
- };
1707
- return {
1708
- off: off
1709
- };
1710
- };
1711
- var paperEventEmitterContext = React.createContext({
1712
- emitter: eventEmitter,
1713
- emitPaperClicked: emitPaperClicked,
1714
- onPaperClicked: onPaperClicked,
1715
- emitPortMouseUp: emitPortMouseUp,
1716
- onPortMouseUp: onPortMouseUp,
1717
- emitPortMouseDown: emitPortMouseDown,
1718
- onPortMouseDown: onPortMouseDown,
1719
- emitPortMoved: emitPortMoved,
1720
- onPortMoved: onPortMoved,
1721
- emitPortSelected: emitPortSelected,
1722
- onPortSelected: onPortSelected,
1723
- emitElementMoved: emitElementMoved,
1724
- onElementMoved: onElementMoved,
1725
- emitElementResized: emitElementResized,
1726
- onElementResized: onElementResized,
1727
- emitElementSelected: emitElementSelected,
1728
- onElementSelected: onElementSelected,
1729
- emitCommandRenderElement: emitCommandRenderElement,
1730
- onCommandRenderElement: onCommandRenderElement,
1731
- emitCommandDeleteSelectedPort: emitCommandDeleteSelectedPort,
1732
- onCommandDeleteSelectedPort: onCommandDeleteSelectedPort,
1733
- emitCommandDeleteSelectedElement: emitCommandDeleteSelectedElement,
1734
- onCommandDeleteSelectedElement: onCommandDeleteSelectedElement,
1735
- emitCommandDeleteSelectedLink: emitCommandDeleteSelectedLink,
1736
- onCommandDeleteSelectedLink: onCommandDeleteSelectedLink,
1737
- emitCommandDeleteSelectedText: emitCommandDeleteSelectedText,
1738
- onCommandDeleteSelectedText: onCommandDeleteSelectedText,
1739
- emitElementLinkStarted: emitElementLinkStarted,
1740
- onElementLinkStarted: onElementLinkStarted,
1741
- emitElementLinkEnded: emitElementLinkEnded,
1742
- onElementLinkEnded: onElementLinkEnded,
1743
- emitTextSelected: emitTextSelected,
1744
- onTextSelected: onTextSelected,
1745
- emitCommandRenderPort: emitCommandRenderPort,
1746
- onCommandRenderPort: onCommandRenderPort,
1747
- });
1748
-
1749
- var editorConfigurationContext = React.createContext(null);
1750
- var useEditorConfiguration = function () {
1751
- var context = React.useContext(editorConfigurationContext);
1752
- if (!context) {
1753
- throw new Error("useEditorConfiguration must be used within an EditorConfigurationProvider");
1754
- }
1755
- return context;
1756
- };
1757
- var EditorConfigurationContextProvider = editorConfigurationContext.Provider;
1758
-
1759
- var Text = React.forwardRef(function (_a, ref) {
1760
- 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;
1761
- var _d = React.useState(false), isSelected = _d[0], setIsSelected = _d[1];
1762
- var _e = React.useState(false), isEditing = _e[0], setIsEditing = _e[1];
1763
- var textFontSize = useEditorConfiguration().textFontSize;
1764
- var absolutePosition = React.useMemo(function () {
1765
- var _a, _b;
1766
- return {
1767
- x: ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0) + x,
1768
- y: ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0) + y,
1769
- };
1770
- }, [x, y, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y]);
1771
- var svgRef = React.useRef();
1772
- var _f = React.useContext(paperEventEmitterContext), onPaperClicked = _f.onPaperClicked, emitTextSelected = _f.emitTextSelected, onPortSelected = _f.onPortSelected, onElementSelected = _f.onElementSelected, onTextSelected = _f.onTextSelected;
1773
- React.useEffect(function () {
1774
- var paperClickListener = onPaperClicked(function (ev) {
1775
- var _a;
1776
- var textareaELe = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('textarea');
1777
- if (ev.target !== textareaELe) {
1778
- setIsSelected(false);
1779
- setIsEditing(false);
1780
- }
1781
- });
1782
- var portSelectedListener = onPortSelected(function (port) {
1783
- setIsSelected(false);
1784
- setIsEditing(false);
1785
- });
1786
- var elementSelectedListener = onElementSelected(function (element) {
1787
- setIsSelected(false);
1788
- setIsEditing(false);
1789
- });
1790
- var textSelectedListener = onTextSelected(function (text) {
1791
- if (text.id !== id) {
1792
- setIsSelected(false);
1793
- setIsEditing(false);
1794
- }
1795
- });
1796
- return function () {
1797
- paperClickListener.off();
1798
- portSelectedListener.off();
1799
- elementSelectedListener.off();
1800
- textSelectedListener.off();
1801
- };
1802
- }, []);
1803
- //Handle click on svg element
1804
- var handleClick = function (ev) {
1805
- if (!selectable)
1806
- return;
1807
- ev.stopPropagation();
1808
- var position = {
1809
- x: x,
1810
- y: y,
1811
- };
1812
- var text = {
1813
- id: id,
1814
- content: content,
1815
- position: position,
1816
- size: {
1817
- width: width,
1818
- height: height,
1819
- },
1820
- editable: editable
1821
- };
1822
- setIsSelected(true);
1823
- onSelected && onSelected(text);
1824
- emitTextSelected(text);
1825
- };
1826
- var handleChangeText = function (ev) {
1827
- if (!editable)
1828
- return;
1829
- onContentChanged === null || onContentChanged === void 0 ? void 0 : onContentChanged(ev, ev.target.value);
1830
- };
1831
- useSelectionFrame({
1832
- objectX: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.x,
1833
- objectY: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.y,
1834
- container: container,
1835
- targetSVGElement: (isSelected && svgRef.current) ? svgRef.current : undefined,
1836
- resizability: {
1837
- enabled: onResized ? true : false,
1838
- keepRatio: false,
1839
- },
1840
- onMove: onMoved,
1841
- onResize: onResized,
1842
- strokeWidth: 3,
1843
- });
1844
- var textAlign = React.useMemo(function () {
1845
- switch (align) {
1846
- case exports.TextAlign.left:
1847
- return 'left';
1848
- case exports.TextAlign.right:
1849
- return 'right';
1850
- case exports.TextAlign.center:
1851
- return 'center';
1852
- default:
1853
- return 'left';
1854
- }
1855
- }, [align]);
1856
- var fontSize = fontSizeProp || textFontSize || TEXT_FONT_SIZE;
1857
- var borderStyle = border || 'none';
1858
- return (React.createElement("svg", { style: {
1859
- overflow: "visible",
1860
- pointerEvents: selectable ? undefined : 'none',
1861
- }, x: x, y: y, ref: function (node) {
1862
- svgRef.current = node;
1863
- if (typeof ref === 'function') {
1864
- ref(node);
1865
- }
1866
- else if (ref) {
1867
- ref.current = node;
1868
- }
1869
- }, onClick: handleClick },
1870
- React.createElement("foreignObject", { width: width, height: height, style: {
1871
- overflow: 'visible',
1872
- userSelect: 'none',
1873
- WebkitUserSelect: 'none',
1874
- msUserSelect: 'none'
1875
- } },
1876
- React.createElement("div", { style: {
1877
- width: '100%',
1878
- height: '100%',
1879
- borderWidth: '1px',
1880
- borderColor: '#ccc',
1881
- borderStyle: borderStyle,
1882
- // whiteSpace: 'pre-wrap',
1883
- boxSizing: 'border-box',
1884
- } },
1885
- React.createElement("textarea", { style: {
1886
- fontFamily: 'initial',
1887
- display: 'inline-block',
1888
- width: '100%',
1889
- height: '100%',
1890
- overflow: 'hidden',
1891
- border: 'none',
1892
- background: 'transparent',
1893
- outline: 'none',
1894
- resize: 'none',
1895
- textAlign: textAlign,
1896
- fontSize: fontSize,
1897
- }, readOnly: !isEditing, onDoubleClick: function () {
1898
- if (editable) {
1899
- setIsEditing(true);
1900
- }
1901
- }, value: content, onChange: handleChangeText })))));
1902
- });
1903
- var Text$1 = React.memo(Text);
1904
-
1905
- /**
1906
- * Created by Alex Bol on 2/18/2017.
1907
- */
1908
-
1909
- /**
1910
- * Global constant DP_TOL is used for comparison of floating point numbers.
1911
- * It is set to 0.000001.
1912
- * @type {number}
1913
- */
1914
- const DP_TOL = 0.000001;
1915
-
1916
- var utils = {
1917
- DP_TOL: DP_TOL,
1918
- /**
1919
- * Returns *true* if value comparable to zero
1920
- * @return {boolean}
1921
- */
1922
- EQ_0: function(x) {
1923
- return ( (x) < DP_TOL && (x) > -DP_TOL );
1924
- },
1925
- /**
1926
- * Returns *true* if two values are equal up to DP_TOL
1927
- * @return {boolean}
1928
- */
1929
- EQ: function(x,y) {
1930
- return ( (x)-(y) < DP_TOL && (x)-(y) > -DP_TOL );
1931
- },
1932
- /**
1933
- * Returns *true* if first argument greater than second argument up to DP_TOL
1934
- * @return {boolean}
1935
- */
1936
- GT: (x,y) => {
1937
- return ( (x)-(y) > DP_TOL );
1938
- },
1939
- /**
1940
- * Returns *true* if first argument greater than or equal to second argument up to DP_TOL
1941
- * @return {boolean}
1942
- */
1943
- GE: (x,y) => {
1944
- return ( (x)-(y) > -DP_TOL );
1945
- },
1946
- /**
1947
- * Returns *true* if first argument less than second argument up to DP_TOL
1948
- * @return {boolean}
1949
- */
1950
- LT: (x,y) => {
1951
- return ( (x)-(y) < -DP_TOL )
1952
- },
1953
- /**
1954
- * Returns *true* if first argument less than or equal to second argument up to DP_TOL
1955
- * @return {boolean}
1956
- */
1957
- LE: (x,y) => {
1958
- return ( (x)-(y) < DP_TOL );
1959
- }
1960
- };
1961
-
1962
- /**
1963
- * Created by Alex Bol on 2/19/2017.
1964
- */
1965
-
1966
- var errors = {
1967
- ILLEGAL_PARAMETERS: new ReferenceError('Illegal Parameters'),
1968
- ZERO_DIVISION: new Error('Zero division')
1373
+ /**
1374
+ * Created by Alex Bol on 2/19/2017.
1375
+ */
1376
+
1377
+ var errors = {
1378
+ ILLEGAL_PARAMETERS: new ReferenceError('Illegal Parameters'),
1379
+ ZERO_DIVISION: new Error('Zero division')
1969
1380
  };
1970
1381
 
1971
1382
  var matrix = function(Flatten) {
@@ -7442,43 +6853,6 @@ var checkPositionOnLine = function (position, line) {
7442
6853
  return _line.contains(point);
7443
6854
  };
7444
6855
 
7445
- // Calculate the position of the 4 vertices of a rectangle relative to its parent svg
7446
- var getRectangleCorners = function (rectSVG) {
7447
- var ownerSVG = rectSVG.ownerSVGElement;
7448
- var rectStrokeWidth = Number(rectSVG.getAttribute('stroke-width')) || 0;
7449
- var strokeWidthOffset = rectStrokeWidth / 2;
7450
- if (!ownerSVG) {
7451
- throw new Error('Rectangle does not wrapper by svg.');
7452
- }
7453
- var ownerX = ownerSVG.x.baseVal.value;
7454
- var ownerY = ownerSVG.y.baseVal.value;
7455
- var ownerWidth = ownerSVG.width.baseVal.value;
7456
- var ownerHeight = ownerSVG.height.baseVal.value;
7457
- var a = { x: ownerX + strokeWidthOffset, y: ownerY + strokeWidthOffset };
7458
- var b = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + strokeWidthOffset };
7459
- var c = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7460
- var d = { x: ownerX + strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7461
- return [a, b, c, d];
7462
- };
7463
- //find rotation angle of svg element on g element
7464
- var getElementRotationInfo = function (element) {
7465
- var gElement = element;
7466
- var rotationAngle = 0;
7467
- while (!(gElement instanceof SVGGElement)) {
7468
- gElement = gElement.parentElement;
7469
- }
7470
- var transform = gElement.getAttribute('transform');
7471
- if (transform) {
7472
- // Match the rotation value using a regular expression
7473
- var rotateMatch = transform.match(/rotate\(([-\d.]+)(?:\s+[-\d.]+\s+[-\d.]+)?\)/);
7474
- if (rotateMatch) {
7475
- // The first capture group is the rotation angle
7476
- rotationAngle = parseFloat(rotateMatch[1]);
7477
- }
7478
- }
7479
- return rotationAngle;
7480
- };
7481
-
7482
6856
  // const topLeftOffsetOfSquareHoldingRect = (x: number, y: number, rectWidth: number, rectHeight: number, rotation?: number): IPosition => {
7483
6857
  // rotation = rotation || 0;
7484
6858
  // const rotationInRadians = rotation * Math.PI / 180;
@@ -7532,8 +6906,213 @@ function calculateAngleWithOx(pStart, pEnd) {
7532
6906
  if (angleInDegrees < 0) {
7533
6907
  angleInDegrees += 360;
7534
6908
  }
7535
- return angleInDegrees;
7536
- }
6909
+ return angleInDegrees;
6910
+ }
6911
+
6912
+ // Render the svg <path> element
6913
+ function getCurvePathData(points, smoothing, closed) {
6914
+ if (smoothing === void 0) { smoothing = 0.2; }
6915
+ // append first 2 points for closed paths
6916
+ if (closed) {
6917
+ points = points.concat(points.slice(0, 2));
6918
+ }
6919
+ // Properties of a line
6920
+ var line = function (pointA, pointB) {
6921
+ var lengthX = pointB.x - pointA.x;
6922
+ var lengthY = pointB.y - pointA.y;
6923
+ return {
6924
+ length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
6925
+ angle: Math.atan2(lengthY, lengthX)
6926
+ };
6927
+ };
6928
+ // Position of a control point
6929
+ var controlPoint = function (current, previous, next, reverse) {
6930
+ var p = previous || current;
6931
+ var n = next || current;
6932
+ var o = line(p, n);
6933
+ var angle = o.angle + (reverse ? Math.PI : 0);
6934
+ var length = o.length * smoothing;
6935
+ var x = current.x + Math.cos(angle) * length;
6936
+ var y = current.y + Math.sin(angle) * length;
6937
+ return { x: x, y: y };
6938
+ };
6939
+ var pathData = [];
6940
+ pathData.push({ type: "M", values: [points[0].x, points[0].y] });
6941
+ for (var i = 1; i < points.length; i++) {
6942
+ var point = points[i];
6943
+ var cp1 = controlPoint(points[i - 1], points[i - 2], point);
6944
+ var cp2 = controlPoint(point, points[i - 1], points[i + 1], true);
6945
+ var command = {
6946
+ type: "C",
6947
+ values: [cp1.x, cp1.y, cp2.x, cp2.y, point.x, point.y]
6948
+ };
6949
+ pathData.push(command);
6950
+ }
6951
+ // copy last commands 1st controlpoint to first curveto
6952
+ if (closed) {
6953
+ var comLast = pathData[pathData.length - 1];
6954
+ var valuesLastC = comLast.values;
6955
+ var valuesFirstC = pathData[1].values;
6956
+ pathData[1] = {
6957
+ type: "C",
6958
+ values: [valuesLastC[0], valuesLastC[1], valuesFirstC.slice(2)].flat()
6959
+ };
6960
+ // delete last curveto
6961
+ pathData = pathData.slice(0, pathData.length - 1);
6962
+ }
6963
+ return pathData;
6964
+ }
6965
+ // convert pathdata to d attribute string
6966
+ function pathDataToD(pathData, decimals) {
6967
+ if (decimals === void 0) { decimals = 3; }
6968
+ var d = pathData
6969
+ .map(function (com) {
6970
+ return "".concat(com.type).concat(com.values.map(function (value) { return +value.toFixed(decimals); }).join(" "));
6971
+ })
6972
+ .join(" ");
6973
+ return d;
6974
+ }
6975
+ function createSmoothPathString(points, smoothing, close) {
6976
+ var pathData = getCurvePathData(points, smoothing, close);
6977
+ var pathString = pathDataToD(pathData);
6978
+ return pathString;
6979
+ }
6980
+ // a helper function to measure the distance between 2 points
6981
+ function dist(p1, p2) {
6982
+ var dx = p2.x - p1.x;
6983
+ var dy = p2.y - p1.y;
6984
+ return Math.sqrt(dx * dx + dy * dy);
6985
+ }
6986
+ //find distance from starting point of path to a point
6987
+ function getLengthForPoint(p, thePath, precision) {
6988
+ if (precision === void 0) { precision = 50; }
6989
+ var pathLength = thePath.getTotalLength();
6990
+ var theRecord = pathLength; //length of path
6991
+ var division = pathLength / precision;
6992
+ var theSegment;
6993
+ for (var i = 0; i < precision; i++) {
6994
+ // get a point on the path for thia distance
6995
+ var _p = thePath.getPointAtLength(i * division);
6996
+ // get the distance between the new point _p and the point p
6997
+ var theDistance = dist(_p, p);
6998
+ if (theDistance < theRecord) {
6999
+ // if the distance is smaller than the record set the new record
7000
+ theRecord = theDistance;
7001
+ theSegment = i;
7002
+ }
7003
+ }
7004
+ return (theSegment * division);
7005
+ }
7006
+ //Add points to the list of points in the correct position
7007
+ function addPointToList(point, listPoints, path) {
7008
+ var getAddIndex = function (startIndex, endIndex) {
7009
+ //Add in the middle if there are only 2 points
7010
+ if ((endIndex - startIndex) === 1) {
7011
+ return startIndex + 1;
7012
+ }
7013
+ var middleIndex = Math.ceil((startIndex + endIndex) / 2);
7014
+ var lengthOfMiddlePoint = getLengthForPoint(listPoints[middleIndex], path); //distance from start point to mid point
7015
+ var lengthOfAddedPoint = getLengthForPoint(point, path); //distance from adding point to mid point
7016
+ //compare if lengthOfMiddlePoint is less than lengthOfAddedPoint,
7017
+ //then new point can be added in the range of mid point to end point,
7018
+ //otherwise it can be added in the range of start point to middle point.
7019
+ if (lengthOfAddedPoint < lengthOfMiddlePoint) {
7020
+ return getAddIndex(startIndex, middleIndex);
7021
+ }
7022
+ else {
7023
+ return getAddIndex(middleIndex, endIndex);
7024
+ }
7025
+ };
7026
+ var addedIndex = getAddIndex(0, listPoints.length - 1);
7027
+ listPoints.splice(addedIndex, 0, point);
7028
+ return __spreadArray([], listPoints, true);
7029
+ }
7030
+ // Parse the d attribute of a path element and extract points from path commands
7031
+ function getPointsFromPathData(dAttribute) {
7032
+ var points = [];
7033
+ // Remove extra whitespace and split by command letters
7034
+ var cleanD = dAttribute.replace(/\s+/g, ' ').trim();
7035
+ // Regular expression to match path commands (M, L, C, etc.) and their values
7036
+ var commandRegex = /([MLCZmlcz])\s*([^MLCZmlcz]*)/g;
7037
+ var match;
7038
+ while ((match = commandRegex.exec(cleanD)) !== null) {
7039
+ var command = match[1].toUpperCase();
7040
+ var values = match[2].trim();
7041
+ if (values) {
7042
+ var coords = values.split(/[\s,]+/).map(Number).filter(function (num) { return !isNaN(num); });
7043
+ switch (command) {
7044
+ case 'M': // Move to
7045
+ if (coords.length >= 2) {
7046
+ points.push({ x: coords[0], y: coords[1] });
7047
+ }
7048
+ break;
7049
+ case 'L': // Line to
7050
+ if (coords.length >= 2) {
7051
+ points.push({ x: coords[0], y: coords[1] });
7052
+ }
7053
+ break;
7054
+ case 'C': // Cubic bezier curve
7055
+ // For cubic curves, we take the end point (last 2 coordinates)
7056
+ if (coords.length >= 6) {
7057
+ points.push({ x: coords[4], y: coords[5] });
7058
+ }
7059
+ break;
7060
+ case 'Q': // Quadratic bezier curve
7061
+ // For quadratic curves, we take the end point (last 2 coordinates)
7062
+ if (coords.length >= 4) {
7063
+ points.push({ x: coords[2], y: coords[3] });
7064
+ }
7065
+ break;
7066
+ }
7067
+ }
7068
+ }
7069
+ return points;
7070
+ }
7071
+ // Get points from a path element's d attribute
7072
+ function getPointsFromPathElement(pathElement) {
7073
+ var dAttribute = pathElement.getAttribute('d');
7074
+ if (!dAttribute) {
7075
+ return [];
7076
+ }
7077
+ return getPointsFromPathData(dAttribute);
7078
+ }
7079
+
7080
+ // Calculate the position of the 4 vertices of a rectangle relative to its parent svg
7081
+ var getRectangleCorners = function (rectSVG) {
7082
+ var ownerSVG = rectSVG.ownerSVGElement;
7083
+ var rectStrokeWidth = Number(rectSVG.getAttribute('stroke-width')) || 0;
7084
+ var strokeWidthOffset = rectStrokeWidth / 2;
7085
+ if (!ownerSVG) {
7086
+ throw new Error('Rectangle does not wrapper by svg.');
7087
+ }
7088
+ var ownerX = ownerSVG.x.baseVal.value;
7089
+ var ownerY = ownerSVG.y.baseVal.value;
7090
+ var ownerWidth = ownerSVG.width.baseVal.value;
7091
+ var ownerHeight = ownerSVG.height.baseVal.value;
7092
+ var a = { x: ownerX + strokeWidthOffset, y: ownerY + strokeWidthOffset };
7093
+ var b = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + strokeWidthOffset };
7094
+ var c = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7095
+ var d = { x: ownerX + strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7096
+ return [a, b, c, d];
7097
+ };
7098
+ //find rotation angle of svg element on g element
7099
+ var getElementRotationInfo = function (element) {
7100
+ var gElement = element;
7101
+ var rotationAngle = 0;
7102
+ while (!(gElement instanceof SVGGElement)) {
7103
+ gElement = gElement.parentElement;
7104
+ }
7105
+ var transform = gElement.getAttribute('transform');
7106
+ if (transform) {
7107
+ // Match the rotation value using a regular expression
7108
+ var rotateMatch = transform.match(/rotate\(([-\d.]+)(?:\s+[-\d.]+\s+[-\d.]+)?\)/);
7109
+ if (rotateMatch) {
7110
+ // The first capture group is the rotation angle
7111
+ rotationAngle = parseFloat(rotateMatch[1]);
7112
+ }
7113
+ }
7114
+ return rotationAngle;
7115
+ };
7537
7116
 
7538
7117
  /**
7539
7118
  * Check if position 1 is within the radius r of position 2
@@ -7573,591 +7152,1184 @@ var findNearestPointOnSegment = function (position, linePoints) {
7573
7152
  var segment = Flatten$1.segment(Flatten$1.point(beginPosition.x, beginPosition.y), Flatten$1.point(endPosition.x, endPosition.y));
7574
7153
  var _a = point.distanceTo(segment); _a[0]; var segmentFromPointToSegment = _a[1];
7575
7154
  return {
7576
- x: segmentFromPointToSegment.pe.x,
7577
- y: segmentFromPointToSegment.pe.y
7155
+ x: segmentFromPointToSegment.pe.x,
7156
+ y: segmentFromPointToSegment.pe.y
7157
+ };
7158
+ };
7159
+ /**
7160
+ * From 1 point find projected Point on the line segments so that the distance between 2 points is shortest.
7161
+ * @param position
7162
+ * @param lines
7163
+ * @returns
7164
+ */
7165
+ var findNearestProjectedPoint = function (position, lines) {
7166
+ var possiblePoints = lines.map(function (p) { return findNearestPointOnSegment(position, p); });
7167
+ var nearestPoint = findNearestPosition(possiblePoints, position);
7168
+ return nearestPoint;
7169
+ };
7170
+ /**
7171
+ * Check if a point is inside a polygon
7172
+ * @param position
7173
+ * @param polygonPoints
7174
+ * @returns
7175
+ */
7176
+ var checkPointContainsPolygon = function (position, polygonPoints) {
7177
+ var polygon = new Flatten$1.Polygon();
7178
+ polygon.addFace(polygonPoints.map(function (p) { return Flatten$1.point(p.x, p.y); }));
7179
+ return polygon.contains(Flatten$1.point(position.x, position.y));
7180
+ };
7181
+ /**
7182
+ * @param ele : IElement
7183
+ * @returns Flatten.Polygon
7184
+ */
7185
+ var makePolygonOfElement = function (ele) {
7186
+ var polygon = new Flatten$1.Polygon();
7187
+ var vertexes = getFourVertexesOfBBoxFromElement(ele);
7188
+ polygon.addFace([
7189
+ Flatten$1.point(vertexes[0].x, vertexes[0].y),
7190
+ Flatten$1.point(vertexes[1].x, vertexes[1].y),
7191
+ Flatten$1.point(vertexes[2].x, vertexes[2].y),
7192
+ Flatten$1.point(vertexes[3].x, vertexes[3].y),
7193
+ ]);
7194
+ return polygon;
7195
+ };
7196
+ var getIntersectionPositions = function (pointStart, pointEnd, ele) {
7197
+ var segment = Flatten$1.segment(Flatten$1.point(pointStart.x, pointStart.y), Flatten$1.point(pointEnd.x, pointEnd.y));
7198
+ var polygonOfEle = makePolygonOfElement(ele);
7199
+ /* Remove duplicate positions from the result of finding the intersection points between a segment and a polygon.
7200
+ It then maps the intersection points to objects with rounded x and y coordinates. */
7201
+ return removeDuplicatePosition(segment.intersect(polygonOfEle).map(function (p) { return ({ x: Math.round(p.x), y: Math.round(p.y) }); }));
7202
+ };
7203
+ //Find the first intersection point of the line starting from startPosition to endPosition on the elements
7204
+ var getFirstIntersection = function (startPosition, endPosition, elements) {
7205
+ if (!endPosition)
7206
+ return undefined;
7207
+ var result;
7208
+ for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
7209
+ var element = elements_1[_i];
7210
+ //Find intersection positions on element
7211
+ var intersectionPoints = getIntersectionPositions(startPosition, endPosition, element);
7212
+ //If the line intersects at 1 point (can be the starting point or the ending point) or no point then ignore
7213
+ if (intersectionPoints.length <= 1) {
7214
+ continue;
7215
+ }
7216
+ var selectablePointsList = __spreadArray([], intersectionPoints, true);
7217
+ //If a point is found on a previous element, add it to the list of intersection points on the current element.
7218
+ if (result === null || result === void 0 ? void 0 : result.nearestIntersection) {
7219
+ selectablePointsList.push(result.nearestIntersection);
7220
+ }
7221
+ var nearest = findNearestPosition(selectablePointsList, startPosition);
7222
+ //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.
7223
+ if (!(result === null || result === void 0 ? void 0 : result.nearestIntersection) || !checkSamePosition(nearest, result.nearestIntersection)) {
7224
+ result = {
7225
+ element: element,
7226
+ intersectionPointsList: intersectionPoints,
7227
+ nearestIntersection: nearest,
7228
+ };
7229
+ }
7230
+ }
7231
+ return result;
7232
+ };
7233
+ //Find a point next to an element from a point on the element
7234
+ var generateSubstitutePosition = function (intersectedPosition, targetPosition, ele) {
7235
+ var translationOffset = 20;
7236
+ var _a = getFourVertexesOfBBoxFromElement(ele), vertex1Position = _a[0], vertex2Position = _a[1], vertex3Position = _a[2], vertex4Position = _a[3];
7237
+ var replacementPosition = null;
7238
+ if (checkSamePosition(vertex1Position, intersectedPosition, 0)) {
7239
+ //Cut at vertex 1 of bbox, move out a distance x,y
7240
+ replacementPosition = {
7241
+ x: vertex1Position.x - translationOffset,
7242
+ y: vertex1Position.y - translationOffset,
7243
+ };
7244
+ }
7245
+ else if (checkSamePosition(vertex2Position, intersectedPosition, 0)) {
7246
+ //Cut at vertex 2 of bbox, move out a distance x,y
7247
+ replacementPosition = {
7248
+ x: vertex2Position.x + translationOffset,
7249
+ y: vertex2Position.y - translationOffset,
7250
+ };
7251
+ }
7252
+ else if (checkSamePosition(vertex3Position, intersectedPosition, 0)) {
7253
+ //Cut at vertex 3 of bbox, move out a distance x,y
7254
+ replacementPosition = {
7255
+ x: vertex3Position.x + translationOffset,
7256
+ y: vertex3Position.y + translationOffset,
7257
+ };
7258
+ }
7259
+ else if (checkSamePosition(vertex4Position, intersectedPosition, 0)) {
7260
+ //Cut at vertex 4 of bbox, move out a distance x,y
7261
+ replacementPosition = {
7262
+ x: vertex4Position.x - translationOffset,
7263
+ y: vertex4Position.y + translationOffset,
7264
+ };
7265
+ }
7266
+ else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex2Position])) {
7267
+ //cut top edge, move left or right
7268
+ var lineOfVertex12 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex2Position.x, vertex2Position.y));
7269
+ //Check if the line lies on the edge of the bbox then move the starting point out 1 distance perpendicular to the edge.
7270
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex12)[0] === 0 &&
7271
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex12)[0] === 0) {
7272
+ //lie on a straight line 1-2
7273
+ replacementPosition = {
7274
+ x: intersectedPosition.x,
7275
+ y: intersectedPosition.y - translationOffset,
7276
+ };
7277
+ }
7278
+ else {
7279
+ //Translate to the left of vertex 1
7280
+ var leftPosition = {
7281
+ x: vertex1Position.x - translationOffset,
7282
+ y: vertex1Position.y,
7283
+ };
7284
+ //Translate to the right of vertex 2
7285
+ var rightPosition = {
7286
+ x: vertex2Position.x + translationOffset,
7287
+ y: vertex2Position.y,
7288
+ };
7289
+ replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7290
+ }
7291
+ }
7292
+ else if (checkPositionOnLine(intersectedPosition, [vertex3Position, vertex4Position])) {
7293
+ //cut bottom edge, move left or right
7294
+ var lineOfVertex34 = Flatten$1.line(Flatten$1.point(vertex3Position.x, vertex3Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7295
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex34)[0] === 0 &&
7296
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex34)[0] === 0) {
7297
+ //lie on a straight line 3-4
7298
+ replacementPosition = {
7299
+ x: intersectedPosition.x,
7300
+ y: intersectedPosition.y + translationOffset,
7301
+ };
7302
+ }
7303
+ else {
7304
+ //Translate to the left of vertex 4
7305
+ var leftPosition = {
7306
+ x: vertex4Position.x - translationOffset,
7307
+ y: vertex4Position.y,
7308
+ };
7309
+ //Translate to the right of vertex 3
7310
+ var rightPosition = {
7311
+ x: vertex3Position.x + translationOffset,
7312
+ y: vertex3Position.y,
7313
+ };
7314
+ replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7315
+ }
7316
+ }
7317
+ else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex4Position])) {
7318
+ //cut left edge, move up or down
7319
+ var lineOfVertex14 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7320
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex14)[0] === 0 &&
7321
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex14)[0] === 0) {
7322
+ //lie on a straight line 1-4
7323
+ replacementPosition = {
7324
+ x: intersectedPosition.x - translationOffset,
7325
+ y: intersectedPosition.y,
7326
+ };
7327
+ }
7328
+ else {
7329
+ //Translate to the top of vertex 1
7330
+ var topPosition = {
7331
+ x: vertex1Position.x,
7332
+ y: vertex1Position.y - translationOffset,
7333
+ };
7334
+ //Translate to the bottom of vertex 4
7335
+ var bottomPosition = {
7336
+ x: vertex4Position.x,
7337
+ y: vertex4Position.y + translationOffset,
7338
+ };
7339
+ replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7340
+ }
7341
+ }
7342
+ else if (checkPositionOnLine(intersectedPosition, [vertex2Position, vertex3Position])) {
7343
+ //cut right edge, move up or down
7344
+ var lineOfVertex23 = Flatten$1.line(Flatten$1.point(vertex2Position.x, vertex2Position.y), Flatten$1.point(vertex3Position.x, vertex3Position.y));
7345
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex23)[0] === 0 &&
7346
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex23)[0] === 0) {
7347
+ //lie on a straight line 2-3
7348
+ replacementPosition = {
7349
+ x: intersectedPosition.x + translationOffset,
7350
+ y: intersectedPosition.y,
7351
+ };
7352
+ }
7353
+ else {
7354
+ //Translate to the top of vertex 2
7355
+ var topPosition = {
7356
+ x: vertex2Position.x,
7357
+ y: vertex2Position.y - translationOffset,
7358
+ };
7359
+ //Translate to the bottom of vertex 3
7360
+ var bottomPosition = {
7361
+ x: vertex3Position.x,
7362
+ y: vertex3Position.y + translationOffset,
7363
+ };
7364
+ replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7365
+ }
7366
+ }
7367
+ return replacementPosition;
7368
+ };
7369
+ // export const getRelativePosition = (clientPosition: IPosition, relativeElement: Element): IPosition => {
7370
+ // const relativeRect = relativeElement.getBoundingClientRect();
7371
+ // return {
7372
+ // x: clientPosition.x - relativeRect.left,
7373
+ // y: clientPosition.y - relativeRect.top,
7374
+ // }
7375
+ // }
7376
+ var getFourVertexesOfBBoxFromElement = function (element) {
7377
+ var absolutePosition = getAbsolutePosition(element);
7378
+ var vertex1Position = {
7379
+ x: absolutePosition.x,
7380
+ y: absolutePosition.y
7381
+ };
7382
+ var vertex2Position = {
7383
+ x: absolutePosition.x + element.size.width,
7384
+ y: absolutePosition.y
7385
+ };
7386
+ var vertex3Position = {
7387
+ x: absolutePosition.x + element.size.width,
7388
+ y: absolutePosition.y + element.size.height
7389
+ };
7390
+ var vertex4Position = {
7391
+ x: absolutePosition.x,
7392
+ y: absolutePosition.y + element.size.height
7393
+ };
7394
+ return [vertex1Position, vertex2Position, vertex3Position, vertex4Position];
7395
+ };
7396
+ //get absolute position of element
7397
+ var getAbsolutePosition = function (element) {
7398
+ var parentElement = element.parentElement;
7399
+ var elemenetPositionWithTopLeftAnchor = {
7400
+ x: element.position.x,
7401
+ y: element.position.y,
7402
+ };
7403
+ if (element.positionAnchor === exports.PositioningAnchor.Center) {
7404
+ elemenetPositionWithTopLeftAnchor.x -= element.size.width / 2;
7405
+ elemenetPositionWithTopLeftAnchor.y -= element.size.height / 2;
7406
+ }
7407
+ if (!parentElement) {
7408
+ return __assign({}, elemenetPositionWithTopLeftAnchor);
7409
+ }
7410
+ var absoluteParentElement = getAbsolutePosition(parentElement);
7411
+ var x = elemenetPositionWithTopLeftAnchor.x + absoluteParentElement.x;
7412
+ var y = elemenetPositionWithTopLeftAnchor.y + absoluteParentElement.y;
7413
+ return {
7414
+ x: x,
7415
+ y: y,
7578
7416
  };
7579
7417
  };
7580
- /**
7581
- * From 1 point find projected Point on the line segments so that the distance between 2 points is shortest.
7582
- * @param position
7583
- * @param lines
7584
- * @returns
7585
- */
7586
- var findNearestProjectedPoint = function (position, lines) {
7587
- var possiblePoints = lines.map(function (p) { return findNearestPointOnSegment(position, p); });
7588
- var nearestPoint = findNearestPosition(possiblePoints, position);
7589
- return nearestPoint;
7590
- };
7591
- /**
7592
- * Check if a point is inside a polygon
7593
- * @param position
7594
- * @param polygonPoints
7595
- * @returns
7596
- */
7597
- var checkPointContainsPolygon = function (position, polygonPoints) {
7598
- var polygon = new Flatten$1.Polygon();
7599
- polygon.addFace(polygonPoints.map(function (p) { return Flatten$1.point(p.x, p.y); }));
7600
- return polygon.contains(Flatten$1.point(position.x, position.y));
7418
+ //get absolute position of element
7419
+ var getPortAbsolutePosition = function (port, element) {
7420
+ var elementAbsolutePosition = getAbsolutePosition(element);
7421
+ return {
7422
+ x: elementAbsolutePosition.x + port.position.x,
7423
+ y: elementAbsolutePosition.y + port.position.y,
7424
+ };
7601
7425
  };
7602
- /**
7603
- * @param ele : IElement
7604
- * @returns Flatten.Polygon
7605
- */
7606
- var makePolygonOfElement = function (ele) {
7607
- var polygon = new Flatten$1.Polygon();
7608
- var vertexes = getFourVertexesOfBBoxFromElement(ele);
7609
- polygon.addFace([
7610
- Flatten$1.point(vertexes[0].x, vertexes[0].y),
7611
- Flatten$1.point(vertexes[1].x, vertexes[1].y),
7612
- Flatten$1.point(vertexes[2].x, vertexes[2].y),
7613
- Flatten$1.point(vertexes[3].x, vertexes[3].y),
7614
- ]);
7615
- return polygon;
7426
+ var transformAbsPositionToElementRelativePosition = function (position, element) {
7427
+ var parentElement = element.parentElement;
7428
+ if (!parentElement) {
7429
+ return position;
7430
+ }
7431
+ var absoluteParentElement = getAbsolutePosition(parentElement);
7432
+ var result = {
7433
+ x: position.x - absoluteParentElement.x,
7434
+ y: position.y - absoluteParentElement.y,
7435
+ };
7436
+ if (element.positionAnchor === exports.PositioningAnchor.Center) {
7437
+ result.x += element.size.width / 2;
7438
+ result.y += element.size.height / 2;
7439
+ }
7440
+ return result;
7616
7441
  };
7617
- var getIntersectionPositions = function (pointStart, pointEnd, ele) {
7618
- var segment = Flatten$1.segment(Flatten$1.point(pointStart.x, pointStart.y), Flatten$1.point(pointEnd.x, pointEnd.y));
7619
- var polygonOfEle = makePolygonOfElement(ele);
7620
- /* Remove duplicate positions from the result of finding the intersection points between a segment and a polygon.
7621
- It then maps the intersection points to objects with rounded x and y coordinates. */
7622
- return removeDuplicatePosition(segment.intersect(polygonOfEle).map(function (p) { return ({ x: Math.round(p.x), y: Math.round(p.y) }); }));
7442
+ var transformAbsPositionToRelativePositionInsideElement = function (absolutePosition, parentAbsolutePosition) {
7443
+ var _a, _b;
7444
+ var position = {
7445
+ x: absolutePosition.x - ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0),
7446
+ y: absolutePosition.y - ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0),
7447
+ };
7448
+ return position;
7623
7449
  };
7624
- //Find the first intersection point of the line starting from startPosition to endPosition on the elements
7625
- var getFirstIntersection = function (startPosition, endPosition, elements) {
7626
- if (!endPosition)
7627
- return undefined;
7628
- var result;
7629
- for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
7630
- var element = elements_1[_i];
7631
- //Find intersection positions on element
7632
- var intersectionPoints = getIntersectionPositions(startPosition, endPosition, element);
7633
- //If the line intersects at 1 point (can be the starting point or the ending point) or no point then ignore
7634
- if (intersectionPoints.length <= 1) {
7635
- continue;
7450
+ var correctPortPositionInElement = function (elementRelativePosition, elementWidth, elementHeight, portMoveableAreas, portSlideRailSVGClassName, element) {
7451
+ //Normalize a point so that it can lie exactly on an area
7452
+ var normalizePortPositionOnMoveableAreas = function (moveableAreas, position) {
7453
+ var lines = moveableAreas.filter(function (area) { return area.length === 2; });
7454
+ var polygons = moveableAreas.filter(function (area) { return area.length >= 3; });
7455
+ var normalizedPosition;
7456
+ //If moveableAreas is lines
7457
+ if (lines.length > 0) {
7458
+ var newPosition_1 = findNearestProjectedPoint({ x: position.x, y: position.y }, lines);
7459
+ if (newPosition_1) {
7460
+ normalizedPosition = newPosition_1;
7461
+ }
7636
7462
  }
7637
- var selectablePointsList = __spreadArray([], intersectionPoints, true);
7638
- //If a point is found on a previous element, add it to the list of intersection points on the current element.
7639
- if (result === null || result === void 0 ? void 0 : result.nearestIntersection) {
7640
- selectablePointsList.push(result.nearestIntersection);
7463
+ //If moveableAreas is polygons
7464
+ else if (polygons.length > 0) {
7465
+ var newPosition_2 = { x: position.x, y: position.y };
7466
+ var isContainsInPolygons = polygons.some(function (p) { return checkPointContainsPolygon(newPosition_2, p); });
7467
+ if (isContainsInPolygons) {
7468
+ normalizedPosition = newPosition_2;
7469
+ }
7641
7470
  }
7642
- var nearest = findNearestPosition(selectablePointsList, startPosition);
7643
- //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.
7644
- if (!(result === null || result === void 0 ? void 0 : result.nearestIntersection) || !checkSamePosition(nearest, result.nearestIntersection)) {
7645
- result = {
7646
- element: element,
7647
- intersectionPointsList: intersectionPoints,
7648
- nearestIntersection: nearest,
7649
- };
7471
+ return normalizedPosition;
7472
+ };
7473
+ var getSlideRailSVG = function (portSlideRailSVGClassName) {
7474
+ if (!element)
7475
+ return;
7476
+ var slideRailSVG = element.querySelector(".".concat(portSlideRailSVGClassName));
7477
+ return slideRailSVG;
7478
+ };
7479
+ //Calculate the position of the 4 vertices of a rectangle relative to element
7480
+ var calculateSlideRailRectSVGPositions = function (slideRailSVG) {
7481
+ var coordinates = getRectangleCorners(slideRailSVG);
7482
+ var ownerSVG = slideRailSVG.ownerSVGElement;
7483
+ var rotationAngle = getElementRotationInfo(ownerSVG);
7484
+ if (rotationAngle !== 0) {
7485
+ var rotationCenterX = elementWidth / 2;
7486
+ var rotationCenterY = elementHeight / 2;
7487
+ coordinates = getRotatedRectangleCoordinates(coordinates, rotationCenterX, rotationCenterY, rotationAngle);
7488
+ }
7489
+ return coordinates;
7490
+ };
7491
+ var normalizePortPositionOnSlideRailSVG = function (portSlideRailSVGClassName, position) {
7492
+ var slideRailSVG = getSlideRailSVG(portSlideRailSVGClassName);
7493
+ if (!slideRailSVG)
7494
+ return;
7495
+ var moveTo;
7496
+ //check and get new position if Rect element
7497
+ if (slideRailSVG instanceof SVGRectElement) {
7498
+ var _a = calculateSlideRailRectSVGPositions(slideRailSVG), a = _a[0], b = _a[1], c = _a[2], d = _a[3]; //Get 4 vertices of rect element
7499
+ var moveableAreas = [
7500
+ [a, b],
7501
+ [b, c],
7502
+ [c, d],
7503
+ [d, a]
7504
+ ];
7505
+ logger.info("Port's moveable areas parsed from svg ".concat(portSlideRailSVGClassName), moveableAreas);
7506
+ var newPosition_3 = normalizePortPositionOnMoveableAreas(moveableAreas, position);
7507
+ if (newPosition_3) {
7508
+ moveTo = newPosition_3;
7509
+ }
7510
+ }
7511
+ else if (slideRailSVG instanceof SVGCircleElement) { //check and get new position if circle element
7512
+ var cx = Number(slideRailSVG.getAttribute('cx'));
7513
+ var cy = Number(slideRailSVG.getAttribute('cy'));
7514
+ var r = Number(slideRailSVG.getAttribute('r'));
7515
+ var circle = Flatten$1.circle(Flatten$1.point(cx, cy), r);
7516
+ var _b = circle.distanceTo(Flatten$1.point(position.x, position.y)), num = _b[0], segment = _b[1];
7517
+ if (num <= r) {
7518
+ moveTo = {
7519
+ x: segment.ps.x,
7520
+ y: segment.ps.y,
7521
+ };
7522
+ }
7650
7523
  }
7524
+ return moveTo;
7525
+ };
7526
+ var newPosition;
7527
+ if (portMoveableAreas && portMoveableAreas.length > 0) { //If moveable areas is defined
7528
+ newPosition = normalizePortPositionOnMoveableAreas(portMoveableAreas, elementRelativePosition);
7651
7529
  }
7652
- return result;
7530
+ else if (portSlideRailSVGClassName) { //If port slide rail svg classname is defined
7531
+ newPosition = normalizePortPositionOnSlideRailSVG(portSlideRailSVGClassName, elementRelativePosition);
7532
+ }
7533
+ return newPosition || elementRelativePosition;
7653
7534
  };
7654
- //Find a point next to an element from a point on the element
7655
- var generateSubstitutePosition = function (intersectedPosition, targetPosition, ele) {
7656
- var translationOffset = 20;
7657
- var _a = getFourVertexesOfBBoxFromElement(ele), vertex1Position = _a[0], vertex2Position = _a[1], vertex3Position = _a[2], vertex4Position = _a[3];
7658
- var replacementPosition = null;
7659
- if (checkSamePosition(vertex1Position, intersectedPosition, 0)) {
7660
- //Cut at vertex 1 of bbox, move out a distance x,y
7661
- replacementPosition = {
7662
- x: vertex1Position.x - translationOffset,
7663
- y: vertex1Position.y - translationOffset,
7535
+ var windowsPositionToPaperPosition = function (clientPosition, paperElement, zoom) {
7536
+ var paperRect = paperElement.getBoundingClientRect();
7537
+ // Calculate the position relative to the paper element
7538
+ var xPosOnPaper = (clientPosition.x - paperRect.left) / zoom;
7539
+ var yPosOnPaper = (clientPosition.y - paperRect.top) / zoom;
7540
+ return {
7541
+ x: Math.round(xPosOnPaper),
7542
+ y: Math.round(yPosOnPaper),
7543
+ };
7544
+ };
7545
+
7546
+ var getSVGBBoxOutsideTransformedParent = function (svgElement) {
7547
+ var bbox = svgElement.getBBox(); // Get bounding box of the element
7548
+ var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
7549
+ // Define the four corners of the bounding box
7550
+ var corners = [
7551
+ { x: bbox.x, y: bbox.y },
7552
+ { x: bbox.x + bbox.width, y: bbox.y },
7553
+ { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
7554
+ { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
7555
+ ];
7556
+ // Function to apply the transformation matrix to a point
7557
+ function transformPoint(x, y, matrix) {
7558
+ return {
7559
+ x: matrix.a * x + matrix.c * y + matrix.e,
7560
+ y: matrix.b * x + matrix.d * y + matrix.f
7664
7561
  };
7665
7562
  }
7666
- else if (checkSamePosition(vertex2Position, intersectedPosition, 0)) {
7667
- //Cut at vertex 2 of bbox, move out a distance x,y
7668
- replacementPosition = {
7669
- x: vertex2Position.x + translationOffset,
7670
- y: vertex2Position.y - translationOffset,
7671
- };
7563
+ // Transform each corner according to the matrix
7564
+ if (matrix) {
7565
+ return corners.map(function (corner) {
7566
+ return transformPoint(corner.x, corner.y, matrix);
7567
+ });
7672
7568
  }
7673
- else if (checkSamePosition(vertex3Position, intersectedPosition, 0)) {
7674
- //Cut at vertex 3 of bbox, move out a distance x,y
7675
- replacementPosition = {
7676
- x: vertex3Position.x + translationOffset,
7677
- y: vertex3Position.y + translationOffset,
7678
- };
7569
+ else {
7570
+ return corners;
7679
7571
  }
7680
- else if (checkSamePosition(vertex4Position, intersectedPosition, 0)) {
7681
- //Cut at vertex 4 of bbox, move out a distance x,y
7682
- replacementPosition = {
7683
- x: vertex4Position.x - translationOffset,
7684
- y: vertex4Position.y + translationOffset,
7572
+ };
7573
+ //function returns the array of corners of the bbox of the element after applying the transformation matrix of the parent element
7574
+ var getRotatedSVGBBox = function (svgElement) {
7575
+ var bbox = svgElement.getBBox(); // Get bounding box of the element
7576
+ var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
7577
+ // Define the four corners of the bounding box
7578
+ var corners = [
7579
+ { x: bbox.x, y: bbox.y },
7580
+ { x: bbox.x + bbox.width, y: bbox.y },
7581
+ { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
7582
+ { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
7583
+ ];
7584
+ // Function to apply the transformation matrix to a point
7585
+ function transformPoint(x, y, matrix) {
7586
+ return {
7587
+ x: matrix.a * x + matrix.c * y,
7588
+ y: matrix.b * x + matrix.d * y // + matrix.f
7685
7589
  };
7686
7590
  }
7687
- else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex2Position])) {
7688
- //cut top edge, move left or right
7689
- var lineOfVertex12 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex2Position.x, vertex2Position.y));
7690
- //Check if the line lies on the edge of the bbox then move the starting point out 1 distance perpendicular to the edge.
7691
- if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex12)[0] === 0 &&
7692
- Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex12)[0] === 0) {
7693
- //lie on a straight line 1-2
7694
- replacementPosition = {
7695
- x: intersectedPosition.x,
7696
- y: intersectedPosition.y - translationOffset,
7697
- };
7591
+ // Transform each corner according to the matrix
7592
+ if (matrix) {
7593
+ return corners.map(function (corner) {
7594
+ return transformPoint(corner.x, corner.y, matrix);
7595
+ });
7596
+ }
7597
+ else {
7598
+ return corners;
7599
+ }
7600
+ };
7601
+
7602
+ var SelectionFrame = function (props) {
7603
+ var propTargetSVGElement = props.targetSVGElement, propWidth = props.width, propHeight = props.height, propFramePadding = props.framePadding, objectX = props.objectX, objectY = props.objectY,
7604
+ // movingOffsetThreshold: propMovingOffsetThreshold,
7605
+ 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;
7606
+ var bbox = propTargetSVGElement === null || propTargetSVGElement === void 0 ? void 0 : propTargetSVGElement.getBBox();
7607
+ var _a = React.useState(propWidth || (bbox === null || bbox === void 0 ? void 0 : bbox.width) || MIN_ELEMENT_SIZE), width = _a[0], setWidth = _a[1];
7608
+ var _b = React.useState(propHeight || (bbox === null || bbox === void 0 ? void 0 : bbox.height) || MIN_ELEMENT_SIZE), height = _b[0], setHeight = _b[1];
7609
+ React.useEffect(function () {
7610
+ if (propWidth) {
7611
+ setWidth(propWidth);
7698
7612
  }
7699
- else {
7700
- //Translate to the left of vertex 1
7701
- var leftPosition = {
7702
- x: vertex1Position.x - translationOffset,
7703
- y: vertex1Position.y,
7704
- };
7705
- //Translate to the right of vertex 2
7706
- var rightPosition = {
7707
- x: vertex2Position.x + translationOffset,
7708
- y: vertex2Position.y,
7709
- };
7710
- replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7613
+ }, [objectX, propWidth]);
7614
+ React.useEffect(function () {
7615
+ if (propHeight) {
7616
+ setHeight(propHeight);
7711
7617
  }
7712
- }
7713
- else if (checkPositionOnLine(intersectedPosition, [vertex3Position, vertex4Position])) {
7714
- //cut bottom edge, move left or right
7715
- var lineOfVertex34 = Flatten$1.line(Flatten$1.point(vertex3Position.x, vertex3Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7716
- if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex34)[0] === 0 &&
7717
- Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex34)[0] === 0) {
7718
- //lie on a straight line 3-4
7719
- replacementPosition = {
7720
- x: intersectedPosition.x,
7721
- y: intersectedPosition.y + translationOffset,
7722
- };
7618
+ }, [objectY, propHeight]);
7619
+ var _c = React.useState(objectX !== null && objectX !== void 0 ? objectX : 0), curX = _c[0], setCurX = _c[1];
7620
+ var _d = React.useState(objectY !== null && objectY !== void 0 ? objectY : 0), curY = _d[0], setCurY = _d[1];
7621
+ React.useEffect(function () {
7622
+ if (objectX) {
7623
+ setCurX(objectX);
7723
7624
  }
7724
- else {
7725
- //Translate to the left of vertex 4
7726
- var leftPosition = {
7727
- x: vertex4Position.x - translationOffset,
7728
- y: vertex4Position.y,
7729
- };
7730
- //Translate to the right of vertex 3
7731
- var rightPosition = {
7732
- x: vertex3Position.x + translationOffset,
7733
- y: vertex3Position.y,
7734
- };
7735
- replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7625
+ }, [objectX]);
7626
+ React.useEffect(function () {
7627
+ if (objectY) {
7628
+ setCurY(objectY);
7736
7629
  }
7737
- }
7738
- else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex4Position])) {
7739
- //cut left edge, move up or down
7740
- var lineOfVertex14 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7741
- if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex14)[0] === 0 &&
7742
- Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex14)[0] === 0) {
7743
- //lie on a straight line 1-4
7744
- replacementPosition = {
7745
- x: intersectedPosition.x - translationOffset,
7746
- y: intersectedPosition.y,
7747
- };
7630
+ }, [objectY]);
7631
+ var framePadding = propFramePadding || 0;
7632
+ var r = 5;
7633
+ var _e = React.useState(false), draggingRect = _e[0], setDraggingRect = _e[1];
7634
+ var _f = React.useState(false), draggingCircle = _f[0], setDraggingCircle = _f[1];
7635
+ var _g = React.useState(0), startX = _g[0], setStartX = _g[1];
7636
+ var _h = React.useState(0), startY = _h[0], setStartY = _h[1];
7637
+ var _j = React.useState(0), xFromMouse = _j[0], setXFromMouse = _j[1];
7638
+ var _k = React.useState(0), yFromMouse = _k[0], setYFromMouse = _k[1];
7639
+ var _l = React.useState(0), lastMoveTime = _l[0], setLastMoveTime = _l[1];
7640
+ var getMousePosition = function (event) {
7641
+ var position = windowsPositionToPaperPosition({
7642
+ x: event.clientX,
7643
+ y: event.clientY
7644
+ }, propContainer, zoom);
7645
+ return position;
7646
+ };
7647
+ var addRectHandleMouseDown = function (event) {
7648
+ event.stopPropagation();
7649
+ if (!draggingCircle) {
7650
+ setDraggingRect(true);
7651
+ setStartX(event.clientX);
7652
+ setStartY(event.clientY);
7653
+ var mousePosition = getMousePosition(event);
7654
+ var xFromMouse_1 = (curX || 0) - mousePosition.x;
7655
+ var yFromMouse_1 = (curY || 0) - mousePosition.y;
7656
+ setXFromMouse(xFromMouse_1);
7657
+ setYFromMouse(yFromMouse_1);
7748
7658
  }
7749
- else {
7750
- //Translate to the top of vertex 1
7751
- var topPosition = {
7752
- x: vertex1Position.x,
7753
- y: vertex1Position.y - translationOffset,
7754
- };
7755
- //Translate to the bottom of vertex 4
7756
- var bottomPosition = {
7757
- x: vertex4Position.x,
7758
- y: vertex4Position.y + translationOffset,
7759
- };
7760
- replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7659
+ if (propOnMouseDown) {
7660
+ propOnMouseDown(event);
7661
+ }
7662
+ };
7663
+ var rectHandleMouseMove = React.useCallback(function (event) {
7664
+ var mouseEvent = event;
7665
+ if (draggingRect) {
7666
+ if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
7667
+ return;
7668
+ }
7669
+ //Coordinates of mouse on paper.
7670
+ var mousePosition = getMousePosition(mouseEvent);
7671
+ var newX = mousePosition.x + xFromMouse;
7672
+ var newY = mousePosition.y + yFromMouse;
7673
+ if (propOnMove) {
7674
+ setCurX(newX);
7675
+ setCurY(newY);
7676
+ propOnMove(newX, newY);
7677
+ setLastMoveTime(Date.now());
7678
+ setStartX(mouseEvent.clientX);
7679
+ setStartY(mouseEvent.clientY);
7680
+ }
7681
+ }
7682
+ }, [draggingRect, propOnMove, propMovingRate, startX, startY, lastMoveTime, xFromMouse, yFromMouse, zoom]);
7683
+ React.useEffect(function () {
7684
+ var addRectHandleMouseUp = function () {
7685
+ setDraggingRect(false);
7686
+ setXFromMouse(0);
7687
+ setYFromMouse(0);
7688
+ };
7689
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mousemove', rectHandleMouseMove);
7690
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mouseup', addRectHandleMouseUp);
7691
+ return function () {
7692
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mousemove', rectHandleMouseMove);
7693
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mouseup', addRectHandleMouseUp);
7694
+ };
7695
+ }, [propContainer, rectHandleMouseMove, zoom]);
7696
+ var circleHandleMouseDown = function (event) {
7697
+ event.stopPropagation();
7698
+ if (!draggingRect) {
7699
+ // const paperPosition = getMousePosition(event);
7700
+ // setStartX(paperPosition.x);
7701
+ // setStartY(paperPosition.y);
7702
+ setDraggingCircle(true);
7761
7703
  }
7704
+ };
7705
+ React.useEffect(function () {
7706
+ logger.debug('SelectionFrame: circleHandleMouseDown triggered', {
7707
+ draggingCircle: draggingCircle,
7708
+ startX: startX,
7709
+ startY: startY,
7710
+ width: width,
7711
+ height: height,
7712
+ propMovingRate: propMovingRate
7713
+ });
7714
+ var circleHandleMouseMove = function (event) {
7715
+ var mouseEvent = event;
7716
+ if (draggingCircle) {
7717
+ var mousePosition = getMousePosition(mouseEvent);
7718
+ // let offsetX = mouseEvent.clientX - startX;
7719
+ // let offsetY = mouseEvent.clientY - startY;
7720
+ if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
7721
+ return;
7722
+ }
7723
+ // setStartX(mouseEvent.clientX);
7724
+ // setStartY(mouseEvent.clientY);
7725
+ setLastMoveTime(Date.now());
7726
+ var newWidth = mousePosition.x - curX;
7727
+ var newHeight = mousePosition.y - curY;
7728
+ if (propResizability.keepRatio) {
7729
+ var ratio = Math.max(Math.abs(newWidth / width), Math.abs(newHeight / height));
7730
+ newWidth = newWidth > 0 ? ratio * width : -ratio * width;
7731
+ newHeight = newHeight > 0 ? ratio * height : -ratio * height;
7732
+ }
7733
+ // if (propResizability.keepRatio) {
7734
+ // let resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
7735
+ // const increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
7736
+ // offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
7737
+ // offsetY = increasing ? resizingRatio * height : -resizingRatio * height;
7738
+ // }
7739
+ // newWidth += offsetX;
7740
+ // newHeight += offsetY;
7741
+ if (newWidth < MIN_ELEMENT_SIZE) {
7742
+ newWidth = MIN_ELEMENT_SIZE;
7743
+ }
7744
+ if (newHeight < MIN_ELEMENT_SIZE) {
7745
+ newHeight = MIN_ELEMENT_SIZE;
7746
+ }
7747
+ setWidth(newWidth);
7748
+ setHeight(newHeight);
7749
+ if (propOnResize) {
7750
+ propOnResize(newWidth, newHeight);
7751
+ }
7752
+ }
7753
+ };
7754
+ var circleHandleMouseUp = function () {
7755
+ setDraggingCircle(false);
7756
+ };
7757
+ var container = propContainer;
7758
+ container.addEventListener('mousemove', circleHandleMouseMove);
7759
+ container.addEventListener('mouseup', circleHandleMouseUp);
7760
+ //logging the start of the circle handle mouse move
7761
+ logger.debug('SelectionFrame: circleHandleMouseMove started', container);
7762
+ return function () {
7763
+ container.removeEventListener('mousemove', circleHandleMouseMove);
7764
+ container.removeEventListener('mouseup', circleHandleMouseUp);
7765
+ //logging the end of the circle handle mouse move
7766
+ logger.debug('SelectionFrame: circleHandleMouseMove ended', container);
7767
+ };
7768
+ }, [draggingCircle, width, height, curX, curY, lastMoveTime, propContainer, propMovingRate, propOnResize, propResizability, startX, startY]);
7769
+ var rectangleSize = Math.max(width, height);
7770
+ var leftX = framePadding;
7771
+ var topY = framePadding;
7772
+ if (propAnchor === exports.PositioningAnchor.Center) {
7773
+ leftX -= rectangleSize / 2;
7774
+ topY -= rectangleSize / 2;
7762
7775
  }
7763
- else if (checkPositionOnLine(intersectedPosition, [vertex2Position, vertex3Position])) {
7764
- //cut right edge, move up or down
7765
- var lineOfVertex23 = Flatten$1.line(Flatten$1.point(vertex2Position.x, vertex2Position.y), Flatten$1.point(vertex3Position.x, vertex3Position.y));
7766
- if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex23)[0] === 0 &&
7767
- Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex23)[0] === 0) {
7768
- //lie on a straight line 2-3
7769
- replacementPosition = {
7770
- x: intersectedPosition.x + translationOffset,
7771
- y: intersectedPosition.y,
7772
- };
7776
+ return (React.createElement(React.Fragment, null,
7777
+ PropDragDropHandlerElement && React.createElement(PropDragDropHandlerElement, { dragging: draggingRect, onMouseDown: addRectHandleMouseDown }),
7778
+ 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 }),
7779
+ propResizability.enabled ?
7780
+ (React.createElement("circle", { cursor: 'se-resize', cx: leftX + width, cy: topY + height, r: r, fill: 'blue', stroke: 'blue', onMouseDown: circleHandleMouseDown })) : null));
7781
+ };
7782
+
7783
+ var useSelectionFrame = function (props) {
7784
+ React.useEffect(function () {
7785
+ //log selection frame rendering
7786
+ if (props.targetSVGElement) {
7787
+ console.debug('Rendering SelectionFrame for targetSVGElement:', props.targetSVGElement);
7773
7788
  }
7774
7789
  else {
7775
- //Translate to the top of vertex 2
7776
- var topPosition = {
7777
- x: vertex2Position.x,
7778
- y: vertex2Position.y - translationOffset,
7779
- };
7780
- //Translate to the bottom of vertex 3
7781
- var bottomPosition = {
7782
- x: vertex3Position.x,
7783
- y: vertex3Position.y + translationOffset,
7784
- };
7785
- replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7790
+ console.warn('No targetSVGElement provided for SelectionFrame.');
7791
+ }
7792
+ if (props.targetSVGElement && props.container) {
7793
+ //render SelectionFrame component to the parent element of the targetSVGElement
7794
+ if (props.container) {
7795
+ var svg_1 = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
7796
+ svg_1.style.overflow = 'visible';
7797
+ svg_1.style.outline = 'none';
7798
+ props.targetSVGElement.appendChild(svg_1);
7799
+ var root_1 = createRoot(svg_1);
7800
+ root_1.render(React.createElement(SelectionFrame, __assign({}, props, { container: props.container })));
7801
+ return function () {
7802
+ root_1.unmount();
7803
+ if (props.targetSVGElement) {
7804
+ props.targetSVGElement.removeChild(svg_1);
7805
+ }
7806
+ };
7807
+ }
7786
7808
  }
7787
- }
7788
- return replacementPosition;
7809
+ }, [props]);
7810
+ };
7811
+
7812
+ var eventEmitter = new EventEmitter();
7813
+ var emitPaperClicked = function (ev) {
7814
+ eventEmitter.emit(EVENT_NAME.PAPER_CLICK, ev);
7789
7815
  };
7790
- var getRelativePosition = function (clientPosition, relativeElement) {
7791
- var relativeRect = relativeElement.getBoundingClientRect();
7816
+ var onPaperClicked = function (callback) {
7817
+ eventEmitter.on(EVENT_NAME.PAPER_CLICK, callback);
7818
+ var off = function () {
7819
+ eventEmitter.off(EVENT_NAME.PAPER_CLICK, callback);
7820
+ };
7792
7821
  return {
7793
- x: clientPosition.x - relativeRect.left,
7794
- y: clientPosition.y - relativeRect.top,
7822
+ off: off
7795
7823
  };
7796
7824
  };
7797
- var getFourVertexesOfBBoxFromElement = function (element) {
7798
- var absolutePosition = getAbsolutePosition(element);
7799
- var vertex1Position = {
7800
- x: absolutePosition.x,
7801
- y: absolutePosition.y
7825
+ var emitPortMouseUp = function (ev, port, elementId) {
7826
+ eventEmitter.emit(EVENT_NAME.PORT_MOUSE_UP, ev, port, elementId);
7827
+ };
7828
+ var onPortMouseUp = function (callback) {
7829
+ eventEmitter.on(EVENT_NAME.PORT_MOUSE_UP, callback);
7830
+ var off = function () {
7831
+ eventEmitter.off(EVENT_NAME.PORT_MOUSE_UP, callback);
7802
7832
  };
7803
- var vertex2Position = {
7804
- x: absolutePosition.x + element.size.width,
7805
- y: absolutePosition.y
7833
+ return {
7834
+ off: off
7806
7835
  };
7807
- var vertex3Position = {
7808
- x: absolutePosition.x + element.size.width,
7809
- y: absolutePosition.y + element.size.height
7836
+ };
7837
+ var emitPortMouseDown = function (ev, port, elementId) {
7838
+ eventEmitter.emit(EVENT_NAME.PORT_MOUSE_DOWN, ev, port, elementId);
7839
+ };
7840
+ var onPortMouseDown = function (callback) {
7841
+ eventEmitter.on(EVENT_NAME.PORT_MOUSE_DOWN, callback);
7842
+ var off = function () {
7843
+ eventEmitter.off(EVENT_NAME.PORT_MOUSE_DOWN, callback);
7810
7844
  };
7811
- var vertex4Position = {
7812
- x: absolutePosition.x,
7813
- y: absolutePosition.y + element.size.height
7845
+ return {
7846
+ off: off
7814
7847
  };
7815
- return [vertex1Position, vertex2Position, vertex3Position, vertex4Position];
7816
7848
  };
7817
- //get absolute position of element
7818
- var getAbsolutePosition = function (element) {
7819
- var parentElement = element.parentElement;
7820
- var elemenetPositionWithTopLeftAnchor = {
7821
- x: element.position.x,
7822
- y: element.position.y,
7849
+ var emitPortMoved = function (port, elementId, oldPosition, newPosition) {
7850
+ eventEmitter.emit(EVENT_NAME.PORT_MOVED, port, elementId, oldPosition, newPosition);
7851
+ };
7852
+ var onPortMoved = function (callback) {
7853
+ eventEmitter.on(EVENT_NAME.PORT_MOVED, callback);
7854
+ var off = function () {
7855
+ eventEmitter.off(EVENT_NAME.PORT_MOVED, callback);
7823
7856
  };
7824
- if (element.positionAnchor === exports.PositioningAnchor.Center) {
7825
- elemenetPositionWithTopLeftAnchor.x -= element.size.width / 2;
7826
- elemenetPositionWithTopLeftAnchor.y -= element.size.height / 2;
7827
- }
7828
- if (!parentElement) {
7829
- return __assign({}, elemenetPositionWithTopLeftAnchor);
7830
- }
7831
- var absoluteParentElement = getAbsolutePosition(parentElement);
7832
- var x = elemenetPositionWithTopLeftAnchor.x + absoluteParentElement.x;
7833
- var y = elemenetPositionWithTopLeftAnchor.y + absoluteParentElement.y;
7834
7857
  return {
7835
- x: x,
7836
- y: y,
7858
+ off: off
7837
7859
  };
7838
7860
  };
7839
- //get absolute position of element
7840
- var getPortAbsolutePosition = function (port, element) {
7841
- var elementAbsolutePosition = getAbsolutePosition(element);
7861
+ var emitElementMoved = function (element, oldPosition, newPosition) {
7862
+ eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(element.id));
7863
+ };
7864
+ var onElementMoved = function (elementId, callback) {
7865
+ eventEmitter.on("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
7866
+ var off = function () {
7867
+ eventEmitter.off("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
7868
+ };
7842
7869
  return {
7843
- x: elementAbsolutePosition.x + port.position.x,
7844
- y: elementAbsolutePosition.y + port.position.y,
7870
+ off: off
7845
7871
  };
7846
7872
  };
7847
- var transformAbsPositionToElementRelativePosition = function (position, element) {
7848
- var parentElement = element.parentElement;
7849
- if (!parentElement) {
7850
- return position;
7851
- }
7852
- var absoluteParentElement = getAbsolutePosition(parentElement);
7853
- var result = {
7854
- x: position.x - absoluteParentElement.x,
7855
- y: position.y - absoluteParentElement.y,
7873
+ var emitElementResized = function (element, oldSize, newSize) {
7874
+ eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(element.id), oldSize, newSize);
7875
+ };
7876
+ var onElementResized = function (elementId, callback) {
7877
+ eventEmitter.on("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
7878
+ var off = function () {
7879
+ eventEmitter.off("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
7880
+ };
7881
+ return {
7882
+ off: off
7856
7883
  };
7857
- if (element.positionAnchor === exports.PositioningAnchor.Center) {
7858
- result.x += element.size.width / 2;
7859
- result.y += element.size.height / 2;
7860
- }
7861
- return result;
7862
7884
  };
7863
- var transformAbsPositionToRelativePositionInsideElement = function (absolutePosition, parentAbsolutePosition) {
7864
- var _a, _b;
7865
- var position = {
7866
- x: absolutePosition.x - ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0),
7867
- y: absolutePosition.y - ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0),
7885
+ var emitCommandDeleteSelectedPort = function () {
7886
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT);
7887
+ };
7888
+ var onCommandDeleteSelectedPort = function (callback) {
7889
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
7890
+ var off = function () {
7891
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
7892
+ };
7893
+ return {
7894
+ off: off
7895
+ };
7896
+ };
7897
+ var emitCommandDeleteSelectedElement = function () {
7898
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT);
7899
+ };
7900
+ var onCommandDeleteSelectedElement = function (callback) {
7901
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
7902
+ var off = function () {
7903
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
7904
+ };
7905
+ return {
7906
+ off: off
7907
+ };
7908
+ };
7909
+ var emitCommandDeleteSelectedLink = function () {
7910
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK);
7911
+ };
7912
+ var onCommandDeleteSelectedLink = function (callback) {
7913
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
7914
+ var off = function () {
7915
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
7916
+ };
7917
+ return {
7918
+ off: off
7919
+ };
7920
+ };
7921
+ var emitCommandDeleteSelectedText = function () {
7922
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT);
7923
+ };
7924
+ var onCommandDeleteSelectedText = function (callback) {
7925
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
7926
+ var off = function () {
7927
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
7928
+ };
7929
+ return {
7930
+ off: off
7931
+ };
7932
+ };
7933
+ var emitElementLinkStarted = function (elementLink) {
7934
+ eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_STARTED, elementLink);
7935
+ };
7936
+ var onElementLinkStarted = function (callback) {
7937
+ eventEmitter.on(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
7938
+ var off = function () {
7939
+ eventEmitter.off(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
7940
+ };
7941
+ return {
7942
+ off: off
7943
+ };
7944
+ };
7945
+ var emitElementLinkEnded = function (elementLink) {
7946
+ eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_ENDED, elementLink);
7947
+ };
7948
+ var onElementLinkEnded = function (callback) {
7949
+ eventEmitter.on(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
7950
+ var off = function () {
7951
+ eventEmitter.off(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
7952
+ };
7953
+ return {
7954
+ off: off
7955
+ };
7956
+ };
7957
+ var emitElementSelected = function (element) {
7958
+ eventEmitter.emit(EVENT_NAME.ELEMENT_SELECTED, element);
7959
+ };
7960
+ var onElementSelected = function (callback) {
7961
+ eventEmitter.on(EVENT_NAME.ELEMENT_SELECTED, callback);
7962
+ var off = function () {
7963
+ eventEmitter.off(EVENT_NAME.ELEMENT_SELECTED, callback);
7964
+ };
7965
+ return {
7966
+ off: off
7967
+ };
7968
+ };
7969
+ var emitCommandRenderElement = function (elementId) {
7970
+ eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_ELEMENT, elementId);
7971
+ };
7972
+ var onCommandRenderElement = function (callback) {
7973
+ eventEmitter.on(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
7974
+ var off = function () {
7975
+ eventEmitter.off(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
7976
+ };
7977
+ return {
7978
+ off: off
7979
+ };
7980
+ };
7981
+ var emitPortSelected = function (port, elementId) {
7982
+ eventEmitter.emit(EVENT_NAME.PORT_SELECTED, port, elementId);
7983
+ };
7984
+ var onPortSelected = function (callback) {
7985
+ eventEmitter.on(EVENT_NAME.PORT_SELECTED, callback);
7986
+ var off = function () {
7987
+ eventEmitter.off(EVENT_NAME.PORT_SELECTED, callback);
7988
+ };
7989
+ return {
7990
+ off: off
7991
+ };
7992
+ };
7993
+ var emitCommandRenderPort = function (portId, elementId) {
7994
+ eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_PORT, portId, elementId);
7995
+ };
7996
+ var onCommandRenderPort = function (callback) {
7997
+ eventEmitter.on(EVENT_NAME.COMMAND_RENDER_PORT, callback);
7998
+ var off = function () {
7999
+ eventEmitter.off(EVENT_NAME.COMMAND_RENDER_PORT, callback);
8000
+ };
8001
+ return {
8002
+ off: off
8003
+ };
8004
+ };
8005
+ var emitTextSelected = function (text) {
8006
+ eventEmitter.emit(EVENT_NAME.TEXT_SELECTED, text);
8007
+ };
8008
+ var onTextSelected = function (callback) {
8009
+ eventEmitter.on(EVENT_NAME.TEXT_SELECTED, callback);
8010
+ var off = function () {
8011
+ eventEmitter.off(EVENT_NAME.TEXT_SELECTED, callback);
7868
8012
  };
7869
- return position;
7870
- };
7871
- var correctPortPositionInElement = function (elementRelativePosition, elementWidth, elementHeight, portMoveableAreas, portSlideRailSVGClassName, element) {
7872
- //Normalize a point so that it can lie exactly on an area
7873
- var normalizePortPositionOnMoveableAreas = function (moveableAreas, position) {
7874
- var lines = moveableAreas.filter(function (area) { return area.length === 2; });
7875
- var polygons = moveableAreas.filter(function (area) { return area.length >= 3; });
7876
- var normalizedPosition;
7877
- //If moveableAreas is lines
7878
- if (lines.length > 0) {
7879
- var newPosition_1 = findNearestProjectedPoint({ x: position.x, y: position.y }, lines);
7880
- if (newPosition_1) {
7881
- normalizedPosition = newPosition_1;
7882
- }
7883
- }
7884
- //If moveableAreas is polygons
7885
- else if (polygons.length > 0) {
7886
- var newPosition_2 = { x: position.x, y: position.y };
7887
- var isContainsInPolygons = polygons.some(function (p) { return checkPointContainsPolygon(newPosition_2, p); });
7888
- if (isContainsInPolygons) {
7889
- normalizedPosition = newPosition_2;
7890
- }
7891
- }
7892
- return normalizedPosition;
8013
+ return {
8014
+ off: off
7893
8015
  };
7894
- var getSlideRailSVG = function (portSlideRailSVGClassName) {
7895
- if (!element)
8016
+ };
8017
+ var paperEventEmitterContext = React.createContext({
8018
+ emitter: eventEmitter,
8019
+ emitPaperClicked: emitPaperClicked,
8020
+ onPaperClicked: onPaperClicked,
8021
+ emitPortMouseUp: emitPortMouseUp,
8022
+ onPortMouseUp: onPortMouseUp,
8023
+ emitPortMouseDown: emitPortMouseDown,
8024
+ onPortMouseDown: onPortMouseDown,
8025
+ emitPortMoved: emitPortMoved,
8026
+ onPortMoved: onPortMoved,
8027
+ emitPortSelected: emitPortSelected,
8028
+ onPortSelected: onPortSelected,
8029
+ emitElementMoved: emitElementMoved,
8030
+ onElementMoved: onElementMoved,
8031
+ emitElementResized: emitElementResized,
8032
+ onElementResized: onElementResized,
8033
+ emitElementSelected: emitElementSelected,
8034
+ onElementSelected: onElementSelected,
8035
+ emitCommandRenderElement: emitCommandRenderElement,
8036
+ onCommandRenderElement: onCommandRenderElement,
8037
+ emitCommandDeleteSelectedPort: emitCommandDeleteSelectedPort,
8038
+ onCommandDeleteSelectedPort: onCommandDeleteSelectedPort,
8039
+ emitCommandDeleteSelectedElement: emitCommandDeleteSelectedElement,
8040
+ onCommandDeleteSelectedElement: onCommandDeleteSelectedElement,
8041
+ emitCommandDeleteSelectedLink: emitCommandDeleteSelectedLink,
8042
+ onCommandDeleteSelectedLink: onCommandDeleteSelectedLink,
8043
+ emitCommandDeleteSelectedText: emitCommandDeleteSelectedText,
8044
+ onCommandDeleteSelectedText: onCommandDeleteSelectedText,
8045
+ emitElementLinkStarted: emitElementLinkStarted,
8046
+ onElementLinkStarted: onElementLinkStarted,
8047
+ emitElementLinkEnded: emitElementLinkEnded,
8048
+ onElementLinkEnded: onElementLinkEnded,
8049
+ emitTextSelected: emitTextSelected,
8050
+ onTextSelected: onTextSelected,
8051
+ emitCommandRenderPort: emitCommandRenderPort,
8052
+ onCommandRenderPort: onCommandRenderPort,
8053
+ });
8054
+
8055
+ var editorConfigurationContext = React.createContext(null);
8056
+ var useEditorConfiguration = function () {
8057
+ var context = React.useContext(editorConfigurationContext);
8058
+ if (!context) {
8059
+ throw new Error("useEditorConfiguration must be used within an EditorConfigurationProvider");
8060
+ }
8061
+ return context;
8062
+ };
8063
+ var EditorConfigurationContextProvider = editorConfigurationContext.Provider;
8064
+
8065
+ /**
8066
+ * Zoom context to manage zoom level and related state.
8067
+ * This context can be used to provide zoom functionality across the application.
8068
+ */
8069
+ var zoomContext = React.createContext(null);
8070
+ var ZoomContextProvider = function (_a) {
8071
+ var children = _a.children;
8072
+ var _b = React.useState(1), zoom = _b[0], setZoom = _b[1];
8073
+ var _c = React.useState(0), scrollLeft = _c[0], setScrollLeft = _c[1];
8074
+ var _d = React.useState(0), scrollTop = _d[0], setScrollTop = _d[1];
8075
+ var wrapperRef = React.useRef(null);
8076
+ var contentRef = React.useRef(null);
8077
+ var handleWheel = function (e) {
8078
+ // Chỉ zoom khi giữ Ctrl
8079
+ if (!e.ctrlKey)
7896
8080
  return;
7897
- var slideRailSVG = element.querySelector(".".concat(portSlideRailSVGClassName));
7898
- return slideRailSVG;
8081
+ e.preventDefault();
8082
+ var delta = -e.deltaY;
8083
+ var zoomFactor = 0.05;
8084
+ var newZoom = zoom + (delta > 0 ? zoomFactor : -zoomFactor);
8085
+ newZoom = Math.max(0.1, Math.min(newZoom, 4));
8086
+ if (!wrapperRef.current || !contentRef.current)
8087
+ return;
8088
+ var wrapper = wrapperRef.current;
8089
+ var content = contentRef.current;
8090
+ // Get bounding rectangle of the content
8091
+ var rect = content.getBoundingClientRect();
8092
+ var offsetX = e.clientX - rect.left;
8093
+ var offsetY = e.clientY - rect.top;
8094
+ var percentX = offsetX / (content.offsetWidth);
8095
+ var percentY = offsetY / (content.offsetHeight);
8096
+ console.log(offsetX, offsetY, content.offsetWidth, content.offsetHeight, percentX, percentY);
8097
+ // Old width and height of content
8098
+ var prevWidth = content.offsetWidth * zoom;
8099
+ var prevHeight = content.offsetHeight * zoom;
8100
+ var newWidth = content.offsetWidth * newZoom;
8101
+ var newHeight = content.offsetHeight * newZoom;
8102
+ var scrollLeft = wrapper.scrollLeft + (percentX * (newWidth - prevWidth));
8103
+ var scrollTop = wrapper.scrollTop + (percentY * (newHeight - prevHeight));
8104
+ setZoom(newZoom);
8105
+ setScrollLeft(scrollLeft);
8106
+ setScrollTop(scrollTop);
7899
8107
  };
7900
- //Calculate the position of the 4 vertices of a rectangle relative to element
7901
- var calculateSlideRailRectSVGPositions = function (slideRailSVG) {
7902
- var coordinates = getRectangleCorners(slideRailSVG);
7903
- var ownerSVG = slideRailSVG.ownerSVGElement;
7904
- var rotationAngle = getElementRotationInfo(ownerSVG);
7905
- if (rotationAngle !== 0) {
7906
- var rotationCenterX = elementWidth / 2;
7907
- var rotationCenterY = elementHeight / 2;
7908
- coordinates = getRotatedRectangleCoordinates(coordinates, rotationCenterX, rotationCenterY, rotationAngle);
7909
- }
7910
- return coordinates;
8108
+ React.useLayoutEffect(function () {
8109
+ var _a;
8110
+ (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({
8111
+ left: scrollLeft,
8112
+ top: scrollTop,
8113
+ });
8114
+ }, [zoom, scrollLeft, scrollTop]);
8115
+ var resetZoom = function () {
8116
+ setZoom(1);
7911
8117
  };
7912
- var normalizePortPositionOnSlideRailSVG = function (portSlideRailSVGClassName, position) {
7913
- var slideRailSVG = getSlideRailSVG(portSlideRailSVGClassName);
7914
- if (!slideRailSVG)
7915
- return;
7916
- var moveTo;
7917
- //check and get new position if Rect element
7918
- if (slideRailSVG instanceof SVGRectElement) {
7919
- var _a = calculateSlideRailRectSVGPositions(slideRailSVG), a = _a[0], b = _a[1], c = _a[2], d = _a[3]; //Get 4 vertices of rect element
7920
- var moveableAreas = [
7921
- [a, b],
7922
- [b, c],
7923
- [c, d],
7924
- [d, a]
7925
- ];
7926
- logger.info("Port's moveable areas parsed from svg ".concat(portSlideRailSVGClassName), moveableAreas);
7927
- var newPosition_3 = normalizePortPositionOnMoveableAreas(moveableAreas, position);
7928
- if (newPosition_3) {
7929
- moveTo = newPosition_3;
7930
- }
7931
- }
7932
- else if (slideRailSVG instanceof SVGCircleElement) { //check and get new position if circle element
7933
- var cx = Number(slideRailSVG.getAttribute('cx'));
7934
- var cy = Number(slideRailSVG.getAttribute('cy'));
7935
- var r = Number(slideRailSVG.getAttribute('r'));
7936
- var circle = Flatten$1.circle(Flatten$1.point(cx, cy), r);
7937
- var _b = circle.distanceTo(Flatten$1.point(position.x, position.y)), num = _b[0], segment = _b[1];
7938
- if (num <= r) {
7939
- moveTo = {
7940
- x: segment.ps.x,
7941
- y: segment.ps.y,
7942
- };
8118
+ React.useEffect(function () {
8119
+ var preventBrowserZoom = function (e) {
8120
+ if (e.ctrlKey || e.metaKey) {
8121
+ e.preventDefault();
7943
8122
  }
7944
- }
7945
- return moveTo;
7946
- };
7947
- var newPosition;
7948
- if (portMoveableAreas && portMoveableAreas.length > 0) { //If moveable areas is defined
7949
- newPosition = normalizePortPositionOnMoveableAreas(portMoveableAreas, elementRelativePosition);
7950
- }
7951
- else if (portSlideRailSVGClassName) { //If port slide rail svg classname is defined
7952
- newPosition = normalizePortPositionOnSlideRailSVG(portSlideRailSVGClassName, elementRelativePosition);
8123
+ };
8124
+ window.addEventListener("wheel", preventBrowserZoom, { passive: false });
8125
+ return function () {
8126
+ window.removeEventListener("wheel", preventBrowserZoom);
8127
+ };
8128
+ }, []);
8129
+ return (React.createElement(zoomContext.Provider, { value: { zoom: zoom, setZoom: setZoom, resetZoom: resetZoom } },
8130
+ React.createElement("div", { ref: wrapperRef, onWheel: handleWheel, style: {
8131
+ width: "100vw",
8132
+ height: "92vh",
8133
+ overflow: "auto",
8134
+ } },
8135
+ React.createElement("div", { ref: contentRef, style: {
8136
+ transform: "scale(".concat(zoom, ")"),
8137
+ transformOrigin: "top left",
8138
+ // transition: "transform 0.1s linear",
8139
+ } }, children))));
8140
+ };
8141
+ var useZoomContext = function () {
8142
+ var context = React.useContext(zoomContext);
8143
+ if (!context) {
8144
+ throw new Error("useZoomContext must be used within a ZoomContextProvider");
7953
8145
  }
7954
- return newPosition || elementRelativePosition;
8146
+ return context;
7955
8147
  };
7956
8148
 
7957
- var Port1 = React.forwardRef(function (props, ref) {
7958
- 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,
7959
- // onManuallyTriggerRenderHandler,
7960
- renderShape = props.renderShape, children = props.children;
7961
- var textRef = React.useRef(null);
7962
- var rotationAngle = React.useMemo(function () {
7963
- if (!calculateRotationAngle)
7964
- return 0;
7965
- return calculateRotationAngle(x, y);
7966
- }, [calculateRotationAngle, x, y]);
7967
- var renderLabel = function (label) {
7968
- var content = label.content, size = label.size;
7969
- var position = label.position || PORT_LABEL_POSITION;
7970
- 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) {
7971
- if (onPortLabelMoved) {
7972
- var relativePosInSideEle = transformAbsPositionToRelativePositionInsideElement({ x: xOnPaper, y: yOnPaper }, parentAbsolutePosition);
7973
- var newXPort = relativePosInSideEle.x - x;
7974
- var newYPort = relativePosInSideEle.y - y;
7975
- onPortLabelMoved(newXPort, newYPort, id);
7976
- }
7977
- }, 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); } });
7978
- };
7979
- var renderedShape = React.useMemo(function () {
7980
- if (renderShape) {
7981
- var RenderShape = renderShape;
7982
- return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle }), children));
7983
- }
7984
- else {
7985
- 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);
7986
- }
7987
- }, [props]);
7988
- return (React.createElement(React.Fragment, null,
7989
- renderedShape,
7990
- label && renderLabel(label)));
7991
- });
7992
- var Port = React.memo(Port1);
7993
-
7994
- // Render the svg <path> element
7995
- function getCurvePathData(points, smoothing, closed) {
7996
- if (smoothing === void 0) { smoothing = 0.2; }
7997
- // append first 2 points for closed paths
7998
- if (closed) {
7999
- points = points.concat(points.slice(0, 2));
8000
- }
8001
- // Properties of a line
8002
- var line = function (pointA, pointB) {
8003
- var lengthX = pointB.x - pointA.x;
8004
- var lengthY = pointB.y - pointA.y;
8149
+ var Text = React.forwardRef(function (_a, ref) {
8150
+ 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;
8151
+ var _d = React.useState(false), isSelected = _d[0], setIsSelected = _d[1];
8152
+ var _e = React.useState(false), isEditing = _e[0], setIsEditing = _e[1];
8153
+ var textFontSize = useEditorConfiguration().textFontSize;
8154
+ var zoom = useZoomContext().zoom;
8155
+ var absolutePosition = React.useMemo(function () {
8156
+ var _a, _b;
8005
8157
  return {
8006
- length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
8007
- angle: Math.atan2(lengthY, lengthX)
8158
+ x: ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0) + x,
8159
+ y: ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0) + y,
8008
8160
  };
8009
- };
8010
- // Position of a control point
8011
- var controlPoint = function (current, previous, next, reverse) {
8012
- var p = previous || current;
8013
- var n = next || current;
8014
- var o = line(p, n);
8015
- var angle = o.angle + (reverse ? Math.PI : 0);
8016
- var length = o.length * smoothing;
8017
- var x = current.x + Math.cos(angle) * length;
8018
- var y = current.y + Math.sin(angle) * length;
8019
- return { x: x, y: y };
8020
- };
8021
- var pathData = [];
8022
- pathData.push({ type: "M", values: [points[0].x, points[0].y] });
8023
- for (var i = 1; i < points.length; i++) {
8024
- var point = points[i];
8025
- var cp1 = controlPoint(points[i - 1], points[i - 2], point);
8026
- var cp2 = controlPoint(point, points[i - 1], points[i + 1], true);
8027
- var command = {
8028
- type: "C",
8029
- values: [cp1.x, cp1.y, cp2.x, cp2.y, point.x, point.y]
8161
+ }, [x, y, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y]);
8162
+ var svgRef = React.useRef();
8163
+ var _f = React.useContext(paperEventEmitterContext), onPaperClicked = _f.onPaperClicked, emitTextSelected = _f.emitTextSelected, onPortSelected = _f.onPortSelected, onElementSelected = _f.onElementSelected, onTextSelected = _f.onTextSelected;
8164
+ React.useEffect(function () {
8165
+ var paperClickListener = onPaperClicked(function (ev) {
8166
+ var _a;
8167
+ var textareaELe = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('textarea');
8168
+ if (ev.target !== textareaELe) {
8169
+ setIsSelected(false);
8170
+ setIsEditing(false);
8171
+ }
8172
+ });
8173
+ var portSelectedListener = onPortSelected(function (port) {
8174
+ setIsSelected(false);
8175
+ setIsEditing(false);
8176
+ });
8177
+ var elementSelectedListener = onElementSelected(function (element) {
8178
+ setIsSelected(false);
8179
+ setIsEditing(false);
8180
+ });
8181
+ var textSelectedListener = onTextSelected(function (text) {
8182
+ if (text.id !== id) {
8183
+ setIsSelected(false);
8184
+ setIsEditing(false);
8185
+ }
8186
+ });
8187
+ return function () {
8188
+ paperClickListener.off();
8189
+ portSelectedListener.off();
8190
+ elementSelectedListener.off();
8191
+ textSelectedListener.off();
8030
8192
  };
8031
- pathData.push(command);
8032
- }
8033
- // copy last commands 1st controlpoint to first curveto
8034
- if (closed) {
8035
- var comLast = pathData[pathData.length - 1];
8036
- var valuesLastC = comLast.values;
8037
- var valuesFirstC = pathData[1].values;
8038
- pathData[1] = {
8039
- type: "C",
8040
- values: [valuesLastC[0], valuesLastC[1], valuesFirstC.slice(2)].flat()
8193
+ }, []);
8194
+ //Handle click on svg element
8195
+ var handleClick = function (ev) {
8196
+ if (!selectable)
8197
+ return;
8198
+ ev.stopPropagation();
8199
+ var position = {
8200
+ x: x,
8201
+ y: y,
8041
8202
  };
8042
- // delete last curveto
8043
- pathData = pathData.slice(0, pathData.length - 1);
8044
- }
8045
- return pathData;
8046
- }
8047
- // convert pathdata to d attribute string
8048
- function pathDataToD(pathData, decimals) {
8049
- if (decimals === void 0) { decimals = 3; }
8050
- var d = pathData
8051
- .map(function (com) {
8052
- return "".concat(com.type).concat(com.values.map(function (value) { return +value.toFixed(decimals); }).join(" "));
8053
- })
8054
- .join(" ");
8055
- return d;
8056
- }
8057
- function createSmoothPathString(points, smoothing, close) {
8058
- var pathData = getCurvePathData(points, smoothing, close);
8059
- var pathString = pathDataToD(pathData);
8060
- return pathString;
8061
- }
8062
- // a helper function to measure the distance between 2 points
8063
- function dist(p1, p2) {
8064
- var dx = p2.x - p1.x;
8065
- var dy = p2.y - p1.y;
8066
- return Math.sqrt(dx * dx + dy * dy);
8067
- }
8068
- //find distance from starting point of path to a point
8069
- function getLengthForPoint(p, thePath, precision) {
8070
- if (precision === void 0) { precision = 50; }
8071
- var pathLength = thePath.getTotalLength();
8072
- var theRecord = pathLength; //length of path
8073
- var division = pathLength / precision;
8074
- var theSegment;
8075
- for (var i = 0; i < precision; i++) {
8076
- // get a point on the path for thia distance
8077
- var _p = thePath.getPointAtLength(i * division);
8078
- // get the distance between the new point _p and the point p
8079
- var theDistance = dist(_p, p);
8080
- if (theDistance < theRecord) {
8081
- // if the distance is smaller than the record set the new record
8082
- theRecord = theDistance;
8083
- theSegment = i;
8084
- }
8085
- }
8086
- return (theSegment * division);
8087
- }
8088
- //Add points to the list of points in the correct position
8089
- function addPointToList(point, listPoints, path) {
8090
- var getAddIndex = function (startIndex, endIndex) {
8091
- //Add in the middle if there are only 2 points
8092
- if ((endIndex - startIndex) === 1) {
8093
- return startIndex + 1;
8094
- }
8095
- var middleIndex = Math.ceil((startIndex + endIndex) / 2);
8096
- var lengthOfMiddlePoint = getLengthForPoint(listPoints[middleIndex], path); //distance from start point to mid point
8097
- var lengthOfAddedPoint = getLengthForPoint(point, path); //distance from adding point to mid point
8098
- //compare if lengthOfMiddlePoint is less than lengthOfAddedPoint,
8099
- //then new point can be added in the range of mid point to end point,
8100
- //otherwise it can be added in the range of start point to middle point.
8101
- if (lengthOfAddedPoint < lengthOfMiddlePoint) {
8102
- return getAddIndex(startIndex, middleIndex);
8103
- }
8104
- else {
8105
- return getAddIndex(middleIndex, endIndex);
8106
- }
8203
+ var text = {
8204
+ id: id,
8205
+ content: content,
8206
+ position: position,
8207
+ size: {
8208
+ width: width,
8209
+ height: height,
8210
+ },
8211
+ editable: editable
8212
+ };
8213
+ setIsSelected(true);
8214
+ onSelected && onSelected(text);
8215
+ emitTextSelected(text);
8107
8216
  };
8108
- var addedIndex = getAddIndex(0, listPoints.length - 1);
8109
- listPoints.splice(addedIndex, 0, point);
8110
- return __spreadArray([], listPoints, true);
8111
- }
8112
- // Parse the d attribute of a path element and extract points from path commands
8113
- function getPointsFromPathData(dAttribute) {
8114
- var points = [];
8115
- // Remove extra whitespace and split by command letters
8116
- var cleanD = dAttribute.replace(/\s+/g, ' ').trim();
8117
- // Regular expression to match path commands (M, L, C, etc.) and their values
8118
- var commandRegex = /([MLCZmlcz])\s*([^MLCZmlcz]*)/g;
8119
- var match;
8120
- while ((match = commandRegex.exec(cleanD)) !== null) {
8121
- var command = match[1].toUpperCase();
8122
- var values = match[2].trim();
8123
- if (values) {
8124
- var coords = values.split(/[\s,]+/).map(Number).filter(function (num) { return !isNaN(num); });
8125
- switch (command) {
8126
- case 'M': // Move to
8127
- if (coords.length >= 2) {
8128
- points.push({ x: coords[0], y: coords[1] });
8129
- }
8130
- break;
8131
- case 'L': // Line to
8132
- if (coords.length >= 2) {
8133
- points.push({ x: coords[0], y: coords[1] });
8134
- }
8135
- break;
8136
- case 'C': // Cubic bezier curve
8137
- // For cubic curves, we take the end point (last 2 coordinates)
8138
- if (coords.length >= 6) {
8139
- points.push({ x: coords[4], y: coords[5] });
8140
- }
8141
- break;
8142
- case 'Q': // Quadratic bezier curve
8143
- // For quadratic curves, we take the end point (last 2 coordinates)
8144
- if (coords.length >= 4) {
8145
- points.push({ x: coords[2], y: coords[3] });
8146
- }
8147
- break;
8217
+ var handleChangeText = function (ev) {
8218
+ if (!editable)
8219
+ return;
8220
+ onContentChanged === null || onContentChanged === void 0 ? void 0 : onContentChanged(ev, ev.target.value);
8221
+ };
8222
+ useSelectionFrame({
8223
+ objectX: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.x,
8224
+ objectY: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.y,
8225
+ container: container,
8226
+ targetSVGElement: (isSelected && svgRef.current) ? svgRef.current : undefined,
8227
+ resizability: {
8228
+ enabled: onResized ? true : false,
8229
+ keepRatio: false,
8230
+ },
8231
+ onMove: onMoved,
8232
+ onResize: onResized,
8233
+ strokeWidth: 3,
8234
+ zoom: zoom,
8235
+ });
8236
+ var textAlign = React.useMemo(function () {
8237
+ switch (align) {
8238
+ case exports.TextAlign.left:
8239
+ return 'left';
8240
+ case exports.TextAlign.right:
8241
+ return 'right';
8242
+ case exports.TextAlign.center:
8243
+ return 'center';
8244
+ default:
8245
+ return 'left';
8246
+ }
8247
+ }, [align]);
8248
+ var fontSize = fontSizeProp || textFontSize || TEXT_FONT_SIZE;
8249
+ var borderStyle = border || 'none';
8250
+ return (React.createElement("svg", { style: {
8251
+ overflow: "visible",
8252
+ pointerEvents: selectable ? undefined : 'none',
8253
+ }, x: x, y: y, ref: function (node) {
8254
+ svgRef.current = node;
8255
+ if (typeof ref === 'function') {
8256
+ ref(node);
8257
+ }
8258
+ else if (ref) {
8259
+ ref.current = node;
8148
8260
  }
8261
+ }, onClick: handleClick },
8262
+ React.createElement("foreignObject", { width: width, height: height, style: {
8263
+ overflow: 'visible',
8264
+ userSelect: 'none',
8265
+ WebkitUserSelect: 'none',
8266
+ msUserSelect: 'none'
8267
+ } },
8268
+ React.createElement("div", { style: {
8269
+ width: '100%',
8270
+ height: '100%',
8271
+ borderWidth: '1px',
8272
+ borderColor: '#ccc',
8273
+ borderStyle: borderStyle,
8274
+ // whiteSpace: 'pre-wrap',
8275
+ boxSizing: 'border-box',
8276
+ } },
8277
+ React.createElement("textarea", { style: {
8278
+ fontFamily: 'initial',
8279
+ display: 'inline-block',
8280
+ width: '100%',
8281
+ height: '100%',
8282
+ overflow: 'hidden',
8283
+ border: 'none',
8284
+ background: 'transparent',
8285
+ outline: 'none',
8286
+ resize: 'none',
8287
+ textAlign: textAlign,
8288
+ fontSize: fontSize,
8289
+ }, readOnly: !isEditing, onDoubleClick: function () {
8290
+ if (editable) {
8291
+ setIsEditing(true);
8292
+ }
8293
+ }, value: content, onChange: handleChangeText })))));
8294
+ });
8295
+ var Text$1 = React.memo(Text);
8296
+
8297
+ var Port1 = React.forwardRef(function (props, ref) {
8298
+ 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, onContextMenu = props.onContextMenu,
8299
+ // onManuallyTriggerRenderHandler,
8300
+ renderShape = props.renderShape, children = props.children;
8301
+ var textRef = React.useRef(null);
8302
+ var rotationAngle = React.useMemo(function () {
8303
+ if (!calculateRotationAngle)
8304
+ return 0;
8305
+ return calculateRotationAngle(x, y);
8306
+ }, [calculateRotationAngle, x, y]);
8307
+ var renderLabel = function (label) {
8308
+ var content = label.content, size = label.size;
8309
+ var position = label.position || PORT_LABEL_POSITION;
8310
+ 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) {
8311
+ if (onPortLabelMoved) {
8312
+ var relativePosInSideEle = transformAbsPositionToRelativePositionInsideElement({ x: xOnPaper, y: yOnPaper }, parentAbsolutePosition);
8313
+ var newXPort = relativePosInSideEle.x - x;
8314
+ var newYPort = relativePosInSideEle.y - y;
8315
+ onPortLabelMoved(newXPort, newYPort, id);
8316
+ }
8317
+ }, 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); } });
8318
+ };
8319
+ var renderedShape = React.useMemo(function () {
8320
+ if (renderShape) {
8321
+ var RenderShape = renderShape;
8322
+ return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle, onContextMenu: function (e) { return onContextMenu === null || onContextMenu === void 0 ? void 0 : onContextMenu(id, e); } }), children));
8149
8323
  }
8150
- }
8151
- return points;
8152
- }
8153
- // Get points from a path element's d attribute
8154
- function getPointsFromPathElement(pathElement) {
8155
- var dAttribute = pathElement.getAttribute('d');
8156
- if (!dAttribute) {
8157
- return [];
8158
- }
8159
- return getPointsFromPathData(dAttribute);
8160
- }
8324
+ else {
8325
+ 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); }, onContextMenu: function (e) { return onContextMenu === null || onContextMenu === void 0 ? void 0 : onContextMenu(id, e); }, ref: ref, x: x, y: y, positioningAnchor: exports.PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" }, children);
8326
+ }
8327
+ }, [props]);
8328
+ return (React.createElement(React.Fragment, null,
8329
+ renderedShape,
8330
+ label && renderLabel(label)));
8331
+ });
8332
+ var Port = React.memo(Port1);
8161
8333
 
8162
8334
  //Defined remove icon for element link, shown when element link is selected.
8163
8335
  function CloseIcon(_a) {
@@ -8186,17 +8358,34 @@ var IElementLink = function (_a) {
8186
8358
  }), selectedLabelRef = _l[0], setSelectedLabelRef = _l[1];
8187
8359
  var _m = React.useState(false), isSelectedLink = _m[0], setIsSelectedLink = _m[1];
8188
8360
  var _o = React.useContext(paperEventEmitterContext), onPaperClicked = _o.onPaperClicked, onElementSelected = _o.onElementSelected;
8361
+ var zoom = useZoomContext().zoom;
8189
8362
  var pathRef = React.useRef(null);
8190
8363
  var labelRef = React.useRef(null);
8191
8364
  var sourceLabelRef = React.useRef(null);
8192
8365
  var targetLabelRef = React.useRef(null);
8193
8366
  var isFirstRender = React.useRef(true);
8194
8367
  var onPointsChangedRef = React.useRef();
8368
+ var lastUpdatedPoints = React.useRef(Date.now());
8195
8369
  var angleMarkerStart = '0';
8196
8370
  var angleMarkerEnd = '0';
8197
8371
  var markerStartPosition;
8198
8372
  var markerEndPosition;
8199
8373
  var centerPathPosition = undefined;
8374
+ // Throttle pointsProp updates to avoid excessive renders
8375
+ React.useEffect(function () {
8376
+ var delay = 100; // 100ms delay
8377
+ var timeoutId = setTimeout(function () {
8378
+ var now = Date.now();
8379
+ if (now - lastUpdatedPoints.current >= delay) {
8380
+ setPoints(pointsProp || []);
8381
+ lastUpdatedPoints.current = now;
8382
+ }
8383
+ }, delay - (Date.now() - lastUpdatedPoints.current));
8384
+ return function () {
8385
+ clearTimeout(timeoutId);
8386
+ };
8387
+ // Use JSON.stringify for deep comparison
8388
+ }, [JSON.stringify(pointsProp)]);
8200
8389
  React.useEffect(function () {
8201
8390
  var paperClickListener = onPaperClicked(function () {
8202
8391
  setSelectedLabelRef({
@@ -8248,10 +8437,13 @@ var IElementLink = function (_a) {
8248
8437
  var handleMouseMove = function (ev) {
8249
8438
  var mouseEvent = ev;
8250
8439
  if (isDragging && draggingPointIndex !== undefined && container) {
8251
- var offset_1 = getRelativePosition({ x: mouseEvent.clientX, y: mouseEvent.clientY }, container);
8440
+ var paperPosition_1 = windowsPositionToPaperPosition({
8441
+ x: mouseEvent.clientX,
8442
+ y: mouseEvent.clientY
8443
+ }, container, zoom);
8252
8444
  setPoints(function (prev) {
8253
8445
  var temp = __spreadArray([], prev, true);
8254
- temp[draggingPointIndex] = offset_1;
8446
+ temp[draggingPointIndex] = paperPosition_1;
8255
8447
  return temp;
8256
8448
  });
8257
8449
  }
@@ -8266,23 +8458,19 @@ var IElementLink = function (_a) {
8266
8458
  container === null || container === void 0 ? void 0 : container.removeEventListener('mousemove', handleMouseMove);
8267
8459
  container === null || container === void 0 ? void 0 : container.removeEventListener('mouseup', mouseUp);
8268
8460
  };
8269
- }, [container, isDragging, draggingPointIndex]);
8461
+ }, [container, isDragging, draggingPointIndex, zoom]);
8270
8462
  var handleMouseDownOnPath = function (ev) {
8271
8463
  ev.preventDefault();
8272
- var svgContainer = ev.target.ownerSVGElement;
8273
8464
  //add point if click on path
8274
8465
  setIsDragging(true);
8275
- var rect = svgContainer.getBoundingClientRect();
8276
- var offsetX = ev.clientX - rect.left;
8277
- var offsetY = ev.clientY - rect.top;
8278
8466
  //Position of the new point on the path
8279
- var newPoint = {
8280
- x: offsetX,
8281
- y: offsetY
8282
- };
8283
- var newPoints = addPointToList(newPoint, __spreadArray(__spreadArray([sourcePosition], points, true), [targetPosition], false), pathRef.current);
8467
+ var paperPosition = windowsPositionToPaperPosition({
8468
+ x: ev.clientX,
8469
+ y: ev.clientY
8470
+ }, container, zoom);
8471
+ var newPoints = addPointToList(paperPosition, __spreadArray(__spreadArray([sourcePosition], points, true), [targetPosition], false), pathRef.current);
8284
8472
  var pointsWithoutStartEndPoint = newPoints.slice(1, newPoints.length - 1);
8285
- var addedIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === newPoint.x && p.y === newPoint.y; });
8473
+ var addedIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === paperPosition.x && p.y === paperPosition.y; });
8286
8474
  var leftPointIndex = addedIndex - 1;
8287
8475
  var rightPointIndex = addedIndex + 1;
8288
8476
  var distFromLeftPoint;
@@ -8321,7 +8509,7 @@ var IElementLink = function (_a) {
8321
8509
  }
8322
8510
  }
8323
8511
  //Find new index of added point
8324
- _draggingPointIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === newPoint.x && p.y === newPoint.y; });
8512
+ _draggingPointIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === paperPosition.x && p.y === paperPosition.y; });
8325
8513
  setDraggingPointIndex(_draggingPointIndex);
8326
8514
  setPoints(pointsWithoutStartEndPoint);
8327
8515
  };
@@ -8436,62 +8624,6 @@ var IElementLink = function (_a) {
8436
8624
  };
8437
8625
  var ElementLink = React.memo(IElementLink);
8438
8626
 
8439
- var getSVGBBoxOutsideTransformedParent = function (svgElement) {
8440
- var bbox = svgElement.getBBox(); // Get bounding box of the element
8441
- var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
8442
- // Define the four corners of the bounding box
8443
- var corners = [
8444
- { x: bbox.x, y: bbox.y },
8445
- { x: bbox.x + bbox.width, y: bbox.y },
8446
- { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
8447
- { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
8448
- ];
8449
- // Function to apply the transformation matrix to a point
8450
- function transformPoint(x, y, matrix) {
8451
- return {
8452
- x: matrix.a * x + matrix.c * y + matrix.e,
8453
- y: matrix.b * x + matrix.d * y + matrix.f
8454
- };
8455
- }
8456
- // Transform each corner according to the matrix
8457
- if (matrix) {
8458
- return corners.map(function (corner) {
8459
- return transformPoint(corner.x, corner.y, matrix);
8460
- });
8461
- }
8462
- else {
8463
- return corners;
8464
- }
8465
- };
8466
- //function returns the array of corners of the bbox of the element after applying the transformation matrix of the parent element
8467
- var getRotatedSVGBBox = function (svgElement) {
8468
- var bbox = svgElement.getBBox(); // Get bounding box of the element
8469
- var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
8470
- // Define the four corners of the bounding box
8471
- var corners = [
8472
- { x: bbox.x, y: bbox.y },
8473
- { x: bbox.x + bbox.width, y: bbox.y },
8474
- { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
8475
- { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
8476
- ];
8477
- // Function to apply the transformation matrix to a point
8478
- function transformPoint(x, y, matrix) {
8479
- return {
8480
- x: matrix.a * x + matrix.c * y,
8481
- y: matrix.b * x + matrix.d * y // + matrix.f
8482
- };
8483
- }
8484
- // Transform each corner according to the matrix
8485
- if (matrix) {
8486
- return corners.map(function (corner) {
8487
- return transformPoint(corner.x, corner.y, matrix);
8488
- });
8489
- }
8490
- else {
8491
- return corners;
8492
- }
8493
- };
8494
-
8495
8627
  function configureLogger(_a) {
8496
8628
  var level = _a.level, customLogger = _a.customLogger;
8497
8629
  if (level !== undefined)
@@ -8541,13 +8673,14 @@ var ElementWrapper = React.forwardRef(function (_a, ref) {
8541
8673
  });
8542
8674
 
8543
8675
  var Element = React.forwardRef(function (props, forwardedRef) {
8544
- var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, cssClass = props.cssClass, portPlaceholderShape = props.portPlaceholderShape, children = props.children, container = props.container, parentAbsolutePosition = props.parentAbsolutePosition, textsPlaceHolderFlexStyle = props.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition = props.textsPlaceHolderFlexboxPosition, textsPlaceHolderClassName = props.textsPlaceHolderClassName, texts = props.texts, portSlideRailSVGClassName = props.portSlideRailSVGClassName, portMoveableAreas = props.portMoveableAreas, portDirection = props.portDirection, defaultPortSize = props.defaultPortSize, onClick = props.onClick, onContextMenu = props.onContextMenu, renderShape = props.renderShape; props.onMoved; var onPortMoved = props.onPortMoved; props.onResized; var onPortMouseDown = props.onPortMouseDown, onPortMouseUp = props.onPortMouseUp, onMouseMove = props.onMouseMove, onMouseLeave = props.onMouseLeave, onMouseUp = props.onMouseUp, onMouseDown = props.onMouseDown, onMouseUpAtLinkedPortPlaceholder = props.onMouseUpAtLinkedPortPlaceholder, onTextUpdated = props.onTextUpdated;
8676
+ var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, cssClass = props.cssClass, portPlaceholderShape = props.portPlaceholderShape, children = props.children, container = props.container, parentAbsolutePosition = props.parentAbsolutePosition, textsPlaceHolderFlexStyle = props.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition = props.textsPlaceHolderFlexboxPosition, textsPlaceHolderClassName = props.textsPlaceHolderClassName, texts = props.texts, portSlideRailSVGClassName = props.portSlideRailSVGClassName, portMoveableAreas = props.portMoveableAreas, portDirection = props.portDirection, defaultPortSize = props.defaultPortSize, onClick = props.onClick, onContextMenu = props.onContextMenu, renderShape = props.renderShape; props.onMoved; var onPortMoved = props.onPortMoved; props.onResized; var onPortMouseDown = props.onPortMouseDown, onPortMouseUp = props.onPortMouseUp, onMouseMove = props.onMouseMove, onMouseLeave = props.onMouseLeave, onMouseUp = props.onMouseUp, onMouseDown = props.onMouseDown, onMouseUpAtLinkedPortPlaceholder = props.onMouseUpAtLinkedPortPlaceholder, onTextUpdated = props.onTextUpdated, onPortContextMenu = props.onPortContextMenu; props.onPortsChanged;
8545
8677
  var _a = React.useState(), selectedPort = _a[0], setSelectedPort = _a[1];
8546
8678
  var _b = React.useState(), hoveredPort = _b[0], setHoveredPort = _b[1];
8547
8679
  var _c = React.useState([]), ports = _c[0], setPorts = _c[1];
8548
8680
  var _d = React.useState(false), someElementLinkStarted = _d[0], setSomeElementLinkStarted = _d[1];
8549
8681
  var _e = React.useState(), potentialPortPosition = _e[0], setPotentialPortPosition = _e[1];
8550
8682
  var _paperEventEmitterContext = React.useContext(paperEventEmitterContext);
8683
+ var zoom = useZoomContext().zoom;
8551
8684
  var elementRef = React.useRef(null);
8552
8685
  React.useImperativeHandle(forwardedRef, function () { return elementRef.current; });
8553
8686
  var elementLinkStarted = React.useRef();
@@ -8628,24 +8761,39 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8628
8761
  var eventListener = _paperEventEmitterContext.onPaperClicked(function (ev) {
8629
8762
  setSelectedPort(undefined);
8630
8763
  });
8764
+ return function () {
8765
+ eventListener.off();
8766
+ };
8767
+ }, []);
8768
+ //Normalize port position
8769
+ var normalizePortPosition = React.useCallback(function (tempNewPosition) {
8770
+ var newPosition = correctPortPositionInElement(tempNewPosition, width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current || undefined);
8771
+ return newPosition || tempNewPosition;
8772
+ }, [width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current]);
8773
+ React.useEffect(function () {
8631
8774
  //listen element resize to update position of the ports by element size.
8632
8775
  var eleResizeListener = _paperEventEmitterContext.onElementResized(id, function () {
8776
+ var _a;
8777
+ var isChanged = false;
8633
8778
  var newPorts = portsRef.current.map(function (port) {
8634
8779
  var newPosition = normalizePortPosition({ x: port.position.x, y: port.position.y });
8635
8780
  //Check port moved
8636
8781
  if (port.position.x !== newPosition.x || port.position.y !== newPosition.y) {
8637
- onPortMoved === null || onPortMoved === void 0 ? void 0 : onPortMoved(port, id, port.position, newPosition);
8782
+ isChanged = true;
8638
8783
  _paperEventEmitterContext.emitPortMoved(port, id, port.position, newPosition);
8639
8784
  }
8640
- return __assign(__assign({}, port), { position: newPosition });
8785
+ port.position = newPosition;
8786
+ return port;
8641
8787
  });
8642
8788
  setPorts(newPorts);
8789
+ if (isChanged) {
8790
+ (_a = props.onPortsChanged) === null || _a === void 0 ? void 0 : _a.call(props, newPorts, id);
8791
+ }
8643
8792
  });
8644
8793
  return function () {
8645
- eventListener.off();
8646
8794
  eleResizeListener.off();
8647
8795
  };
8648
- }, [onPortMoved]);
8796
+ }, [onPortMoved, normalizePortPosition, width, height, portMoveableAreas, portSlideRailSVGClassName]);
8649
8797
  //Listen creating element link started, ended.
8650
8798
  React.useEffect(function () {
8651
8799
  var elementStartedListener = _paperEventEmitterContext.onElementLinkStarted(function (tempLink) {
@@ -8718,11 +8866,6 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8718
8866
  var slideRailSVG = (_a = elementRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(".".concat(portSlideRailSVGClassName));
8719
8867
  return slideRailSVG;
8720
8868
  }, []);
8721
- //Normalize port position
8722
- var normalizePortPosition = function (tempNewPosition) {
8723
- var newPosition = correctPortPositionInElement(tempNewPosition, width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current || undefined);
8724
- return newPosition || tempNewPosition;
8725
- };
8726
8869
  var handlePortMove = function (newX, newY) {
8727
8870
  if (!selectedPort)
8728
8871
  return;
@@ -8815,24 +8958,17 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8815
8958
  setPotentialPortPosition(undefined);
8816
8959
  return;
8817
8960
  }
8818
- /* The above code is calculating the relative position of the mouse within a specific
8819
- element on the page. It first gets the bounding rectangle of the element using
8820
- `getBoundingClientRect()` and the bounding box of the element using `getBBox()`. Then,
8821
- it calculates the relative position of the mouse within the element by subtracting the
8822
- element's position from the mouse's position. The result is stored in the
8823
- `mousePositionOnElement` object, which contains the x and y coordinates of the mouse
8824
- relative to the element. */
8825
- var elementBounding = elementRef.current.getBoundingClientRect();
8826
- var elementBBox = elementRef.current.getBBox();
8827
- //Get relative position of mouse on element
8961
+ var paper = windowsPositionToPaperPosition({
8962
+ x: ev.clientX,
8963
+ y: ev.clientY
8964
+ }, container, zoom);
8965
+ var elementAbsPosition_1 = getElementAbsPosition();
8828
8966
  var mousePositionOnElement = {
8829
- x: ev.clientX - (elementBounding.left - elementBBox.x),
8830
- y: ev.clientY - (elementBounding.top - elementBBox.y),
8967
+ x: paper.x - elementAbsPosition_1.x,
8968
+ y: paper.y - elementAbsPosition_1.y,
8831
8969
  };
8832
8970
  var tempPotentialPortPosition = normalizePortPosition(mousePositionOnElement);
8833
- //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
8834
- //Nếu có thì cho nó là potentialPortPosition và hiện portPlaceholderShape
8835
- //Nếu không thì bỏ qua hoặc xóa potentialPortPosition.
8971
+ // Ensure the potential port position is within the element
8836
8972
  if (checkSamePosition(mousePositionOnElement, tempPotentialPortPosition, 5)) {
8837
8973
  setPotentialPortPosition(tempPotentialPortPosition);
8838
8974
  }
@@ -8876,6 +9012,14 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8876
9012
  if (someElementLinkStarted)
8877
9013
  setHoveredPort(undefined);
8878
9014
  }, [someElementLinkStarted]);
9015
+ //Handle when context menu is opened on port
9016
+ var handlePortContextMenu = React.useCallback(function (portId, e) {
9017
+ e.preventDefault();
9018
+ var port = portsRef.current.find(function (p) { return p.id === portId; });
9019
+ if (!port)
9020
+ return;
9021
+ onPortContextMenu === null || onPortContextMenu === void 0 ? void 0 : onPortContextMenu(port, id, e);
9022
+ }, [onPortContextMenu, id]);
8879
9023
  //Get rotate angle of port by port direction is defined.
8880
9024
  var rotatePort = React.useCallback(function (x, y) {
8881
9025
  // logger.info('calculating port rotation', x, y)
@@ -8916,7 +9060,7 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8916
9060
  break;
8917
9061
  }
8918
9062
  return rotationAngle;
8919
- }, [portSlideRailSVGClassName, portDirection, getSlideRailSVG]);
9063
+ }, [width, height, portSlideRailSVGClassName, portDirection, getSlideRailSVG, normalizePortPosition]);
8920
9064
  var renderedShape = React.useMemo(function () {
8921
9065
  if (renderShape)
8922
9066
  return renderShape(props);
@@ -8940,24 +9084,16 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8940
9084
  : React.createElement("rect", { x: potentialPortPosition.x - PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH / 2, y: potentialPortPosition.y - PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH / 2, width: PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH, height: PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH, rx: PORT_PLACEHOLDER_DEFAULT_SIZE, ry: PORT_PLACEHOLDER_DEFAULT_SIZE, stroke: PORT_PLACEHOLDER_DEFAULT_STROKE, fill: "none", strokeWidth: 3 })), ports === null || ports === void 0 ? void 0 :
8941
9085
  ports.map(function (p, index) {
8942
9086
  var _a, _b, _c, _d, _e, _f, _g, _h;
8943
- return React.createElement(Port, { key: p.id, ref: p.ref, id: p.id, x: p.position.x, y: p.position.y, parentAbsolutePosition: elementAbsPosition, width: (_c = (_b = (_a = p.size) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : defaultPortSize) !== null && _c !== void 0 ? _c : PORT_DEFAULT_SIZE, height: (_f = (_e = (_d = p.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : defaultPortSize) !== null && _f !== void 0 ? _f : PORT_DEFAULT_SIZE, container: container,
8944
- // rotation={rotatePort(p)}
8945
- calculateRotationAngle: rotatePort, label: p.label, onPortLabelMoved: handlePortLabelMoved, onPortLabelResized: handlePortLabelResized, onPortLabelContentChanged: handlePortLabelContentChanged, onSelected: handleSelectedPort, onMouseDown: handlePortMouseDown, onMouseUp: handlePortMouseUp, onMouseMove: handlePortMouseMove,
8946
- // onMouseEnter={() => {
8947
- // if (someElementLinkStarted) setHoveredPort(p)
8948
- // }}
8949
- onMouseLeave: handlePortMouseLeave,
8950
- // onManuallyTriggerRenderHandler={p.manuallyTriggerRenderHandler?.bind(p)}
8951
- renderShape: p.renderShape },
9087
+ return React.createElement(Port, { key: p.id, ref: p.ref, id: p.id, x: p.position.x, y: p.position.y, parentAbsolutePosition: elementAbsPosition, width: (_c = (_b = (_a = p.size) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : defaultPortSize) !== null && _c !== void 0 ? _c : PORT_DEFAULT_SIZE, height: (_f = (_e = (_d = p.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : defaultPortSize) !== null && _f !== void 0 ? _f : PORT_DEFAULT_SIZE, container: container, calculateRotationAngle: rotatePort, label: p.label, onPortLabelMoved: handlePortLabelMoved, onPortLabelResized: handlePortLabelResized, onPortLabelContentChanged: handlePortLabelContentChanged, onSelected: handleSelectedPort, onMouseDown: handlePortMouseDown, onMouseUp: handlePortMouseUp, onMouseMove: handlePortMouseMove, onMouseLeave: handlePortMouseLeave, onContextMenu: handlePortContextMenu, renderShape: p.renderShape },
8952
9088
  selectedPort && selectedPort.id === p.id && (hoveredPort === null || hoveredPort === void 0 ? void 0 : hoveredPort.id) !== p.id &&
8953
9089
  (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: {
8954
9090
  enabled: false,
8955
9091
  keepRatio: false
8956
- }, objectX: elementAbsPosition.x + selectedPort.position.x, objectY: elementAbsPosition.y + selectedPort.position.y, onMove: handlePortMove })),
9092
+ }, objectX: elementAbsPosition.x + selectedPort.position.x, objectY: elementAbsPosition.y + selectedPort.position.y, onMove: handlePortMove, zoom: zoom })),
8957
9093
  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: {
8958
9094
  enabled: false,
8959
9095
  keepRatio: false
8960
- } })));
9096
+ }, zoom: zoom })));
8961
9097
  }), texts === null || texts === void 0 ? void 0 :
8962
9098
  texts.map(function (t, index) {
8963
9099
  var _a, _b;
@@ -9280,6 +9416,8 @@ var Paper = function (props) {
9280
9416
  var _j = React.useState(null), selectedElementSVG = _j[0], setSelectedElementSVG = _j[1];
9281
9417
  var _k = React.useState(false), mouseDownedOnPaper = _k[0], setMouseDownedOnPaper = _k[1];
9282
9418
  var paperEventEmitter = React.useContext(paperEventEmitterContext);
9419
+ var zoom = useZoomContext().zoom;
9420
+ var zoomRef = React.useRef(zoom);
9283
9421
  var paperContainerRef = React.useRef(null);
9284
9422
  var tempLinkRef = React.useRef(tempLink); //Cache tempLink to avoid re-render when tempLink changed
9285
9423
  var elementsRef = React.useRef(elements); //Cache elements to avoid re-render when elements changed
@@ -9287,6 +9425,9 @@ var Paper = function (props) {
9287
9425
  var textsRef = React.useRef(texts); //Cache texts to avoid re-render when texts changed
9288
9426
  var size = props.size;
9289
9427
  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]);
9428
+ React.useEffect(function () {
9429
+ zoomRef.current = zoom;
9430
+ }, [zoom]);
9290
9431
  React.useEffect(function () {
9291
9432
  setElements(props.elements);
9292
9433
  }, [props.elements]);
@@ -9399,12 +9540,12 @@ var Paper = function (props) {
9399
9540
  updateElementsTree();
9400
9541
  }, [elements]);
9401
9542
  //Get all child elements of the deleted element
9402
- var getDeletedChildElements = function (deletedElement) {
9403
- if (!deletedElement.childrenElementsInTree)
9543
+ var getChildOfElement = function (element) {
9544
+ if (!element.childrenElementsInTree)
9404
9545
  return [];
9405
- var childElms = deletedElement.childrenElementsInTree;
9546
+ var childElms = element.childrenElementsInTree;
9406
9547
  var childOfChildElements = childElms.reduce(function (acc, ele) {
9407
- return __spreadArray(__spreadArray([], acc, true), getDeletedChildElements(ele), true);
9548
+ return __spreadArray(__spreadArray([], acc, true), getChildOfElement(ele), true);
9408
9549
  }, []);
9409
9550
  return __spreadArray(__spreadArray([], childElms, true), childOfChildElements, true);
9410
9551
  };
@@ -9413,7 +9554,8 @@ var Paper = function (props) {
9413
9554
  var _a;
9414
9555
  var listener = paperEventEmitter.onCommandDeleteSelectedElement(function () {
9415
9556
  if (selectedElement) {
9416
- var deletedChildElements = getDeletedChildElements(selectedElement);
9557
+ selectedElement.parentElement = undefined; //Remove parent element to avoid memory leak. This will remove the element from the parent element's childrenElements array.
9558
+ var deletedChildElements = getChildOfElement(selectedElement);
9417
9559
  var deletedElementIds_1 = __spreadArray(__spreadArray([], deletedChildElements, true), [selectedElement], false).map(function (e) { return e.id; });
9418
9560
  var prevElements = elementsRef.current;
9419
9561
  var newElements = prevElements.filter(function (e) { return !deletedElementIds_1.includes(e.id); });
@@ -9487,11 +9629,10 @@ var Paper = function (props) {
9487
9629
  }, [selectedText, props.onTextsChanged]);
9488
9630
  var handlePaperMouseMove = function (ev) {
9489
9631
  var _a;
9490
- var currentTarget = ev.currentTarget;
9491
- // Get the mouse position relative to the paper container
9492
- var paperRect = currentTarget.getBoundingClientRect();
9493
- var xPosOnPaper = ev.clientX - paperRect.left;
9494
- var yPosOnPaper = ev.clientY - paperRect.top;
9632
+ var _b = windowsPositionToPaperPosition({
9633
+ x: ev.clientX,
9634
+ y: ev.clientY
9635
+ }, paperContainerRef.current, zoom), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
9495
9636
  //if there is a temp link, update the temp target point
9496
9637
  if (tempLink) {
9497
9638
  var sourceElementAbsPosition = getAbsolutePosition(tempLink.sourceElement);
@@ -9514,15 +9655,14 @@ var Paper = function (props) {
9514
9655
  };
9515
9656
  var handleMouseDownOnPaper = function (ev) {
9516
9657
  var _a, _b;
9517
- var currentTarget = ev.currentTarget;
9518
- // Get the mouse position relative to the paper container
9519
- var paperRect = currentTarget.getBoundingClientRect();
9520
- var xPosOnPaper = ev.clientX - paperRect.left;
9521
- var yPosOnPaper = ev.clientY - paperRect.top;
9522
- setMouseDownedOnPaper(true);
9523
- (_a = props.onPaperClicked) === null || _a === void 0 ? void 0 : _a.call(props, {
9658
+ var _c = windowsPositionToPaperPosition({
9524
9659
  x: ev.clientX,
9525
9660
  y: ev.clientY
9661
+ }, paperContainerRef.current, zoom), xPosOnPaper = _c.x, yPosOnPaper = _c.y;
9662
+ setMouseDownedOnPaper(true);
9663
+ (_a = props.onPaperClicked) === null || _a === void 0 ? void 0 : _a.call(props, {
9664
+ x: xPosOnPaper,
9665
+ y: yPosOnPaper
9526
9666
  });
9527
9667
  paperEventEmitter.emitPaperClicked(ev);
9528
9668
  //broadcast mouse moved position to parent component
@@ -9533,11 +9673,11 @@ var Paper = function (props) {
9533
9673
  };
9534
9674
  var handleMouseUpOnPaper = function (ev) {
9535
9675
  var _a;
9536
- var currentTarget = ev.currentTarget;
9537
9676
  // Get the mouse position relative to the paper container
9538
- var paperRect = currentTarget.getBoundingClientRect();
9539
- var xPosOnPaper = ev.clientX - paperRect.left;
9540
- var yPosOnPaper = ev.clientY - paperRect.top;
9677
+ var _b = windowsPositionToPaperPosition({
9678
+ x: ev.clientX,
9679
+ y: ev.clientY
9680
+ }, paperContainerRef.current, zoom), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
9541
9681
  if (mouseDownedOnPaper) {
9542
9682
  setSelectedElement(undefined);
9543
9683
  setSelectedElementSVG(null);
@@ -9569,17 +9709,15 @@ var Paper = function (props) {
9569
9709
  props.onLinksChanged(newLinks);
9570
9710
  }
9571
9711
  }, [props.onLinksChanged, links]);
9572
- var handlePointsOfLinkChange = React.useCallback(function (points, id) {
9573
- //Update path of element link, that changed
9574
- // const prevLinks = linksRef.current;
9575
- var updatedLinkIndex = links.findIndex(function (l) { return l.id === id; });
9576
- links[updatedLinkIndex].points = points;
9577
- var newLinks = __spreadArray([], links, true);
9712
+ var handlePointsOfLinkChange = React.useCallback(function (points, linkId) {
9713
+ var newLinks = __spreadArray([], linksRef.current, true);
9714
+ var updatedLinkIndex = newLinks.findIndex(function (l) { return l.id === linkId; });
9715
+ newLinks[updatedLinkIndex].points = points;
9578
9716
  setLinks(newLinks);
9579
9717
  if (props.onLinksChanged) {
9580
9718
  props.onLinksChanged(newLinks);
9581
9719
  }
9582
- }, [props.onLinksChanged, links]);
9720
+ }, [props.onLinksChanged]);
9583
9721
  var handlePortMoved = React.useCallback(function (port, elementId, oldPosition, newPosition) {
9584
9722
  var _a;
9585
9723
  var element = elementsRef.current.find(function (e) { return e.id === elementId; });
@@ -9624,9 +9762,14 @@ var Paper = function (props) {
9624
9762
  var _a;
9625
9763
  ev.stopPropagation();
9626
9764
  var element = elementsRef.current.find(function (e) { return e.id === elementId; });
9765
+ var paperPosition = windowsPositionToPaperPosition({
9766
+ x: ev.clientX,
9767
+ y: ev.clientY
9768
+ }, paperContainerRef.current, zoomRef.current);
9769
+ console.log(paperPosition);
9627
9770
  //broadcast port mouse down to parent component
9628
9771
  if (element) {
9629
- (_a = props.onPortMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, port, element);
9772
+ (_a = props.onPortMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, port, element, paperPosition);
9630
9773
  }
9631
9774
  if (!tempLinkRef.current && element) {
9632
9775
  //handle create temp element link;
@@ -9659,9 +9802,13 @@ var Paper = function (props) {
9659
9802
  var _a;
9660
9803
  ev.stopPropagation();
9661
9804
  var element = elementsRef.current.find(function (e) { return e.id === elementId; });
9805
+ var paperPosition = windowsPositionToPaperPosition({
9806
+ x: ev.clientX,
9807
+ y: ev.clientY
9808
+ }, paperContainerRef.current, zoomRef.current);
9662
9809
  //broadcast port mouse down to parent component
9663
9810
  if (element) {
9664
- (_a = props.onPortMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, port, element);
9811
+ (_a = props.onPortMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, port, element, paperPosition);
9665
9812
  }
9666
9813
  //Create new element link, if has tempLink
9667
9814
  if (tempLinkRef.current) {
@@ -9904,6 +10051,14 @@ var Paper = function (props) {
9904
10051
  }
9905
10052
  setMouseDownedOnPaper(false);
9906
10053
  }, [paperEventEmitter]);
10054
+ var handlePortContextMenu = React.useCallback(function (port, elementId, e) {
10055
+ var _a;
10056
+ e.preventDefault();
10057
+ var element = elementsRef.current.find(function (e) { return e.id === elementId; });
10058
+ if (element) {
10059
+ (_a = props.onPortContextMenu) === null || _a === void 0 ? void 0 : _a.call(props, port, element, e);
10060
+ }
10061
+ }, [props.onPortContextMenu]);
9907
10062
  var handleContextMenu = React.useCallback(function (elementId, e, ref) {
9908
10063
  var _a;
9909
10064
  e.preventDefault();
@@ -9916,36 +10071,52 @@ var Paper = function (props) {
9916
10071
  var handleMouseUp = React.useCallback(function (ev, elementId) {
9917
10072
  var _a;
9918
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);
9919
10078
  if (element) {
9920
- (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10079
+ (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9921
10080
  }
9922
10081
  }, [props.onElementMouseUp]);
9923
10082
  var handleMouseDown = React.useCallback(function (ev, elementId) {
9924
10083
  var _a;
9925
10084
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10085
+ var paperPosition = windowsPositionToPaperPosition({
10086
+ x: ev.clientX,
10087
+ y: ev.clientY
10088
+ }, paperContainerRef.current, zoomRef.current);
9926
10089
  if (element) {
9927
- (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10090
+ (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9928
10091
  }
9929
10092
  }, [props.onElementMouseDown]);
9930
10093
  var handleMouseMove = React.useCallback(function (ev, elementId) {
9931
10094
  var _a;
9932
10095
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10096
+ var paperPosition = windowsPositionToPaperPosition({
10097
+ x: ev.clientX,
10098
+ y: ev.clientY
10099
+ }, paperContainerRef.current, zoomRef.current);
9933
10100
  if (element) {
9934
- (_a = props.onElementMouseMove) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10101
+ (_a = props.onElementMouseMove) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9935
10102
  }
9936
10103
  }, [props.onElementMouseMove]);
9937
10104
  var handleMouseLeave = React.useCallback(function (ev, elementId) {
9938
10105
  var _a;
9939
10106
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10107
+ var paperPosition = windowsPositionToPaperPosition({
10108
+ x: ev.clientX,
10109
+ y: ev.clientY
10110
+ }, paperContainerRef.current, zoomRef.current);
9940
10111
  if (element) {
9941
- (_a = props.onElementMouseLeave) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10112
+ (_a = props.onElementMouseLeave) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9942
10113
  }
9943
10114
  }, [props.onElementMouseLeave]);
9944
10115
  var renderElementInTree = React.useCallback(function (element) {
9945
10116
  //use the defined react element or the default Element component
9946
10117
  var ReactElement = element.reactElement || Element$1;
9947
10118
  return (React.createElement("g", { id: "group-of-element-".concat(element.id), key: element.id },
9948
- React.createElement(ReactElement, { key: "element-".concat(element.id), id: element.id, ref: function (refDOM) { return element.DOM = refDOM; }, height: element.size.height, width: element.size.width, x: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.x - element.size.width / 2 : element.position.x, y: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.y - element.size.height / 2 : element.position.y, onClick: handleElementClicked, onContextMenu: handleContextMenu, onMouseUp: handleMouseUp, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, container: paperContainerRef.current, renderShape: element.renderShape, cssClass: element.cssClass, texts: element.texts, ports: element.ports, portMoveableAreas: element.portMoveableAreas, portSlideRailSVGClassName: element.portSlideRailSVGClassName, portDirection: element.portDirection, defaultPortSize: element.defaultPortSize, onPortMoved: handlePortMoved, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortsChanged: handlePortsChanged,
10119
+ React.createElement(ReactElement, { key: "element-".concat(element.id), id: element.id, ref: function (refDOM) { return element.DOM = refDOM; }, height: element.size.height, width: element.size.width, x: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.x - element.size.width / 2 : element.position.x, y: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.y - element.size.height / 2 : element.position.y, onClick: handleElementClicked, onContextMenu: handleContextMenu, onMouseUp: handleMouseUp, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, container: paperContainerRef.current, renderShape: element.renderShape, cssClass: element.cssClass, texts: element.texts, ports: element.ports, portMoveableAreas: element.portMoveableAreas, portSlideRailSVGClassName: element.portSlideRailSVGClassName, portDirection: element.portDirection, defaultPortSize: element.defaultPortSize, onPortMoved: handlePortMoved, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp, onPortsChanged: handlePortsChanged, onPortContextMenu: handlePortContextMenu,
9949
10120
  // portPlaceholderShape={(<Circle x={0} y={0} width={10} height={10} fill='red' positioningAnchor={PositioningAnchor.Center} />)}
9950
10121
  onMouseUpAtLinkedPortPlaceholder: handleMouseUpAtLinkedPortPlaceholder, onTextUpdated: handleElementTextChange, onManuallyTriggerRenderPort: props.onManuallyTriggerRenderPort, textsPlaceHolderClassName: element.textsPlaceHolderClassName, textsPlaceHolderFlexStyle: element.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition: element.textsPlaceHolderFlexboxPosition, parentAbsolutePosition: element.parentElement ? getAbsolutePosition(element.parentElement) : undefined },
9951
10122
  element.childrenElementsInTree && element.childrenElementsInTree.map(renderElementInTree),
@@ -9953,22 +10124,32 @@ var Paper = function (props) {
9953
10124
  React.createElement(SelectionFrame, { container: paperContainerRef.current, targetSVGElement: selectedElementSVG || undefined, resizability: (selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.resizability) || {
9954
10125
  enabled: true,
9955
10126
  keepRatio: true
9956
- }, 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,
10127
+ }, 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,
9957
10128
  //movingOffsetThreshold: ELEMENT_MOVING_OFFSET_THRESHOLD,
9958
10129
  onMouseDown: function (ev) {
9959
10130
  var _a;
9960
10131
  if (selectedElement) {
9961
- (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement);
10132
+ var paperPosition = windowsPositionToPaperPosition({
10133
+ x: ev.clientX,
10134
+ y: ev.clientY
10135
+ }, paperContainerRef.current, zoomRef.current);
10136
+ (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement, paperPosition);
9962
10137
  }
9963
10138
  }, onMouseUp: function (ev) {
9964
10139
  var _a;
9965
10140
  if (selectedElement) {
9966
- (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement);
10141
+ var paperPosition = windowsPositionToPaperPosition({
10142
+ x: ev.clientX,
10143
+ y: ev.clientY
10144
+ }, paperContainerRef.current, zoomRef.current);
10145
+ (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement, paperPosition);
9967
10146
  }
9968
10147
  }, onMove: function (newX, newY) {
10148
+ var _a;
9969
10149
  if (!selectedElement)
9970
10150
  return;
9971
10151
  var oldPosition = __assign({}, selectedElement.position);
10152
+ // Relative position to the paper container
9972
10153
  var newPosition = {
9973
10154
  x: newX,
9974
10155
  y: newY
@@ -9985,10 +10166,29 @@ var Paper = function (props) {
9985
10166
  //let newElementPosition = updateElementPosition(selectedElement, newPosition.x, newPosition.y, true)
9986
10167
  var indexSelectedElement = elements.findIndex(function (e) { return e.id === selectedElement.id; });
9987
10168
  logger.info("Element ".concat(selectedElement.id, " is moving to relative position ").concat(JSON.stringify(selectedElement.position)));
10169
+ // Start updating the position of links connected to the selected element
10170
+ var childElements = getChildOfElement(selectedElement);
10171
+ var elementIds = __spreadArray(__spreadArray([], childElements.map(function (e) { return e.id; }), true), [selectedElement.id], false);
10172
+ var offsetX = newPosition.x - oldPosition.x;
10173
+ var offsetY = newPosition.y - oldPosition.y;
10174
+ // Update position of all points of links that are connected to the selected element
10175
+ var newLinks = linksRef.current.map(function (link) {
10176
+ var isUpdate = elementIds.includes(link.sourceElement.id) && elementIds.includes(link.targetElement.id);
10177
+ if (link.points && isUpdate) {
10178
+ link.points.forEach(function (p) {
10179
+ p.x += offsetX;
10180
+ p.y += offsetY;
10181
+ });
10182
+ }
10183
+ return link;
10184
+ });
10185
+ (_a = props.onLinksChanged) === null || _a === void 0 ? void 0 : _a.call(props, newLinks);
10186
+ // End updating the position of links connected to the selected element
9988
10187
  //Set state to re-render UI with new position
9989
10188
  setElementsInTree(function (prev) { return __spreadArray([], prev, true); });
9990
10189
  if (props.onElementMoved) {
9991
- props.onElementMoved(selectedElement.position, selectedElement, indexSelectedElement);
10190
+ console.log('onElementMoved', selectedElement.position, newPosition);
10191
+ props.onElementMoved(selectedElement.position, selectedElement, indexSelectedElement, newPosition);
9992
10192
  }
9993
10193
  paperEventEmitter.emitElementMoved(selectedElement, oldPosition, selectedElement.position);
9994
10194
  setMouseDownedOnPaper(false);
@@ -10010,12 +10210,12 @@ var Paper = function (props) {
10010
10210
  paperEventEmitter.emitElementResized(selectedElement, oldSize, newSize);
10011
10211
  setMouseDownedOnPaper(false);
10012
10212
  } }))));
10013
- }, [handlePortsChanged, handleElementClicked, handleContextMenu, handlePortMoved, handlePortMouseDown, handlePortMouseUp, handleMouseUpAtLinkedPortPlaceholder, handleElementTextChange, handleMouseUp, handleMouseMove, handleMouseLeave, selectedElement, selectedElementAbsPosition]);
10213
+ }, [handlePortsChanged, handleElementClicked, handleContextMenu, handlePortMoved, handlePortMouseDown, handlePortMouseUp, handleMouseUpAtLinkedPortPlaceholder, handleElementTextChange, handleMouseUp, handleMouseMove, handleMouseLeave, selectedElement, selectedElementAbsPosition, zoom]);
10014
10214
  var ElementsInTree = React.useMemo(function () {
10015
10215
  return elementsInTree.map(function (element, index) {
10016
10216
  return renderElementInTree(element);
10017
10217
  });
10018
- }, [elementsInTree, renderElementInTree, selectedElement]);
10218
+ }, [elementsInTree, renderElementInTree, selectedElement, zoom]);
10019
10219
  return (React.createElement("div", { style: { position: "relative" } },
10020
10220
  React.createElement(Ruler, { squareSize: 100, border: '1px dashed grey' }),
10021
10221
  React.createElement("svg", { tabIndex: 0, width: size.width, height: size.height, ref: paperContainerRef, id: "paper-container", onMouseMove: handlePaperMouseMove, onMouseDown: handleMouseDownOnPaper, onMouseUp: handleMouseUpOnPaper },
@@ -10043,83 +10243,6 @@ var Paper = function (props) {
10043
10243
  };
10044
10244
  var Paper$1 = React.memo(Paper);
10045
10245
 
10046
- /**
10047
- * Zoom context to manage zoom level and related state.
10048
- * This context can be used to provide zoom functionality across the application.
10049
- */
10050
- var zoomContext = React.createContext(null);
10051
- var ZoomContextProvider = function (_a) {
10052
- var children = _a.children;
10053
- var _b = React.useState(1), zoom = _b[0], setZoom = _b[1];
10054
- var _c = React.useState(0), scrollLeft = _c[0], setScrollLeft = _c[1];
10055
- var _d = React.useState(0), scrollTop = _d[0], setScrollTop = _d[1];
10056
- var wrapperRef = React.useRef(null);
10057
- var contentRef = React.useRef(null);
10058
- var handleWheel = function (e) {
10059
- // Chỉ zoom khi giữ Ctrl
10060
- if (!e.ctrlKey)
10061
- return;
10062
- e.preventDefault();
10063
- var delta = -e.deltaY;
10064
- var zoomFactor = 0.05;
10065
- var newZoom = zoom + (delta > 0 ? zoomFactor : -zoomFactor);
10066
- newZoom = Math.max(0.1, Math.min(newZoom, 4));
10067
- if (!wrapperRef.current || !contentRef.current)
10068
- return;
10069
- var wrapper = wrapperRef.current;
10070
- var content = contentRef.current;
10071
- // Get bounding rectangle of the content
10072
- var rect = content.getBoundingClientRect();
10073
- var offsetX = e.clientX - rect.left;
10074
- var offsetY = e.clientY - rect.top;
10075
- var percentX = offsetX / (content.offsetWidth);
10076
- var percentY = offsetY / (content.offsetHeight);
10077
- console.log(offsetX, offsetY, content.offsetWidth, content.offsetHeight, percentX, percentY);
10078
- // Old width and height of content
10079
- var prevWidth = content.offsetWidth * zoom;
10080
- var prevHeight = content.offsetHeight * zoom;
10081
- var newWidth = content.offsetWidth * newZoom;
10082
- var newHeight = content.offsetHeight * newZoom;
10083
- var scrollLeft = wrapper.scrollLeft + (percentX * (newWidth - prevWidth));
10084
- var scrollTop = wrapper.scrollTop + (percentY * (newHeight - prevHeight));
10085
- setZoom(newZoom);
10086
- setScrollLeft(scrollLeft);
10087
- setScrollTop(scrollTop);
10088
- };
10089
- React.useLayoutEffect(function () {
10090
- var _a;
10091
- (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({
10092
- left: scrollLeft,
10093
- top: scrollTop,
10094
- });
10095
- }, [zoom, scrollLeft, scrollTop]);
10096
- var resetZoom = function () {
10097
- setZoom(1);
10098
- };
10099
- React.useEffect(function () {
10100
- var preventBrowserZoom = function (e) {
10101
- if (e.ctrlKey || e.metaKey) {
10102
- e.preventDefault();
10103
- }
10104
- };
10105
- window.addEventListener("wheel", preventBrowserZoom, { passive: false });
10106
- return function () {
10107
- window.removeEventListener("wheel", preventBrowserZoom);
10108
- };
10109
- }, []);
10110
- return (React.createElement(zoomContext.Provider, { value: { zoom: zoom, setZoom: setZoom, resetZoom: resetZoom } },
10111
- React.createElement("div", { ref: wrapperRef, onWheel: handleWheel, style: {
10112
- width: "100vw",
10113
- height: "92vh",
10114
- overflow: "auto",
10115
- } },
10116
- React.createElement("div", { ref: contentRef, style: {
10117
- transform: "scale(".concat(zoom, ")"),
10118
- transformOrigin: "top left",
10119
- // transition: "transform 0.1s linear",
10120
- } }, children))));
10121
- };
10122
-
10123
10246
  var Editor = function (_a) {
10124
10247
  var editorContext = _a.editorContext, width = _a.width, height = _a.height;
10125
10248
  var _b = React.useState([]), elements = _b[0], setElements = _b[1];
@@ -10156,14 +10279,14 @@ var Editor = function (_a) {
10156
10279
  var handlePaperClicked = React.useCallback(function (position) {
10157
10280
  editorContext.onPaperClickedHandler(position);
10158
10281
  }, [editorContext]);
10159
- var handlePortMouseDown = React.useCallback(function (port, element) {
10160
- editorContext.onPortMouseDownHandler(port, element);
10282
+ var handlePortMouseDown = React.useCallback(function (port, element, paperPosition) {
10283
+ editorContext.onPortMouseDownHandler(port, element, paperPosition);
10161
10284
  }, [editorContext]);
10162
- var handlePortMouseUp = React.useCallback(function (port, element) {
10163
- editorContext.onPortMouseUpHandler(port, element);
10285
+ var handlePortMouseUp = React.useCallback(function (port, element, paperPosition) {
10286
+ editorContext.onPortMouseUpHandler(port, element, paperPosition);
10164
10287
  }, [editorContext]);
10165
- var handlePortMoved = React.useCallback(function (position, port, element) {
10166
- editorContext.onPortMovedHandler(position, port, element);
10288
+ var handlePortMoved = React.useCallback(function (relativePosition, port, element) {
10289
+ editorContext.onPortMovedHandler(relativePosition, port, element);
10167
10290
  }, [editorContext]);
10168
10291
  var handlePortSelected = React.useCallback(function (port, element) {
10169
10292
  editorContext.onPortSelectedHandler(port, element);
@@ -10171,11 +10294,14 @@ var Editor = function (_a) {
10171
10294
  var handlePortsChanged = React.useCallback(function (ports, element) {
10172
10295
  element.ports = ports;
10173
10296
  }, [editorContext]);
10297
+ var handlePortContextMenu = React.useCallback(function (port, element, event) {
10298
+ editorContext.onPortContextMenuHandler(port, element, event);
10299
+ }, [editorContext]);
10174
10300
  var handleElementContextMenu = React.useCallback(function (element, event) {
10175
10301
  editorContext.onElementContextMenuHandler(element, event);
10176
10302
  }, [editorContext]);
10177
- var handleElementMoved = React.useCallback(function (position, element) {
10178
- editorContext.onElementMovedHandler(position, element);
10303
+ var handleElementMoved = React.useCallback(function (relativePosition, element) {
10304
+ editorContext.onElementMovedHandler(relativePosition, element);
10179
10305
  }, [editorContext]);
10180
10306
  var handleElementResized = React.useCallback(function (size, element) {
10181
10307
  editorContext.onElementResizedHandler(size, element);
@@ -10183,17 +10309,17 @@ var Editor = function (_a) {
10183
10309
  var handleElementSelected = React.useCallback(function (element) {
10184
10310
  editorContext.onElementSelectedHandler(element);
10185
10311
  }, [editorContext]);
10186
- var handleElementMouseLeave = React.useCallback(function (ev, element) {
10187
- editorContext.onElementMouseLeaveHandler(ev, element);
10312
+ var handleElementMouseLeave = React.useCallback(function (ev, element, paperPosition) {
10313
+ editorContext.onElementMouseLeaveHandler(ev, element, paperPosition);
10188
10314
  }, [editorContext]);
10189
- var handleElementMouseMove = React.useCallback(function (ev, element) {
10190
- editorContext.onElementMouseMoveHandler(ev, element);
10315
+ var handleElementMouseMove = React.useCallback(function (ev, element, paperPosition) {
10316
+ editorContext.onElementMouseMoveHandler(ev, element, paperPosition);
10191
10317
  }, [editorContext]);
10192
- var handleElementMouseDown = React.useCallback(function (ev, element) {
10193
- editorContext.onElementMouseDownHandler(ev, element);
10318
+ var handleElementMouseDown = React.useCallback(function (ev, element, paperPosition) {
10319
+ editorContext.onElementMouseDownHandler(ev, element, paperPosition);
10194
10320
  }, [editorContext]);
10195
- var handleElementMouseUp = React.useCallback(function (ev, element) {
10196
- editorContext.onElementMouseUpHandler(ev, element);
10321
+ var handleElementMouseUp = React.useCallback(function (ev, element, paperPosition) {
10322
+ editorContext.onElementMouseUpHandler(ev, element, paperPosition);
10197
10323
  }, [editorContext]);
10198
10324
  var handleElementsChanged = React.useCallback(function (elements) {
10199
10325
  editorContext.elements = elements;
@@ -10202,7 +10328,6 @@ var Editor = function (_a) {
10202
10328
  editorContext.onLinkSelectedHandler(link);
10203
10329
  }, [editorContext]);
10204
10330
  var handleLinksChanged = React.useCallback(function (links) {
10205
- console.log(links);
10206
10331
  editorContext.links = links;
10207
10332
  }, [editorContext]);
10208
10333
  var handleTextSelected = React.useCallback(function (text) {
@@ -10224,11 +10349,9 @@ var Editor = function (_a) {
10224
10349
  return null;
10225
10350
  }, [editorContext]);
10226
10351
  var handlePaperMouseMoved = React.useCallback(function (position) {
10227
- console.log("handlePaperMouseMoved", position);
10228
10352
  editorContext.onPaperMouseMovedHandler(position);
10229
10353
  }, [editorContext]);
10230
10354
  var handlePaperMouseDown = React.useCallback(function (position) {
10231
- console.log("handlePaperMouseDown", position);
10232
10355
  editorContext.onPaperMouseDownHandler(position);
10233
10356
  }, [editorContext]);
10234
10357
  var handlePaperMouseUp = React.useCallback(function (position) {
@@ -10236,7 +10359,7 @@ var Editor = function (_a) {
10236
10359
  }, [editorContext]);
10237
10360
  return (React.createElement(EditorConfigurationContextProvider, { value: editorContext.configuration },
10238
10361
  React.createElement(ZoomContextProvider, null,
10239
- 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) }))));
10362
+ 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, onPortContextMenu: handlePortContextMenu, 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) }))));
10240
10363
  };
10241
10364
 
10242
10365
  exports.CircleRC = Circle;
@@ -10280,7 +10403,6 @@ exports.getPointsFromPathData = getPointsFromPathData;
10280
10403
  exports.getPointsFromPathElement = getPointsFromPathElement;
10281
10404
  exports.getPortAbsolutePosition = getPortAbsolutePosition;
10282
10405
  exports.getRectangleCorners = getRectangleCorners;
10283
- exports.getRelativePosition = getRelativePosition;
10284
10406
  exports.getRotatedRectangleCoordinates = getRotatedRectangleCoordinates;
10285
10407
  exports.getRotatedSVGBBox = getRotatedSVGBBox;
10286
10408
  exports.getSVGBBoxOutsideTransformedParent = getSVGBBoxOutsideTransformedParent;
@@ -10289,3 +10411,4 @@ exports.pathDataToD = pathDataToD;
10289
10411
  exports.removeDuplicatePosition = removeDuplicatePosition;
10290
10412
  exports.transformAbsPositionToElementRelativePosition = transformAbsPositionToElementRelativePosition;
10291
10413
  exports.transformAbsPositionToRelativePositionInsideElement = transformAbsPositionToRelativePositionInsideElement;
10414
+ exports.windowsPositionToPaperPosition = windowsPositionToPaperPosition;