orcasvn-react-diagrams 0.1.54 → 0.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -957,15 +957,15 @@ var EditorContext = /** @class */ (function () {
957
957
  return this.addEventListener(EVENT_PORT_MOUSE_DOWN, callback);
958
958
  };
959
959
  /** @internal */
960
- EditorContext.prototype.onPortMouseDownHandler = function (port, element) {
961
- this._eventEmitter.emit(EVENT_PORT_MOUSE_DOWN, port, element);
960
+ EditorContext.prototype.onPortMouseDownHandler = function (port, element, paperPosition) {
961
+ this._eventEmitter.emit(EVENT_PORT_MOUSE_DOWN, port, element, paperPosition);
962
962
  };
963
963
  EditorContext.prototype.onPortMouseUp = function (callback) {
964
964
  return this.addEventListener(EVENT_PORT_MOUSE_UP, callback);
965
965
  };
966
966
  /** @internal */
967
- EditorContext.prototype.onPortMouseUpHandler = function (port, element) {
968
- this._eventEmitter.emit(EVENT_PORT_MOUSE_UP, port, element);
967
+ EditorContext.prototype.onPortMouseUpHandler = function (port, element, paperPosition) {
968
+ this._eventEmitter.emit(EVENT_PORT_MOUSE_UP, port, element, paperPosition);
969
969
  };
970
970
  EditorContext.prototype.onPortMoved = function (callback) {
971
971
  return this.addEventListener(EVENT_PORT_MOVED, callback);
@@ -992,8 +992,8 @@ var EditorContext = /** @class */ (function () {
992
992
  return this.addEventListener(EVENT_ELEMENT_MOVED, callback);
993
993
  };
994
994
  /** @internal */
995
- EditorContext.prototype.onElementMovedHandler = function (position, element) {
996
- this._eventEmitter.emit(EVENT_ELEMENT_MOVED, position, element);
995
+ EditorContext.prototype.onElementMovedHandler = function (relativePosition, element) {
996
+ this._eventEmitter.emit(EVENT_ELEMENT_MOVED, relativePosition, element);
997
997
  };
998
998
  EditorContext.prototype.onElementResized = function (callback) {
999
999
  return this.addEventListener(EVENT_ELEMENT_RESIZED, callback);
@@ -1013,29 +1013,29 @@ var EditorContext = /** @class */ (function () {
1013
1013
  return this.addEventListener(EVENT_ELEMENT_MOUSE_MOVE, callback);
1014
1014
  };
1015
1015
  /** @internal */
1016
- EditorContext.prototype.onElementMouseMoveHandler = function (ev, element) {
1017
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_MOVE, ev, element);
1016
+ EditorContext.prototype.onElementMouseMoveHandler = function (ev, element, paperPosition) {
1017
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_MOVE, ev, element, paperPosition);
1018
1018
  };
1019
1019
  EditorContext.prototype.onElementMouseLeave = function (callback) {
1020
1020
  return this.addEventListener(EVENT_ELEMENT_MOUSE_LEAVE, callback);
1021
1021
  };
1022
1022
  /** @internal */
1023
- EditorContext.prototype.onElementMouseLeaveHandler = function (ev, element) {
1024
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_LEAVE, ev, element);
1023
+ EditorContext.prototype.onElementMouseLeaveHandler = function (ev, element, paperPosition) {
1024
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_LEAVE, ev, element, paperPosition);
1025
1025
  };
1026
1026
  EditorContext.prototype.onElementMouseUp = function (callback) {
1027
1027
  return this.addEventListener(EVENT_ELEMENT_MOUSE_UP, callback);
1028
1028
  };
1029
1029
  /** @internal */
1030
- EditorContext.prototype.onElementMouseUpHandler = function (ev, element) {
1031
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_UP, ev, element);
1030
+ EditorContext.prototype.onElementMouseUpHandler = function (ev, element, paperPosition) {
1031
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_UP, ev, element, paperPosition);
1032
1032
  };
1033
1033
  EditorContext.prototype.onElementMouseDown = function (callback) {
1034
1034
  return this.addEventListener(EVENT_ELEMENT_MOUSE_DOWN, callback);
1035
1035
  };
1036
1036
  /** @internal */
1037
- EditorContext.prototype.onElementMouseDownHandler = function (ev, element) {
1038
- this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_DOWN, ev, element);
1037
+ EditorContext.prototype.onElementMouseDownHandler = function (ev, element, paperPosition) {
1038
+ this._eventEmitter.emit(EVENT_ELEMENT_MOUSE_DOWN, ev, element, paperPosition);
1039
1039
  };
1040
1040
  EditorContext.prototype.onLinkSelected = function (callback) {
1041
1041
  return this.addEventListener(EVENT_LINK_SELECTED, callback);
@@ -1305,603 +1305,6 @@ var Logger = /** @class */ (function () {
1305
1305
  }());
1306
1306
  var logger = new Logger();
1307
1307
 
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;
1469
- }
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
- };
1476
-
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
1308
  /**
1906
1309
  * Created by Alex Bol on 2/18/2017.
1907
1310
  */
@@ -7442,43 +6845,6 @@ var checkPositionOnLine = function (position, line) {
7442
6845
  return _line.contains(point);
7443
6846
  };
7444
6847
 
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
6848
  // const topLeftOffsetOfSquareHoldingRect = (x: number, y: number, rectWidth: number, rectHeight: number, rotation?: number): IPosition => {
7483
6849
  // rotation = rotation || 0;
7484
6850
  // const rotationInRadians = rotation * Math.PI / 180;
@@ -7532,8 +6898,213 @@ function calculateAngleWithOx(pStart, pEnd) {
7532
6898
  if (angleInDegrees < 0) {
7533
6899
  angleInDegrees += 360;
7534
6900
  }
7535
- return angleInDegrees;
7536
- }
6901
+ return angleInDegrees;
6902
+ }
6903
+
6904
+ // Render the svg <path> element
6905
+ function getCurvePathData(points, smoothing, closed) {
6906
+ if (smoothing === void 0) { smoothing = 0.2; }
6907
+ // append first 2 points for closed paths
6908
+ if (closed) {
6909
+ points = points.concat(points.slice(0, 2));
6910
+ }
6911
+ // Properties of a line
6912
+ var line = function (pointA, pointB) {
6913
+ var lengthX = pointB.x - pointA.x;
6914
+ var lengthY = pointB.y - pointA.y;
6915
+ return {
6916
+ length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
6917
+ angle: Math.atan2(lengthY, lengthX)
6918
+ };
6919
+ };
6920
+ // Position of a control point
6921
+ var controlPoint = function (current, previous, next, reverse) {
6922
+ var p = previous || current;
6923
+ var n = next || current;
6924
+ var o = line(p, n);
6925
+ var angle = o.angle + (reverse ? Math.PI : 0);
6926
+ var length = o.length * smoothing;
6927
+ var x = current.x + Math.cos(angle) * length;
6928
+ var y = current.y + Math.sin(angle) * length;
6929
+ return { x: x, y: y };
6930
+ };
6931
+ var pathData = [];
6932
+ pathData.push({ type: "M", values: [points[0].x, points[0].y] });
6933
+ for (var i = 1; i < points.length; i++) {
6934
+ var point = points[i];
6935
+ var cp1 = controlPoint(points[i - 1], points[i - 2], point);
6936
+ var cp2 = controlPoint(point, points[i - 1], points[i + 1], true);
6937
+ var command = {
6938
+ type: "C",
6939
+ values: [cp1.x, cp1.y, cp2.x, cp2.y, point.x, point.y]
6940
+ };
6941
+ pathData.push(command);
6942
+ }
6943
+ // copy last commands 1st controlpoint to first curveto
6944
+ if (closed) {
6945
+ var comLast = pathData[pathData.length - 1];
6946
+ var valuesLastC = comLast.values;
6947
+ var valuesFirstC = pathData[1].values;
6948
+ pathData[1] = {
6949
+ type: "C",
6950
+ values: [valuesLastC[0], valuesLastC[1], valuesFirstC.slice(2)].flat()
6951
+ };
6952
+ // delete last curveto
6953
+ pathData = pathData.slice(0, pathData.length - 1);
6954
+ }
6955
+ return pathData;
6956
+ }
6957
+ // convert pathdata to d attribute string
6958
+ function pathDataToD(pathData, decimals) {
6959
+ if (decimals === void 0) { decimals = 3; }
6960
+ var d = pathData
6961
+ .map(function (com) {
6962
+ return "".concat(com.type).concat(com.values.map(function (value) { return +value.toFixed(decimals); }).join(" "));
6963
+ })
6964
+ .join(" ");
6965
+ return d;
6966
+ }
6967
+ function createSmoothPathString(points, smoothing, close) {
6968
+ var pathData = getCurvePathData(points, smoothing, close);
6969
+ var pathString = pathDataToD(pathData);
6970
+ return pathString;
6971
+ }
6972
+ // a helper function to measure the distance between 2 points
6973
+ function dist(p1, p2) {
6974
+ var dx = p2.x - p1.x;
6975
+ var dy = p2.y - p1.y;
6976
+ return Math.sqrt(dx * dx + dy * dy);
6977
+ }
6978
+ //find distance from starting point of path to a point
6979
+ function getLengthForPoint(p, thePath, precision) {
6980
+ if (precision === void 0) { precision = 50; }
6981
+ var pathLength = thePath.getTotalLength();
6982
+ var theRecord = pathLength; //length of path
6983
+ var division = pathLength / precision;
6984
+ var theSegment;
6985
+ for (var i = 0; i < precision; i++) {
6986
+ // get a point on the path for thia distance
6987
+ var _p = thePath.getPointAtLength(i * division);
6988
+ // get the distance between the new point _p and the point p
6989
+ var theDistance = dist(_p, p);
6990
+ if (theDistance < theRecord) {
6991
+ // if the distance is smaller than the record set the new record
6992
+ theRecord = theDistance;
6993
+ theSegment = i;
6994
+ }
6995
+ }
6996
+ return (theSegment * division);
6997
+ }
6998
+ //Add points to the list of points in the correct position
6999
+ function addPointToList(point, listPoints, path) {
7000
+ var getAddIndex = function (startIndex, endIndex) {
7001
+ //Add in the middle if there are only 2 points
7002
+ if ((endIndex - startIndex) === 1) {
7003
+ return startIndex + 1;
7004
+ }
7005
+ var middleIndex = Math.ceil((startIndex + endIndex) / 2);
7006
+ var lengthOfMiddlePoint = getLengthForPoint(listPoints[middleIndex], path); //distance from start point to mid point
7007
+ var lengthOfAddedPoint = getLengthForPoint(point, path); //distance from adding point to mid point
7008
+ //compare if lengthOfMiddlePoint is less than lengthOfAddedPoint,
7009
+ //then new point can be added in the range of mid point to end point,
7010
+ //otherwise it can be added in the range of start point to middle point.
7011
+ if (lengthOfAddedPoint < lengthOfMiddlePoint) {
7012
+ return getAddIndex(startIndex, middleIndex);
7013
+ }
7014
+ else {
7015
+ return getAddIndex(middleIndex, endIndex);
7016
+ }
7017
+ };
7018
+ var addedIndex = getAddIndex(0, listPoints.length - 1);
7019
+ listPoints.splice(addedIndex, 0, point);
7020
+ return __spreadArray([], listPoints, true);
7021
+ }
7022
+ // Parse the d attribute of a path element and extract points from path commands
7023
+ function getPointsFromPathData(dAttribute) {
7024
+ var points = [];
7025
+ // Remove extra whitespace and split by command letters
7026
+ var cleanD = dAttribute.replace(/\s+/g, ' ').trim();
7027
+ // Regular expression to match path commands (M, L, C, etc.) and their values
7028
+ var commandRegex = /([MLCZmlcz])\s*([^MLCZmlcz]*)/g;
7029
+ var match;
7030
+ while ((match = commandRegex.exec(cleanD)) !== null) {
7031
+ var command = match[1].toUpperCase();
7032
+ var values = match[2].trim();
7033
+ if (values) {
7034
+ var coords = values.split(/[\s,]+/).map(Number).filter(function (num) { return !isNaN(num); });
7035
+ switch (command) {
7036
+ case 'M': // Move to
7037
+ if (coords.length >= 2) {
7038
+ points.push({ x: coords[0], y: coords[1] });
7039
+ }
7040
+ break;
7041
+ case 'L': // Line to
7042
+ if (coords.length >= 2) {
7043
+ points.push({ x: coords[0], y: coords[1] });
7044
+ }
7045
+ break;
7046
+ case 'C': // Cubic bezier curve
7047
+ // For cubic curves, we take the end point (last 2 coordinates)
7048
+ if (coords.length >= 6) {
7049
+ points.push({ x: coords[4], y: coords[5] });
7050
+ }
7051
+ break;
7052
+ case 'Q': // Quadratic bezier curve
7053
+ // For quadratic curves, we take the end point (last 2 coordinates)
7054
+ if (coords.length >= 4) {
7055
+ points.push({ x: coords[2], y: coords[3] });
7056
+ }
7057
+ break;
7058
+ }
7059
+ }
7060
+ }
7061
+ return points;
7062
+ }
7063
+ // Get points from a path element's d attribute
7064
+ function getPointsFromPathElement(pathElement) {
7065
+ var dAttribute = pathElement.getAttribute('d');
7066
+ if (!dAttribute) {
7067
+ return [];
7068
+ }
7069
+ return getPointsFromPathData(dAttribute);
7070
+ }
7071
+
7072
+ // Calculate the position of the 4 vertices of a rectangle relative to its parent svg
7073
+ var getRectangleCorners = function (rectSVG) {
7074
+ var ownerSVG = rectSVG.ownerSVGElement;
7075
+ var rectStrokeWidth = Number(rectSVG.getAttribute('stroke-width')) || 0;
7076
+ var strokeWidthOffset = rectStrokeWidth / 2;
7077
+ if (!ownerSVG) {
7078
+ throw new Error('Rectangle does not wrapper by svg.');
7079
+ }
7080
+ var ownerX = ownerSVG.x.baseVal.value;
7081
+ var ownerY = ownerSVG.y.baseVal.value;
7082
+ var ownerWidth = ownerSVG.width.baseVal.value;
7083
+ var ownerHeight = ownerSVG.height.baseVal.value;
7084
+ var a = { x: ownerX + strokeWidthOffset, y: ownerY + strokeWidthOffset };
7085
+ var b = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + strokeWidthOffset };
7086
+ var c = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7087
+ var d = { x: ownerX + strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7088
+ return [a, b, c, d];
7089
+ };
7090
+ //find rotation angle of svg element on g element
7091
+ var getElementRotationInfo = function (element) {
7092
+ var gElement = element;
7093
+ var rotationAngle = 0;
7094
+ while (!(gElement instanceof SVGGElement)) {
7095
+ gElement = gElement.parentElement;
7096
+ }
7097
+ var transform = gElement.getAttribute('transform');
7098
+ if (transform) {
7099
+ // Match the rotation value using a regular expression
7100
+ var rotateMatch = transform.match(/rotate\(([-\d.]+)(?:\s+[-\d.]+\s+[-\d.]+)?\)/);
7101
+ if (rotateMatch) {
7102
+ // The first capture group is the rotation angle
7103
+ rotationAngle = parseFloat(rotateMatch[1]);
7104
+ }
7105
+ }
7106
+ return rotationAngle;
7107
+ };
7537
7108
 
7538
7109
  /**
7539
7110
  * Check if position 1 is within the radius r of position 2
@@ -7573,591 +7144,1177 @@ var findNearestPointOnSegment = function (position, linePoints) {
7573
7144
  var segment = Flatten$1.segment(Flatten$1.point(beginPosition.x, beginPosition.y), Flatten$1.point(endPosition.x, endPosition.y));
7574
7145
  var _a = point.distanceTo(segment); _a[0]; var segmentFromPointToSegment = _a[1];
7575
7146
  return {
7576
- x: segmentFromPointToSegment.pe.x,
7577
- y: segmentFromPointToSegment.pe.y
7147
+ x: segmentFromPointToSegment.pe.x,
7148
+ y: segmentFromPointToSegment.pe.y
7149
+ };
7150
+ };
7151
+ /**
7152
+ * From 1 point find projected Point on the line segments so that the distance between 2 points is shortest.
7153
+ * @param position
7154
+ * @param lines
7155
+ * @returns
7156
+ */
7157
+ var findNearestProjectedPoint = function (position, lines) {
7158
+ var possiblePoints = lines.map(function (p) { return findNearestPointOnSegment(position, p); });
7159
+ var nearestPoint = findNearestPosition(possiblePoints, position);
7160
+ return nearestPoint;
7161
+ };
7162
+ /**
7163
+ * Check if a point is inside a polygon
7164
+ * @param position
7165
+ * @param polygonPoints
7166
+ * @returns
7167
+ */
7168
+ var checkPointContainsPolygon = function (position, polygonPoints) {
7169
+ var polygon = new Flatten$1.Polygon();
7170
+ polygon.addFace(polygonPoints.map(function (p) { return Flatten$1.point(p.x, p.y); }));
7171
+ return polygon.contains(Flatten$1.point(position.x, position.y));
7172
+ };
7173
+ /**
7174
+ * @param ele : IElement
7175
+ * @returns Flatten.Polygon
7176
+ */
7177
+ var makePolygonOfElement = function (ele) {
7178
+ var polygon = new Flatten$1.Polygon();
7179
+ var vertexes = getFourVertexesOfBBoxFromElement(ele);
7180
+ polygon.addFace([
7181
+ Flatten$1.point(vertexes[0].x, vertexes[0].y),
7182
+ Flatten$1.point(vertexes[1].x, vertexes[1].y),
7183
+ Flatten$1.point(vertexes[2].x, vertexes[2].y),
7184
+ Flatten$1.point(vertexes[3].x, vertexes[3].y),
7185
+ ]);
7186
+ return polygon;
7187
+ };
7188
+ var getIntersectionPositions = function (pointStart, pointEnd, ele) {
7189
+ var segment = Flatten$1.segment(Flatten$1.point(pointStart.x, pointStart.y), Flatten$1.point(pointEnd.x, pointEnd.y));
7190
+ var polygonOfEle = makePolygonOfElement(ele);
7191
+ /* Remove duplicate positions from the result of finding the intersection points between a segment and a polygon.
7192
+ It then maps the intersection points to objects with rounded x and y coordinates. */
7193
+ return removeDuplicatePosition(segment.intersect(polygonOfEle).map(function (p) { return ({ x: Math.round(p.x), y: Math.round(p.y) }); }));
7194
+ };
7195
+ //Find the first intersection point of the line starting from startPosition to endPosition on the elements
7196
+ var getFirstIntersection = function (startPosition, endPosition, elements) {
7197
+ if (!endPosition)
7198
+ return undefined;
7199
+ var result;
7200
+ for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
7201
+ var element = elements_1[_i];
7202
+ //Find intersection positions on element
7203
+ var intersectionPoints = getIntersectionPositions(startPosition, endPosition, element);
7204
+ //If the line intersects at 1 point (can be the starting point or the ending point) or no point then ignore
7205
+ if (intersectionPoints.length <= 1) {
7206
+ continue;
7207
+ }
7208
+ var selectablePointsList = __spreadArray([], intersectionPoints, true);
7209
+ //If a point is found on a previous element, add it to the list of intersection points on the current element.
7210
+ if (result === null || result === void 0 ? void 0 : result.nearestIntersection) {
7211
+ selectablePointsList.push(result.nearestIntersection);
7212
+ }
7213
+ var nearest = findNearestPosition(selectablePointsList, startPosition);
7214
+ //If the closest intersection point to the starting point is not found or the new point is different from the previously found point, set a new value.
7215
+ if (!(result === null || result === void 0 ? void 0 : result.nearestIntersection) || !checkSamePosition(nearest, result.nearestIntersection)) {
7216
+ result = {
7217
+ element: element,
7218
+ intersectionPointsList: intersectionPoints,
7219
+ nearestIntersection: nearest,
7220
+ };
7221
+ }
7222
+ }
7223
+ return result;
7224
+ };
7225
+ //Find a point next to an element from a point on the element
7226
+ var generateSubstitutePosition = function (intersectedPosition, targetPosition, ele) {
7227
+ var translationOffset = 20;
7228
+ var _a = getFourVertexesOfBBoxFromElement(ele), vertex1Position = _a[0], vertex2Position = _a[1], vertex3Position = _a[2], vertex4Position = _a[3];
7229
+ var replacementPosition = null;
7230
+ if (checkSamePosition(vertex1Position, intersectedPosition, 0)) {
7231
+ //Cut at vertex 1 of bbox, move out a distance x,y
7232
+ replacementPosition = {
7233
+ x: vertex1Position.x - translationOffset,
7234
+ y: vertex1Position.y - translationOffset,
7235
+ };
7236
+ }
7237
+ else if (checkSamePosition(vertex2Position, intersectedPosition, 0)) {
7238
+ //Cut at vertex 2 of bbox, move out a distance x,y
7239
+ replacementPosition = {
7240
+ x: vertex2Position.x + translationOffset,
7241
+ y: vertex2Position.y - translationOffset,
7242
+ };
7243
+ }
7244
+ else if (checkSamePosition(vertex3Position, intersectedPosition, 0)) {
7245
+ //Cut at vertex 3 of bbox, move out a distance x,y
7246
+ replacementPosition = {
7247
+ x: vertex3Position.x + translationOffset,
7248
+ y: vertex3Position.y + translationOffset,
7249
+ };
7250
+ }
7251
+ else if (checkSamePosition(vertex4Position, intersectedPosition, 0)) {
7252
+ //Cut at vertex 4 of bbox, move out a distance x,y
7253
+ replacementPosition = {
7254
+ x: vertex4Position.x - translationOffset,
7255
+ y: vertex4Position.y + translationOffset,
7256
+ };
7257
+ }
7258
+ else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex2Position])) {
7259
+ //cut top edge, move left or right
7260
+ var lineOfVertex12 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex2Position.x, vertex2Position.y));
7261
+ //Check if the line lies on the edge of the bbox then move the starting point out 1 distance perpendicular to the edge.
7262
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex12)[0] === 0 &&
7263
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex12)[0] === 0) {
7264
+ //lie on a straight line 1-2
7265
+ replacementPosition = {
7266
+ x: intersectedPosition.x,
7267
+ y: intersectedPosition.y - translationOffset,
7268
+ };
7269
+ }
7270
+ else {
7271
+ //Translate to the left of vertex 1
7272
+ var leftPosition = {
7273
+ x: vertex1Position.x - translationOffset,
7274
+ y: vertex1Position.y,
7275
+ };
7276
+ //Translate to the right of vertex 2
7277
+ var rightPosition = {
7278
+ x: vertex2Position.x + translationOffset,
7279
+ y: vertex2Position.y,
7280
+ };
7281
+ replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7282
+ }
7283
+ }
7284
+ else if (checkPositionOnLine(intersectedPosition, [vertex3Position, vertex4Position])) {
7285
+ //cut bottom edge, move left or right
7286
+ var lineOfVertex34 = Flatten$1.line(Flatten$1.point(vertex3Position.x, vertex3Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7287
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex34)[0] === 0 &&
7288
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex34)[0] === 0) {
7289
+ //lie on a straight line 3-4
7290
+ replacementPosition = {
7291
+ x: intersectedPosition.x,
7292
+ y: intersectedPosition.y + translationOffset,
7293
+ };
7294
+ }
7295
+ else {
7296
+ //Translate to the left of vertex 4
7297
+ var leftPosition = {
7298
+ x: vertex4Position.x - translationOffset,
7299
+ y: vertex4Position.y,
7300
+ };
7301
+ //Translate to the right of vertex 3
7302
+ var rightPosition = {
7303
+ x: vertex3Position.x + translationOffset,
7304
+ y: vertex3Position.y,
7305
+ };
7306
+ replacementPosition = findNearestPosition([leftPosition, rightPosition], targetPosition);
7307
+ }
7308
+ }
7309
+ else if (checkPositionOnLine(intersectedPosition, [vertex1Position, vertex4Position])) {
7310
+ //cut left edge, move up or down
7311
+ var lineOfVertex14 = Flatten$1.line(Flatten$1.point(vertex1Position.x, vertex1Position.y), Flatten$1.point(vertex4Position.x, vertex4Position.y));
7312
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex14)[0] === 0 &&
7313
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex14)[0] === 0) {
7314
+ //lie on a straight line 1-4
7315
+ replacementPosition = {
7316
+ x: intersectedPosition.x - translationOffset,
7317
+ y: intersectedPosition.y,
7318
+ };
7319
+ }
7320
+ else {
7321
+ //Translate to the top of vertex 1
7322
+ var topPosition = {
7323
+ x: vertex1Position.x,
7324
+ y: vertex1Position.y - translationOffset,
7325
+ };
7326
+ //Translate to the bottom of vertex 4
7327
+ var bottomPosition = {
7328
+ x: vertex4Position.x,
7329
+ y: vertex4Position.y + translationOffset,
7330
+ };
7331
+ replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7332
+ }
7333
+ }
7334
+ else if (checkPositionOnLine(intersectedPosition, [vertex2Position, vertex3Position])) {
7335
+ //cut right edge, move up or down
7336
+ var lineOfVertex23 = Flatten$1.line(Flatten$1.point(vertex2Position.x, vertex2Position.y), Flatten$1.point(vertex3Position.x, vertex3Position.y));
7337
+ if (Flatten$1.point(intersectedPosition.x, intersectedPosition.y).distanceTo(lineOfVertex23)[0] === 0 &&
7338
+ Flatten$1.point(targetPosition.x, targetPosition.y).distanceTo(lineOfVertex23)[0] === 0) {
7339
+ //lie on a straight line 2-3
7340
+ replacementPosition = {
7341
+ x: intersectedPosition.x + translationOffset,
7342
+ y: intersectedPosition.y,
7343
+ };
7344
+ }
7345
+ else {
7346
+ //Translate to the top of vertex 2
7347
+ var topPosition = {
7348
+ x: vertex2Position.x,
7349
+ y: vertex2Position.y - translationOffset,
7350
+ };
7351
+ //Translate to the bottom of vertex 3
7352
+ var bottomPosition = {
7353
+ x: vertex3Position.x,
7354
+ y: vertex3Position.y + translationOffset,
7355
+ };
7356
+ replacementPosition = findNearestPosition([topPosition, bottomPosition], targetPosition);
7357
+ }
7358
+ }
7359
+ return replacementPosition;
7360
+ };
7361
+ // export const getRelativePosition = (clientPosition: IPosition, relativeElement: Element): IPosition => {
7362
+ // const relativeRect = relativeElement.getBoundingClientRect();
7363
+ // return {
7364
+ // x: clientPosition.x - relativeRect.left,
7365
+ // y: clientPosition.y - relativeRect.top,
7366
+ // }
7367
+ // }
7368
+ var getFourVertexesOfBBoxFromElement = function (element) {
7369
+ var absolutePosition = getAbsolutePosition(element);
7370
+ var vertex1Position = {
7371
+ x: absolutePosition.x,
7372
+ y: absolutePosition.y
7373
+ };
7374
+ var vertex2Position = {
7375
+ x: absolutePosition.x + element.size.width,
7376
+ y: absolutePosition.y
7377
+ };
7378
+ var vertex3Position = {
7379
+ x: absolutePosition.x + element.size.width,
7380
+ y: absolutePosition.y + element.size.height
7381
+ };
7382
+ var vertex4Position = {
7383
+ x: absolutePosition.x,
7384
+ y: absolutePosition.y + element.size.height
7385
+ };
7386
+ return [vertex1Position, vertex2Position, vertex3Position, vertex4Position];
7387
+ };
7388
+ //get absolute position of element
7389
+ var getAbsolutePosition = function (element) {
7390
+ var parentElement = element.parentElement;
7391
+ var elemenetPositionWithTopLeftAnchor = {
7392
+ x: element.position.x,
7393
+ y: element.position.y,
7394
+ };
7395
+ if (element.positionAnchor === exports.PositioningAnchor.Center) {
7396
+ elemenetPositionWithTopLeftAnchor.x -= element.size.width / 2;
7397
+ elemenetPositionWithTopLeftAnchor.y -= element.size.height / 2;
7398
+ }
7399
+ if (!parentElement) {
7400
+ return __assign({}, elemenetPositionWithTopLeftAnchor);
7401
+ }
7402
+ var absoluteParentElement = getAbsolutePosition(parentElement);
7403
+ var x = elemenetPositionWithTopLeftAnchor.x + absoluteParentElement.x;
7404
+ var y = elemenetPositionWithTopLeftAnchor.y + absoluteParentElement.y;
7405
+ return {
7406
+ x: x,
7407
+ y: y,
7578
7408
  };
7579
7409
  };
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));
7410
+ //get absolute position of element
7411
+ var getPortAbsolutePosition = function (port, element) {
7412
+ var elementAbsolutePosition = getAbsolutePosition(element);
7413
+ return {
7414
+ x: elementAbsolutePosition.x + port.position.x,
7415
+ y: elementAbsolutePosition.y + port.position.y,
7416
+ };
7601
7417
  };
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;
7418
+ var transformAbsPositionToElementRelativePosition = function (position, element) {
7419
+ var parentElement = element.parentElement;
7420
+ if (!parentElement) {
7421
+ return position;
7422
+ }
7423
+ var absoluteParentElement = getAbsolutePosition(parentElement);
7424
+ var result = {
7425
+ x: position.x - absoluteParentElement.x,
7426
+ y: position.y - absoluteParentElement.y,
7427
+ };
7428
+ if (element.positionAnchor === exports.PositioningAnchor.Center) {
7429
+ result.x += element.size.width / 2;
7430
+ result.y += element.size.height / 2;
7431
+ }
7432
+ return result;
7616
7433
  };
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) }); }));
7434
+ var transformAbsPositionToRelativePositionInsideElement = function (absolutePosition, parentAbsolutePosition) {
7435
+ var _a, _b;
7436
+ var position = {
7437
+ x: absolutePosition.x - ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0),
7438
+ y: absolutePosition.y - ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0),
7439
+ };
7440
+ return position;
7623
7441
  };
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;
7442
+ var correctPortPositionInElement = function (elementRelativePosition, elementWidth, elementHeight, portMoveableAreas, portSlideRailSVGClassName, element) {
7443
+ //Normalize a point so that it can lie exactly on an area
7444
+ var normalizePortPositionOnMoveableAreas = function (moveableAreas, position) {
7445
+ var lines = moveableAreas.filter(function (area) { return area.length === 2; });
7446
+ var polygons = moveableAreas.filter(function (area) { return area.length >= 3; });
7447
+ var normalizedPosition;
7448
+ //If moveableAreas is lines
7449
+ if (lines.length > 0) {
7450
+ var newPosition_1 = findNearestProjectedPoint({ x: position.x, y: position.y }, lines);
7451
+ if (newPosition_1) {
7452
+ normalizedPosition = newPosition_1;
7453
+ }
7636
7454
  }
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);
7455
+ //If moveableAreas is polygons
7456
+ else if (polygons.length > 0) {
7457
+ var newPosition_2 = { x: position.x, y: position.y };
7458
+ var isContainsInPolygons = polygons.some(function (p) { return checkPointContainsPolygon(newPosition_2, p); });
7459
+ if (isContainsInPolygons) {
7460
+ normalizedPosition = newPosition_2;
7461
+ }
7641
7462
  }
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
- };
7463
+ return normalizedPosition;
7464
+ };
7465
+ var getSlideRailSVG = function (portSlideRailSVGClassName) {
7466
+ if (!element)
7467
+ return;
7468
+ var slideRailSVG = element.querySelector(".".concat(portSlideRailSVGClassName));
7469
+ return slideRailSVG;
7470
+ };
7471
+ //Calculate the position of the 4 vertices of a rectangle relative to element
7472
+ var calculateSlideRailRectSVGPositions = function (slideRailSVG) {
7473
+ var coordinates = getRectangleCorners(slideRailSVG);
7474
+ var ownerSVG = slideRailSVG.ownerSVGElement;
7475
+ var rotationAngle = getElementRotationInfo(ownerSVG);
7476
+ if (rotationAngle !== 0) {
7477
+ var rotationCenterX = elementWidth / 2;
7478
+ var rotationCenterY = elementHeight / 2;
7479
+ coordinates = getRotatedRectangleCoordinates(coordinates, rotationCenterX, rotationCenterY, rotationAngle);
7480
+ }
7481
+ return coordinates;
7482
+ };
7483
+ var normalizePortPositionOnSlideRailSVG = function (portSlideRailSVGClassName, position) {
7484
+ var slideRailSVG = getSlideRailSVG(portSlideRailSVGClassName);
7485
+ if (!slideRailSVG)
7486
+ return;
7487
+ var moveTo;
7488
+ //check and get new position if Rect element
7489
+ if (slideRailSVG instanceof SVGRectElement) {
7490
+ var _a = calculateSlideRailRectSVGPositions(slideRailSVG), a = _a[0], b = _a[1], c = _a[2], d = _a[3]; //Get 4 vertices of rect element
7491
+ var moveableAreas = [
7492
+ [a, b],
7493
+ [b, c],
7494
+ [c, d],
7495
+ [d, a]
7496
+ ];
7497
+ logger.info("Port's moveable areas parsed from svg ".concat(portSlideRailSVGClassName), moveableAreas);
7498
+ var newPosition_3 = normalizePortPositionOnMoveableAreas(moveableAreas, position);
7499
+ if (newPosition_3) {
7500
+ moveTo = newPosition_3;
7501
+ }
7502
+ }
7503
+ else if (slideRailSVG instanceof SVGCircleElement) { //check and get new position if circle element
7504
+ var cx = Number(slideRailSVG.getAttribute('cx'));
7505
+ var cy = Number(slideRailSVG.getAttribute('cy'));
7506
+ var r = Number(slideRailSVG.getAttribute('r'));
7507
+ var circle = Flatten$1.circle(Flatten$1.point(cx, cy), r);
7508
+ var _b = circle.distanceTo(Flatten$1.point(position.x, position.y)), num = _b[0], segment = _b[1];
7509
+ if (num <= r) {
7510
+ moveTo = {
7511
+ x: segment.ps.x,
7512
+ y: segment.ps.y,
7513
+ };
7514
+ }
7650
7515
  }
7516
+ return moveTo;
7517
+ };
7518
+ var newPosition;
7519
+ if (portMoveableAreas && portMoveableAreas.length > 0) { //If moveable areas is defined
7520
+ newPosition = normalizePortPositionOnMoveableAreas(portMoveableAreas, elementRelativePosition);
7651
7521
  }
7652
- return result;
7522
+ else if (portSlideRailSVGClassName) { //If port slide rail svg classname is defined
7523
+ newPosition = normalizePortPositionOnSlideRailSVG(portSlideRailSVGClassName, elementRelativePosition);
7524
+ }
7525
+ return newPosition || elementRelativePosition;
7653
7526
  };
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,
7527
+ var windowsPositionToPaperPosition = function (clientPosition, paperElement, zoom) {
7528
+ var paperRect = paperElement.getBoundingClientRect();
7529
+ // Calculate the position relative to the paper element
7530
+ var xPosOnPaper = (clientPosition.x - paperRect.left) / zoom;
7531
+ var yPosOnPaper = (clientPosition.y - paperRect.top) / zoom;
7532
+ return {
7533
+ x: Math.round(xPosOnPaper),
7534
+ y: Math.round(yPosOnPaper),
7535
+ };
7536
+ };
7537
+
7538
+ var getSVGBBoxOutsideTransformedParent = function (svgElement) {
7539
+ var bbox = svgElement.getBBox(); // Get bounding box of the element
7540
+ var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
7541
+ // Define the four corners of the bounding box
7542
+ var corners = [
7543
+ { x: bbox.x, y: bbox.y },
7544
+ { x: bbox.x + bbox.width, y: bbox.y },
7545
+ { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
7546
+ { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
7547
+ ];
7548
+ // Function to apply the transformation matrix to a point
7549
+ function transformPoint(x, y, matrix) {
7550
+ return {
7551
+ x: matrix.a * x + matrix.c * y + matrix.e,
7552
+ y: matrix.b * x + matrix.d * y + matrix.f
7664
7553
  };
7665
7554
  }
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
- };
7555
+ // Transform each corner according to the matrix
7556
+ if (matrix) {
7557
+ return corners.map(function (corner) {
7558
+ return transformPoint(corner.x, corner.y, matrix);
7559
+ });
7672
7560
  }
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,
7561
+ else {
7562
+ return corners;
7563
+ }
7564
+ };
7565
+ //function returns the array of corners of the bbox of the element after applying the transformation matrix of the parent element
7566
+ var getRotatedSVGBBox = function (svgElement) {
7567
+ var bbox = svgElement.getBBox(); // Get bounding box of the element
7568
+ var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
7569
+ // Define the four corners of the bounding box
7570
+ var corners = [
7571
+ { x: bbox.x, y: bbox.y },
7572
+ { x: bbox.x + bbox.width, y: bbox.y },
7573
+ { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
7574
+ { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
7575
+ ];
7576
+ // Function to apply the transformation matrix to a point
7577
+ function transformPoint(x, y, matrix) {
7578
+ return {
7579
+ x: matrix.a * x + matrix.c * y,
7580
+ y: matrix.b * x + matrix.d * y // + matrix.f
7678
7581
  };
7679
7582
  }
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,
7685
- };
7583
+ // Transform each corner according to the matrix
7584
+ if (matrix) {
7585
+ return corners.map(function (corner) {
7586
+ return transformPoint(corner.x, corner.y, matrix);
7587
+ });
7686
7588
  }
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
- };
7589
+ else {
7590
+ return corners;
7591
+ }
7592
+ };
7593
+
7594
+ var SelectionFrame = function (props) {
7595
+ var propTargetSVGElement = props.targetSVGElement, propWidth = props.width, propHeight = props.height, propFramePadding = props.framePadding, objectX = props.objectX, objectY = props.objectY,
7596
+ // movingOffsetThreshold: propMovingOffsetThreshold,
7597
+ propMovingRate = props.movingRate, propOnMouseDown = props.onMouseDown, propOnMouseUp = props.onMouseUp, propOnMove = props.onMove, propContainer = props.container, propResizability = props.resizability, propOnResize = props.onResize, PropDragDropHandlerElement = props.dragDropHandlerElement, propStrokeWidth = props.strokeWidth, propAnchor = props.anchor, zoom = props.zoom;
7598
+ var bbox = propTargetSVGElement === null || propTargetSVGElement === void 0 ? void 0 : propTargetSVGElement.getBBox();
7599
+ var _a = React.useState(propWidth || (bbox === null || bbox === void 0 ? void 0 : bbox.width) || MIN_ELEMENT_SIZE), width = _a[0], setWidth = _a[1];
7600
+ var _b = React.useState(propHeight || (bbox === null || bbox === void 0 ? void 0 : bbox.height) || MIN_ELEMENT_SIZE), height = _b[0], setHeight = _b[1];
7601
+ React.useEffect(function () {
7602
+ if (propWidth) {
7603
+ setWidth(propWidth);
7698
7604
  }
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);
7605
+ }, [objectX, propWidth]);
7606
+ React.useEffect(function () {
7607
+ if (propHeight) {
7608
+ setHeight(propHeight);
7711
7609
  }
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
- };
7610
+ }, [objectY, propHeight]);
7611
+ var _c = React.useState(objectX !== null && objectX !== void 0 ? objectX : 0), curX = _c[0], setCurX = _c[1];
7612
+ var _d = React.useState(objectY !== null && objectY !== void 0 ? objectY : 0), curY = _d[0], setCurY = _d[1];
7613
+ React.useEffect(function () {
7614
+ if (objectX) {
7615
+ setCurX(objectX);
7723
7616
  }
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);
7617
+ }, [objectX]);
7618
+ React.useEffect(function () {
7619
+ if (objectY) {
7620
+ setCurY(objectY);
7736
7621
  }
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
- };
7622
+ }, [objectY]);
7623
+ var framePadding = propFramePadding || 0;
7624
+ var r = 5;
7625
+ var _e = React.useState(false), draggingRect = _e[0], setDraggingRect = _e[1];
7626
+ var _f = React.useState(false), draggingCircle = _f[0], setDraggingCircle = _f[1];
7627
+ var _g = React.useState(0), startX = _g[0], setStartX = _g[1];
7628
+ var _h = React.useState(0), startY = _h[0], setStartY = _h[1];
7629
+ var _j = React.useState(0), xFromMouse = _j[0], setXFromMouse = _j[1];
7630
+ var _k = React.useState(0), yFromMouse = _k[0], setYFromMouse = _k[1];
7631
+ var _l = React.useState(0), lastMoveTime = _l[0], setLastMoveTime = _l[1];
7632
+ var getMousePosition = function (event) {
7633
+ var position = windowsPositionToPaperPosition({
7634
+ x: event.clientX,
7635
+ y: event.clientY
7636
+ }, propContainer, zoom);
7637
+ return position;
7638
+ };
7639
+ var addRectHandleMouseDown = function (event) {
7640
+ event.stopPropagation();
7641
+ if (!draggingCircle) {
7642
+ setDraggingRect(true);
7643
+ setStartX(event.clientX);
7644
+ setStartY(event.clientY);
7645
+ var mousePosition = getMousePosition(event);
7646
+ var xFromMouse_1 = (curX || 0) - mousePosition.x;
7647
+ var yFromMouse_1 = (curY || 0) - mousePosition.y;
7648
+ setXFromMouse(xFromMouse_1);
7649
+ setYFromMouse(yFromMouse_1);
7748
7650
  }
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);
7651
+ if (propOnMouseDown) {
7652
+ propOnMouseDown(event);
7653
+ }
7654
+ };
7655
+ var rectHandleMouseMove = React.useCallback(function (event) {
7656
+ var mouseEvent = event;
7657
+ if (draggingRect) {
7658
+ if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
7659
+ return;
7660
+ }
7661
+ //Coordinates of mouse on paper.
7662
+ var mousePosition = getMousePosition(mouseEvent);
7663
+ var newX = mousePosition.x + xFromMouse;
7664
+ var newY = mousePosition.y + yFromMouse;
7665
+ if (propOnMove) {
7666
+ setCurX(newX);
7667
+ setCurY(newY);
7668
+ propOnMove(newX, newY);
7669
+ setLastMoveTime(Date.now());
7670
+ setStartX(mouseEvent.clientX);
7671
+ setStartY(mouseEvent.clientY);
7672
+ }
7673
+ }
7674
+ }, [draggingRect, propOnMove, propMovingRate, startX, startY, lastMoveTime, xFromMouse, yFromMouse, zoom]);
7675
+ React.useEffect(function () {
7676
+ var addRectHandleMouseUp = function () {
7677
+ setDraggingRect(false);
7678
+ setXFromMouse(0);
7679
+ setYFromMouse(0);
7680
+ };
7681
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mousemove', rectHandleMouseMove);
7682
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mouseup', addRectHandleMouseUp);
7683
+ return function () {
7684
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mousemove', rectHandleMouseMove);
7685
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mouseup', addRectHandleMouseUp);
7686
+ };
7687
+ }, [propContainer, rectHandleMouseMove, zoom]);
7688
+ var circleHandleMouseDown = function (event) {
7689
+ event.stopPropagation();
7690
+ if (!draggingRect) {
7691
+ setStartX(event.clientX);
7692
+ setStartY(event.clientY);
7693
+ setDraggingCircle(true);
7761
7694
  }
7695
+ };
7696
+ React.useEffect(function () {
7697
+ logger.debug('SelectionFrame: circleHandleMouseDown triggered', {
7698
+ draggingCircle: draggingCircle,
7699
+ startX: startX,
7700
+ startY: startY,
7701
+ width: width,
7702
+ height: height,
7703
+ propMovingRate: propMovingRate
7704
+ });
7705
+ var circleHandleMouseMove = function (event) {
7706
+ var mouseEvent = event;
7707
+ if (draggingCircle) {
7708
+ var offsetX = mouseEvent.clientX - startX;
7709
+ var offsetY = mouseEvent.clientY - startY;
7710
+ if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
7711
+ return;
7712
+ }
7713
+ setStartX(mouseEvent.clientX);
7714
+ setStartY(mouseEvent.clientY);
7715
+ setLastMoveTime(Date.now());
7716
+ var newWidth = width;
7717
+ var newHeight = height;
7718
+ if (propResizability.keepRatio) {
7719
+ var resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
7720
+ var increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
7721
+ offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
7722
+ offsetY = increasing ? resizingRatio * height : -resizingRatio * height;
7723
+ }
7724
+ newWidth += offsetX;
7725
+ newHeight += offsetY;
7726
+ if (newWidth < MIN_ELEMENT_SIZE) {
7727
+ newWidth = MIN_ELEMENT_SIZE;
7728
+ }
7729
+ if (newHeight < MIN_ELEMENT_SIZE) {
7730
+ newHeight = MIN_ELEMENT_SIZE;
7731
+ }
7732
+ setWidth(newWidth);
7733
+ setHeight(newHeight);
7734
+ if (propOnResize) {
7735
+ propOnResize(newWidth, newHeight);
7736
+ }
7737
+ }
7738
+ };
7739
+ var circleHandleMouseUp = function () {
7740
+ setDraggingCircle(false);
7741
+ };
7742
+ var container = propContainer;
7743
+ container.addEventListener('mousemove', circleHandleMouseMove);
7744
+ container.addEventListener('mouseup', circleHandleMouseUp);
7745
+ //logging the start of the circle handle mouse move
7746
+ logger.debug('SelectionFrame: circleHandleMouseMove started', container);
7747
+ return function () {
7748
+ container.removeEventListener('mousemove', circleHandleMouseMove);
7749
+ container.removeEventListener('mouseup', circleHandleMouseUp);
7750
+ //logging the end of the circle handle mouse move
7751
+ logger.debug('SelectionFrame: circleHandleMouseMove ended', container);
7752
+ };
7753
+ }, [draggingCircle, width, height, curX, curY, lastMoveTime, propContainer, propMovingRate, propOnResize, propResizability, startX, startY]);
7754
+ var rectangleSize = Math.max(width, height);
7755
+ var leftX = framePadding;
7756
+ var topY = framePadding;
7757
+ if (propAnchor === exports.PositioningAnchor.Center) {
7758
+ leftX -= rectangleSize / 2;
7759
+ topY -= rectangleSize / 2;
7762
7760
  }
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
- };
7761
+ return (React.createElement(React.Fragment, null,
7762
+ PropDragDropHandlerElement && React.createElement(PropDragDropHandlerElement, { dragging: draggingRect, onMouseDown: addRectHandleMouseDown }),
7763
+ React.createElement("rect", { vectorEffect: "non-scaling-stroke", x: leftX, y: topY, width: width, height: height, fill: 'none', stroke: 'blue', strokeWidth: propStrokeWidth || 5, cursor: draggingRect ? 'grabbing' : 'grab', onMouseDown: addRectHandleMouseDown, onMouseUp: propOnMouseUp }),
7764
+ propResizability.enabled ?
7765
+ (React.createElement("circle", { cursor: 'se-resize', cx: leftX + width, cy: topY + height, r: r, fill: 'blue', stroke: 'blue', onMouseDown: circleHandleMouseDown })) : null));
7766
+ };
7767
+
7768
+ var useSelectionFrame = function (props) {
7769
+ React.useEffect(function () {
7770
+ //log selection frame rendering
7771
+ if (props.targetSVGElement) {
7772
+ console.debug('Rendering SelectionFrame for targetSVGElement:', props.targetSVGElement);
7773
7773
  }
7774
7774
  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);
7775
+ console.warn('No targetSVGElement provided for SelectionFrame.');
7786
7776
  }
7787
- }
7788
- return replacementPosition;
7777
+ if (props.targetSVGElement && props.container) {
7778
+ //render SelectionFrame component to the parent element of the targetSVGElement
7779
+ if (props.container) {
7780
+ var svg_1 = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
7781
+ svg_1.style.overflow = 'visible';
7782
+ svg_1.style.outline = 'none';
7783
+ props.targetSVGElement.appendChild(svg_1);
7784
+ var root_1 = createRoot(svg_1);
7785
+ root_1.render(React.createElement(SelectionFrame, __assign({}, props, { container: props.container })));
7786
+ return function () {
7787
+ root_1.unmount();
7788
+ if (props.targetSVGElement) {
7789
+ props.targetSVGElement.removeChild(svg_1);
7790
+ }
7791
+ };
7792
+ }
7793
+ }
7794
+ }, [props]);
7795
+ };
7796
+
7797
+ var eventEmitter = new EventEmitter();
7798
+ var emitPaperClicked = function (ev) {
7799
+ eventEmitter.emit(EVENT_NAME.PAPER_CLICK, ev);
7789
7800
  };
7790
- var getRelativePosition = function (clientPosition, relativeElement) {
7791
- var relativeRect = relativeElement.getBoundingClientRect();
7801
+ var onPaperClicked = function (callback) {
7802
+ eventEmitter.on(EVENT_NAME.PAPER_CLICK, callback);
7803
+ var off = function () {
7804
+ eventEmitter.off(EVENT_NAME.PAPER_CLICK, callback);
7805
+ };
7792
7806
  return {
7793
- x: clientPosition.x - relativeRect.left,
7794
- y: clientPosition.y - relativeRect.top,
7807
+ off: off
7795
7808
  };
7796
7809
  };
7797
- var getFourVertexesOfBBoxFromElement = function (element) {
7798
- var absolutePosition = getAbsolutePosition(element);
7799
- var vertex1Position = {
7800
- x: absolutePosition.x,
7801
- y: absolutePosition.y
7810
+ var emitPortMouseUp = function (ev, port, elementId) {
7811
+ eventEmitter.emit(EVENT_NAME.PORT_MOUSE_UP, ev, port, elementId);
7812
+ };
7813
+ var onPortMouseUp = function (callback) {
7814
+ eventEmitter.on(EVENT_NAME.PORT_MOUSE_UP, callback);
7815
+ var off = function () {
7816
+ eventEmitter.off(EVENT_NAME.PORT_MOUSE_UP, callback);
7802
7817
  };
7803
- var vertex2Position = {
7804
- x: absolutePosition.x + element.size.width,
7805
- y: absolutePosition.y
7818
+ return {
7819
+ off: off
7806
7820
  };
7807
- var vertex3Position = {
7808
- x: absolutePosition.x + element.size.width,
7809
- y: absolutePosition.y + element.size.height
7821
+ };
7822
+ var emitPortMouseDown = function (ev, port, elementId) {
7823
+ eventEmitter.emit(EVENT_NAME.PORT_MOUSE_DOWN, ev, port, elementId);
7824
+ };
7825
+ var onPortMouseDown = function (callback) {
7826
+ eventEmitter.on(EVENT_NAME.PORT_MOUSE_DOWN, callback);
7827
+ var off = function () {
7828
+ eventEmitter.off(EVENT_NAME.PORT_MOUSE_DOWN, callback);
7810
7829
  };
7811
- var vertex4Position = {
7812
- x: absolutePosition.x,
7813
- y: absolutePosition.y + element.size.height
7830
+ return {
7831
+ off: off
7814
7832
  };
7815
- return [vertex1Position, vertex2Position, vertex3Position, vertex4Position];
7816
7833
  };
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,
7834
+ var emitPortMoved = function (port, elementId, oldPosition, newPosition) {
7835
+ eventEmitter.emit(EVENT_NAME.PORT_MOVED, port, elementId, oldPosition, newPosition);
7836
+ };
7837
+ var onPortMoved = function (callback) {
7838
+ eventEmitter.on(EVENT_NAME.PORT_MOVED, callback);
7839
+ var off = function () {
7840
+ eventEmitter.off(EVENT_NAME.PORT_MOVED, callback);
7823
7841
  };
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
7842
  return {
7835
- x: x,
7836
- y: y,
7843
+ off: off
7844
+ };
7845
+ };
7846
+ var emitElementMoved = function (element, oldPosition, newPosition) {
7847
+ eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(element.id));
7848
+ };
7849
+ var onElementMoved = function (elementId, callback) {
7850
+ eventEmitter.on("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
7851
+ var off = function () {
7852
+ eventEmitter.off("".concat(EVENT_NAME.ELEMENT_MOVED, "_").concat(elementId), callback);
7853
+ };
7854
+ return {
7855
+ off: off
7856
+ };
7857
+ };
7858
+ var emitElementResized = function (element, oldSize, newSize) {
7859
+ eventEmitter.emit("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(element.id), oldSize, newSize);
7860
+ };
7861
+ var onElementResized = function (elementId, callback) {
7862
+ eventEmitter.on("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
7863
+ var off = function () {
7864
+ eventEmitter.off("".concat(EVENT_NAME.ELEMENT_RESIZED, "_").concat(elementId), callback);
7865
+ };
7866
+ return {
7867
+ off: off
7868
+ };
7869
+ };
7870
+ var emitCommandDeleteSelectedPort = function () {
7871
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT);
7872
+ };
7873
+ var onCommandDeleteSelectedPort = function (callback) {
7874
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
7875
+ var off = function () {
7876
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_PORT, callback);
7877
+ };
7878
+ return {
7879
+ off: off
7880
+ };
7881
+ };
7882
+ var emitCommandDeleteSelectedElement = function () {
7883
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT);
7884
+ };
7885
+ var onCommandDeleteSelectedElement = function (callback) {
7886
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
7887
+ var off = function () {
7888
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_ELEMENT, callback);
7889
+ };
7890
+ return {
7891
+ off: off
7892
+ };
7893
+ };
7894
+ var emitCommandDeleteSelectedLink = function () {
7895
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK);
7896
+ };
7897
+ var onCommandDeleteSelectedLink = function (callback) {
7898
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
7899
+ var off = function () {
7900
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_LINK, callback);
7901
+ };
7902
+ return {
7903
+ off: off
7904
+ };
7905
+ };
7906
+ var emitCommandDeleteSelectedText = function () {
7907
+ eventEmitter.emit(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT);
7908
+ };
7909
+ var onCommandDeleteSelectedText = function (callback) {
7910
+ eventEmitter.on(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
7911
+ var off = function () {
7912
+ eventEmitter.off(EVENT_NAME.COMMAND_DELETE_SELECTED_TEXT, callback);
7913
+ };
7914
+ return {
7915
+ off: off
7916
+ };
7917
+ };
7918
+ var emitElementLinkStarted = function (elementLink) {
7919
+ eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_STARTED, elementLink);
7920
+ };
7921
+ var onElementLinkStarted = function (callback) {
7922
+ eventEmitter.on(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
7923
+ var off = function () {
7924
+ eventEmitter.off(EVENT_NAME.ELEMENT_LINK_STARTED, callback);
7925
+ };
7926
+ return {
7927
+ off: off
7928
+ };
7929
+ };
7930
+ var emitElementLinkEnded = function (elementLink) {
7931
+ eventEmitter.emit(EVENT_NAME.ELEMENT_LINK_ENDED, elementLink);
7932
+ };
7933
+ var onElementLinkEnded = function (callback) {
7934
+ eventEmitter.on(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
7935
+ var off = function () {
7936
+ eventEmitter.off(EVENT_NAME.ELEMENT_LINK_ENDED, callback);
7937
+ };
7938
+ return {
7939
+ off: off
7940
+ };
7941
+ };
7942
+ var emitElementSelected = function (element) {
7943
+ eventEmitter.emit(EVENT_NAME.ELEMENT_SELECTED, element);
7944
+ };
7945
+ var onElementSelected = function (callback) {
7946
+ eventEmitter.on(EVENT_NAME.ELEMENT_SELECTED, callback);
7947
+ var off = function () {
7948
+ eventEmitter.off(EVENT_NAME.ELEMENT_SELECTED, callback);
7949
+ };
7950
+ return {
7951
+ off: off
7952
+ };
7953
+ };
7954
+ var emitCommandRenderElement = function (elementId) {
7955
+ eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_ELEMENT, elementId);
7956
+ };
7957
+ var onCommandRenderElement = function (callback) {
7958
+ eventEmitter.on(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
7959
+ var off = function () {
7960
+ eventEmitter.off(EVENT_NAME.COMMAND_RENDER_ELEMENT, callback);
7961
+ };
7962
+ return {
7963
+ off: off
7964
+ };
7965
+ };
7966
+ var emitPortSelected = function (port, elementId) {
7967
+ eventEmitter.emit(EVENT_NAME.PORT_SELECTED, port, elementId);
7968
+ };
7969
+ var onPortSelected = function (callback) {
7970
+ eventEmitter.on(EVENT_NAME.PORT_SELECTED, callback);
7971
+ var off = function () {
7972
+ eventEmitter.off(EVENT_NAME.PORT_SELECTED, callback);
7973
+ };
7974
+ return {
7975
+ off: off
7976
+ };
7977
+ };
7978
+ var emitCommandRenderPort = function (portId, elementId) {
7979
+ eventEmitter.emit(EVENT_NAME.COMMAND_RENDER_PORT, portId, elementId);
7980
+ };
7981
+ var onCommandRenderPort = function (callback) {
7982
+ eventEmitter.on(EVENT_NAME.COMMAND_RENDER_PORT, callback);
7983
+ var off = function () {
7984
+ eventEmitter.off(EVENT_NAME.COMMAND_RENDER_PORT, callback);
7985
+ };
7986
+ return {
7987
+ off: off
7988
+ };
7989
+ };
7990
+ var emitTextSelected = function (text) {
7991
+ eventEmitter.emit(EVENT_NAME.TEXT_SELECTED, text);
7992
+ };
7993
+ var onTextSelected = function (callback) {
7994
+ eventEmitter.on(EVENT_NAME.TEXT_SELECTED, callback);
7995
+ var off = function () {
7996
+ eventEmitter.off(EVENT_NAME.TEXT_SELECTED, callback);
7837
7997
  };
7838
- };
7839
- //get absolute position of element
7840
- var getPortAbsolutePosition = function (port, element) {
7841
- var elementAbsolutePosition = getAbsolutePosition(element);
7842
7998
  return {
7843
- x: elementAbsolutePosition.x + port.position.x,
7844
- y: elementAbsolutePosition.y + port.position.y,
7999
+ off: off
7845
8000
  };
7846
8001
  };
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,
7856
- };
7857
- if (element.positionAnchor === exports.PositioningAnchor.Center) {
7858
- result.x += element.size.width / 2;
7859
- result.y += element.size.height / 2;
8002
+ var paperEventEmitterContext = React.createContext({
8003
+ emitter: eventEmitter,
8004
+ emitPaperClicked: emitPaperClicked,
8005
+ onPaperClicked: onPaperClicked,
8006
+ emitPortMouseUp: emitPortMouseUp,
8007
+ onPortMouseUp: onPortMouseUp,
8008
+ emitPortMouseDown: emitPortMouseDown,
8009
+ onPortMouseDown: onPortMouseDown,
8010
+ emitPortMoved: emitPortMoved,
8011
+ onPortMoved: onPortMoved,
8012
+ emitPortSelected: emitPortSelected,
8013
+ onPortSelected: onPortSelected,
8014
+ emitElementMoved: emitElementMoved,
8015
+ onElementMoved: onElementMoved,
8016
+ emitElementResized: emitElementResized,
8017
+ onElementResized: onElementResized,
8018
+ emitElementSelected: emitElementSelected,
8019
+ onElementSelected: onElementSelected,
8020
+ emitCommandRenderElement: emitCommandRenderElement,
8021
+ onCommandRenderElement: onCommandRenderElement,
8022
+ emitCommandDeleteSelectedPort: emitCommandDeleteSelectedPort,
8023
+ onCommandDeleteSelectedPort: onCommandDeleteSelectedPort,
8024
+ emitCommandDeleteSelectedElement: emitCommandDeleteSelectedElement,
8025
+ onCommandDeleteSelectedElement: onCommandDeleteSelectedElement,
8026
+ emitCommandDeleteSelectedLink: emitCommandDeleteSelectedLink,
8027
+ onCommandDeleteSelectedLink: onCommandDeleteSelectedLink,
8028
+ emitCommandDeleteSelectedText: emitCommandDeleteSelectedText,
8029
+ onCommandDeleteSelectedText: onCommandDeleteSelectedText,
8030
+ emitElementLinkStarted: emitElementLinkStarted,
8031
+ onElementLinkStarted: onElementLinkStarted,
8032
+ emitElementLinkEnded: emitElementLinkEnded,
8033
+ onElementLinkEnded: onElementLinkEnded,
8034
+ emitTextSelected: emitTextSelected,
8035
+ onTextSelected: onTextSelected,
8036
+ emitCommandRenderPort: emitCommandRenderPort,
8037
+ onCommandRenderPort: onCommandRenderPort,
8038
+ });
8039
+
8040
+ var editorConfigurationContext = React.createContext(null);
8041
+ var useEditorConfiguration = function () {
8042
+ var context = React.useContext(editorConfigurationContext);
8043
+ if (!context) {
8044
+ throw new Error("useEditorConfiguration must be used within an EditorConfigurationProvider");
7860
8045
  }
7861
- return result;
8046
+ return context;
7862
8047
  };
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),
8048
+ var EditorConfigurationContextProvider = editorConfigurationContext.Provider;
8049
+
8050
+ /**
8051
+ * Zoom context to manage zoom level and related state.
8052
+ * This context can be used to provide zoom functionality across the application.
8053
+ */
8054
+ var zoomContext = React.createContext(null);
8055
+ var ZoomContextProvider = function (_a) {
8056
+ var children = _a.children;
8057
+ var _b = React.useState(1), zoom = _b[0], setZoom = _b[1];
8058
+ var _c = React.useState(0), scrollLeft = _c[0], setScrollLeft = _c[1];
8059
+ var _d = React.useState(0), scrollTop = _d[0], setScrollTop = _d[1];
8060
+ var wrapperRef = React.useRef(null);
8061
+ var contentRef = React.useRef(null);
8062
+ var handleWheel = function (e) {
8063
+ // Chỉ zoom khi giữ Ctrl
8064
+ if (!e.ctrlKey)
8065
+ return;
8066
+ e.preventDefault();
8067
+ var delta = -e.deltaY;
8068
+ var zoomFactor = 0.05;
8069
+ var newZoom = zoom + (delta > 0 ? zoomFactor : -zoomFactor);
8070
+ newZoom = Math.max(0.1, Math.min(newZoom, 4));
8071
+ if (!wrapperRef.current || !contentRef.current)
8072
+ return;
8073
+ var wrapper = wrapperRef.current;
8074
+ var content = contentRef.current;
8075
+ // Get bounding rectangle of the content
8076
+ var rect = content.getBoundingClientRect();
8077
+ var offsetX = e.clientX - rect.left;
8078
+ var offsetY = e.clientY - rect.top;
8079
+ var percentX = offsetX / (content.offsetWidth);
8080
+ var percentY = offsetY / (content.offsetHeight);
8081
+ console.log(offsetX, offsetY, content.offsetWidth, content.offsetHeight, percentX, percentY);
8082
+ // Old width and height of content
8083
+ var prevWidth = content.offsetWidth * zoom;
8084
+ var prevHeight = content.offsetHeight * zoom;
8085
+ var newWidth = content.offsetWidth * newZoom;
8086
+ var newHeight = content.offsetHeight * newZoom;
8087
+ var scrollLeft = wrapper.scrollLeft + (percentX * (newWidth - prevWidth));
8088
+ var scrollTop = wrapper.scrollTop + (percentY * (newHeight - prevHeight));
8089
+ setZoom(newZoom);
8090
+ setScrollLeft(scrollLeft);
8091
+ setScrollTop(scrollTop);
7868
8092
  };
7869
- return position;
8093
+ React.useLayoutEffect(function () {
8094
+ var _a;
8095
+ (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({
8096
+ left: scrollLeft,
8097
+ top: scrollTop,
8098
+ });
8099
+ }, [zoom, scrollLeft, scrollTop]);
8100
+ var resetZoom = function () {
8101
+ setZoom(1);
8102
+ };
8103
+ React.useEffect(function () {
8104
+ var preventBrowserZoom = function (e) {
8105
+ if (e.ctrlKey || e.metaKey) {
8106
+ e.preventDefault();
8107
+ }
8108
+ };
8109
+ window.addEventListener("wheel", preventBrowserZoom, { passive: false });
8110
+ return function () {
8111
+ window.removeEventListener("wheel", preventBrowserZoom);
8112
+ };
8113
+ }, []);
8114
+ return (React.createElement(zoomContext.Provider, { value: { zoom: zoom, setZoom: setZoom, resetZoom: resetZoom } },
8115
+ React.createElement("div", { ref: wrapperRef, onWheel: handleWheel, style: {
8116
+ width: "100vw",
8117
+ height: "92vh",
8118
+ overflow: "auto",
8119
+ } },
8120
+ React.createElement("div", { ref: contentRef, style: {
8121
+ transform: "scale(".concat(zoom, ")"),
8122
+ transformOrigin: "top left",
8123
+ // transition: "transform 0.1s linear",
8124
+ } }, children))));
7870
8125
  };
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;
8126
+ var useZoomContext = function () {
8127
+ var context = React.useContext(zoomContext);
8128
+ if (!context) {
8129
+ throw new Error("useZoomContext must be used within a ZoomContextProvider");
8130
+ }
8131
+ return context;
8132
+ };
8133
+
8134
+ var Text = React.forwardRef(function (_a, ref) {
8135
+ var id = _a.id, content = _a.content, x = _a.x, y = _a.y, width = _a.width, height = _a.height, editable = _a.editable, _b = _a.selectable, selectable = _b === void 0 ? true : _b, _c = _a.align, align = _c === void 0 ? exports.TextAlign.left : _c, fontSizeProp = _a.fontSize, border = _a.border, container = _a.container, parentAbsolutePosition = _a.parentAbsolutePosition, onSelected = _a.onSelected, onMoved = _a.onMoved, onResized = _a.onResized, onContentChanged = _a.onContentChanged;
8136
+ var _d = React.useState(false), isSelected = _d[0], setIsSelected = _d[1];
8137
+ var _e = React.useState(false), isEditing = _e[0], setIsEditing = _e[1];
8138
+ var textFontSize = useEditorConfiguration().textFontSize;
8139
+ var zoom = useZoomContext().zoom;
8140
+ var absolutePosition = React.useMemo(function () {
8141
+ var _a, _b;
8142
+ return {
8143
+ x: ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0) + x,
8144
+ y: ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0) + y,
8145
+ };
8146
+ }, [x, y, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y]);
8147
+ var svgRef = React.useRef();
8148
+ var _f = React.useContext(paperEventEmitterContext), onPaperClicked = _f.onPaperClicked, emitTextSelected = _f.emitTextSelected, onPortSelected = _f.onPortSelected, onElementSelected = _f.onElementSelected, onTextSelected = _f.onTextSelected;
8149
+ React.useEffect(function () {
8150
+ var paperClickListener = onPaperClicked(function (ev) {
8151
+ var _a;
8152
+ var textareaELe = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('textarea');
8153
+ if (ev.target !== textareaELe) {
8154
+ setIsSelected(false);
8155
+ setIsEditing(false);
7882
8156
  }
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;
8157
+ });
8158
+ var portSelectedListener = onPortSelected(function (port) {
8159
+ setIsSelected(false);
8160
+ setIsEditing(false);
8161
+ });
8162
+ var elementSelectedListener = onElementSelected(function (element) {
8163
+ setIsSelected(false);
8164
+ setIsEditing(false);
8165
+ });
8166
+ var textSelectedListener = onTextSelected(function (text) {
8167
+ if (text.id !== id) {
8168
+ setIsSelected(false);
8169
+ setIsEditing(false);
7890
8170
  }
7891
- }
7892
- return normalizedPosition;
7893
- };
7894
- var getSlideRailSVG = function (portSlideRailSVGClassName) {
7895
- if (!element)
8171
+ });
8172
+ return function () {
8173
+ paperClickListener.off();
8174
+ portSelectedListener.off();
8175
+ elementSelectedListener.off();
8176
+ textSelectedListener.off();
8177
+ };
8178
+ }, []);
8179
+ //Handle click on svg element
8180
+ var handleClick = function (ev) {
8181
+ if (!selectable)
7896
8182
  return;
7897
- var slideRailSVG = element.querySelector(".".concat(portSlideRailSVGClassName));
7898
- return slideRailSVG;
7899
- };
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;
8183
+ ev.stopPropagation();
8184
+ var position = {
8185
+ x: x,
8186
+ y: y,
8187
+ };
8188
+ var text = {
8189
+ id: id,
8190
+ content: content,
8191
+ position: position,
8192
+ size: {
8193
+ width: width,
8194
+ height: height,
8195
+ },
8196
+ editable: editable
8197
+ };
8198
+ setIsSelected(true);
8199
+ onSelected && onSelected(text);
8200
+ emitTextSelected(text);
7911
8201
  };
7912
- var normalizePortPositionOnSlideRailSVG = function (portSlideRailSVGClassName, position) {
7913
- var slideRailSVG = getSlideRailSVG(portSlideRailSVGClassName);
7914
- if (!slideRailSVG)
8202
+ var handleChangeText = function (ev) {
8203
+ if (!editable)
7915
8204
  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
- }
8205
+ onContentChanged === null || onContentChanged === void 0 ? void 0 : onContentChanged(ev, ev.target.value);
8206
+ };
8207
+ useSelectionFrame({
8208
+ objectX: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.x,
8209
+ objectY: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.y,
8210
+ container: container,
8211
+ targetSVGElement: (isSelected && svgRef.current) ? svgRef.current : undefined,
8212
+ resizability: {
8213
+ enabled: onResized ? true : false,
8214
+ keepRatio: false,
8215
+ },
8216
+ onMove: onMoved,
8217
+ onResize: onResized,
8218
+ strokeWidth: 3,
8219
+ zoom: zoom,
8220
+ });
8221
+ var textAlign = React.useMemo(function () {
8222
+ switch (align) {
8223
+ case exports.TextAlign.left:
8224
+ return 'left';
8225
+ case exports.TextAlign.right:
8226
+ return 'right';
8227
+ case exports.TextAlign.center:
8228
+ return 'center';
8229
+ default:
8230
+ return 'left';
7931
8231
  }
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
- };
8232
+ }, [align]);
8233
+ var fontSize = fontSizeProp || textFontSize || TEXT_FONT_SIZE;
8234
+ var borderStyle = border || 'none';
8235
+ return (React.createElement("svg", { style: {
8236
+ overflow: "visible",
8237
+ pointerEvents: selectable ? undefined : 'none',
8238
+ }, x: x, y: y, ref: function (node) {
8239
+ svgRef.current = node;
8240
+ if (typeof ref === 'function') {
8241
+ ref(node);
7943
8242
  }
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);
7953
- }
7954
- return newPosition || elementRelativePosition;
7955
- };
8243
+ else if (ref) {
8244
+ ref.current = node;
8245
+ }
8246
+ }, onClick: handleClick },
8247
+ React.createElement("foreignObject", { width: width, height: height, style: {
8248
+ overflow: 'visible',
8249
+ userSelect: 'none',
8250
+ WebkitUserSelect: 'none',
8251
+ msUserSelect: 'none'
8252
+ } },
8253
+ React.createElement("div", { style: {
8254
+ width: '100%',
8255
+ height: '100%',
8256
+ borderWidth: '1px',
8257
+ borderColor: '#ccc',
8258
+ borderStyle: borderStyle,
8259
+ // whiteSpace: 'pre-wrap',
8260
+ boxSizing: 'border-box',
8261
+ } },
8262
+ React.createElement("textarea", { style: {
8263
+ fontFamily: 'initial',
8264
+ display: 'inline-block',
8265
+ width: '100%',
8266
+ height: '100%',
8267
+ overflow: 'hidden',
8268
+ border: 'none',
8269
+ background: 'transparent',
8270
+ outline: 'none',
8271
+ resize: 'none',
8272
+ textAlign: textAlign,
8273
+ fontSize: fontSize,
8274
+ }, readOnly: !isEditing, onDoubleClick: function () {
8275
+ if (editable) {
8276
+ setIsEditing(true);
8277
+ }
8278
+ }, value: content, onChange: handleChangeText })))));
8279
+ });
8280
+ var Text$1 = React.memo(Text);
7956
8281
 
7957
8282
  var Port1 = React.forwardRef(function (props, ref) {
7958
8283
  var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, container = props.container, label = props.label, parentAbsolutePosition = props.parentAbsolutePosition, onPortLabelMoved = props.onPortLabelMoved, onPortLabelResized = props.onPortLabelResized, onPortLabelContentChanged = props.onPortLabelContentChanged, onSelected = props.onSelected, onMouseDown = props.onMouseDown, onMouseUp = props.onMouseUp, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, onMouseMove = props.onMouseMove, calculateRotationAngle = props.calculateRotationAngle,
7959
8284
  // 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;
8005
- return {
8006
- length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
8007
- angle: Math.atan2(lengthY, lengthX)
8008
- };
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]
8030
- };
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()
8041
- };
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);
8285
+ renderShape = props.renderShape, children = props.children;
8286
+ var textRef = React.useRef(null);
8287
+ var rotationAngle = React.useMemo(function () {
8288
+ if (!calculateRotationAngle)
8289
+ return 0;
8290
+ return calculateRotationAngle(x, y);
8291
+ }, [calculateRotationAngle, x, y]);
8292
+ var renderLabel = function (label) {
8293
+ var content = label.content, size = label.size;
8294
+ var position = label.position || PORT_LABEL_POSITION;
8295
+ return React.createElement(Text$1, { id: label.id, ref: textRef, x: x + position.x, y: y + position.y, parentAbsolutePosition: parentAbsolutePosition, width: size.width, height: size.height, editable: label.editable, selectable: label.selectable, content: content, fontSize: label.fontSize, border: label.border, container: container, onMoved: function (xOnPaper, yOnPaper) {
8296
+ if (onPortLabelMoved) {
8297
+ var relativePosInSideEle = transformAbsPositionToRelativePositionInsideElement({ x: xOnPaper, y: yOnPaper }, parentAbsolutePosition);
8298
+ var newXPort = relativePosInSideEle.x - x;
8299
+ var newYPort = relativePosInSideEle.y - y;
8300
+ onPortLabelMoved(newXPort, newYPort, id);
8301
+ }
8302
+ }, onResized: function (width, height) { return onPortLabelResized === null || onPortLabelResized === void 0 ? void 0 : onPortLabelResized(width, height, id); }, onContentChanged: function (ev, newValue) { return onPortLabelContentChanged === null || onPortLabelContentChanged === void 0 ? void 0 : onPortLabelContentChanged(ev, newValue, id); } });
8303
+ };
8304
+ var renderedShape = React.useMemo(function () {
8305
+ if (renderShape) {
8306
+ var RenderShape = renderShape;
8307
+ return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle }), children));
8103
8308
  }
8104
8309
  else {
8105
- return getAddIndex(middleIndex, endIndex);
8106
- }
8107
- };
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;
8148
- }
8310
+ return React.createElement(Circle, { onMouseDown: function (e) { return onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(id, e); }, onMouseUp: function (e) { return onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(id, e); }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseMove: function (e) { return onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(id, e); }, onClick: function (e) { return onSelected === null || onSelected === void 0 ? void 0 : onSelected(id, e); }, ref: ref, x: x, y: y, positioningAnchor: exports.PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" }, children);
8149
8311
  }
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
- }
8312
+ }, [props]);
8313
+ return (React.createElement(React.Fragment, null,
8314
+ renderedShape,
8315
+ label && renderLabel(label)));
8316
+ });
8317
+ var Port = React.memo(Port1);
8161
8318
 
8162
8319
  //Defined remove icon for element link, shown when element link is selected.
8163
8320
  function CloseIcon(_a) {
@@ -8186,17 +8343,34 @@ var IElementLink = function (_a) {
8186
8343
  }), selectedLabelRef = _l[0], setSelectedLabelRef = _l[1];
8187
8344
  var _m = React.useState(false), isSelectedLink = _m[0], setIsSelectedLink = _m[1];
8188
8345
  var _o = React.useContext(paperEventEmitterContext), onPaperClicked = _o.onPaperClicked, onElementSelected = _o.onElementSelected;
8346
+ var zoom = useZoomContext().zoom;
8189
8347
  var pathRef = React.useRef(null);
8190
8348
  var labelRef = React.useRef(null);
8191
8349
  var sourceLabelRef = React.useRef(null);
8192
8350
  var targetLabelRef = React.useRef(null);
8193
8351
  var isFirstRender = React.useRef(true);
8194
8352
  var onPointsChangedRef = React.useRef();
8353
+ var lastUpdatedPoints = React.useRef(Date.now());
8195
8354
  var angleMarkerStart = '0';
8196
8355
  var angleMarkerEnd = '0';
8197
8356
  var markerStartPosition;
8198
8357
  var markerEndPosition;
8199
8358
  var centerPathPosition = undefined;
8359
+ // Throttle pointsProp updates to avoid excessive renders
8360
+ React.useEffect(function () {
8361
+ var delay = 100; // 100ms delay
8362
+ var timeoutId = setTimeout(function () {
8363
+ var now = Date.now();
8364
+ if (now - lastUpdatedPoints.current >= delay) {
8365
+ setPoints(pointsProp || []);
8366
+ lastUpdatedPoints.current = now;
8367
+ }
8368
+ }, delay - (Date.now() - lastUpdatedPoints.current));
8369
+ return function () {
8370
+ clearTimeout(timeoutId);
8371
+ };
8372
+ // Use JSON.stringify for deep comparison
8373
+ }, [JSON.stringify(pointsProp)]);
8200
8374
  React.useEffect(function () {
8201
8375
  var paperClickListener = onPaperClicked(function () {
8202
8376
  setSelectedLabelRef({
@@ -8248,10 +8422,13 @@ var IElementLink = function (_a) {
8248
8422
  var handleMouseMove = function (ev) {
8249
8423
  var mouseEvent = ev;
8250
8424
  if (isDragging && draggingPointIndex !== undefined && container) {
8251
- var offset_1 = getRelativePosition({ x: mouseEvent.clientX, y: mouseEvent.clientY }, container);
8425
+ var paperPosition_1 = windowsPositionToPaperPosition({
8426
+ x: mouseEvent.clientX,
8427
+ y: mouseEvent.clientY
8428
+ }, container, zoom);
8252
8429
  setPoints(function (prev) {
8253
8430
  var temp = __spreadArray([], prev, true);
8254
- temp[draggingPointIndex] = offset_1;
8431
+ temp[draggingPointIndex] = paperPosition_1;
8255
8432
  return temp;
8256
8433
  });
8257
8434
  }
@@ -8266,23 +8443,19 @@ var IElementLink = function (_a) {
8266
8443
  container === null || container === void 0 ? void 0 : container.removeEventListener('mousemove', handleMouseMove);
8267
8444
  container === null || container === void 0 ? void 0 : container.removeEventListener('mouseup', mouseUp);
8268
8445
  };
8269
- }, [container, isDragging, draggingPointIndex]);
8446
+ }, [container, isDragging, draggingPointIndex, zoom]);
8270
8447
  var handleMouseDownOnPath = function (ev) {
8271
8448
  ev.preventDefault();
8272
- var svgContainer = ev.target.ownerSVGElement;
8273
8449
  //add point if click on path
8274
8450
  setIsDragging(true);
8275
- var rect = svgContainer.getBoundingClientRect();
8276
- var offsetX = ev.clientX - rect.left;
8277
- var offsetY = ev.clientY - rect.top;
8278
8451
  //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);
8452
+ var paperPosition = windowsPositionToPaperPosition({
8453
+ x: ev.clientX,
8454
+ y: ev.clientY
8455
+ }, container, zoom);
8456
+ var newPoints = addPointToList(paperPosition, __spreadArray(__spreadArray([sourcePosition], points, true), [targetPosition], false), pathRef.current);
8284
8457
  var pointsWithoutStartEndPoint = newPoints.slice(1, newPoints.length - 1);
8285
- var addedIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === newPoint.x && p.y === newPoint.y; });
8458
+ var addedIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === paperPosition.x && p.y === paperPosition.y; });
8286
8459
  var leftPointIndex = addedIndex - 1;
8287
8460
  var rightPointIndex = addedIndex + 1;
8288
8461
  var distFromLeftPoint;
@@ -8321,7 +8494,7 @@ var IElementLink = function (_a) {
8321
8494
  }
8322
8495
  }
8323
8496
  //Find new index of added point
8324
- _draggingPointIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === newPoint.x && p.y === newPoint.y; });
8497
+ _draggingPointIndex = pointsWithoutStartEndPoint.findIndex(function (p) { return p.x === paperPosition.x && p.y === paperPosition.y; });
8325
8498
  setDraggingPointIndex(_draggingPointIndex);
8326
8499
  setPoints(pointsWithoutStartEndPoint);
8327
8500
  };
@@ -8436,62 +8609,6 @@ var IElementLink = function (_a) {
8436
8609
  };
8437
8610
  var ElementLink = React.memo(IElementLink);
8438
8611
 
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
8612
  function configureLogger(_a) {
8496
8613
  var level = _a.level, customLogger = _a.customLogger;
8497
8614
  if (level !== undefined)
@@ -8548,6 +8665,7 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8548
8665
  var _d = React.useState(false), someElementLinkStarted = _d[0], setSomeElementLinkStarted = _d[1];
8549
8666
  var _e = React.useState(), potentialPortPosition = _e[0], setPotentialPortPosition = _e[1];
8550
8667
  var _paperEventEmitterContext = React.useContext(paperEventEmitterContext);
8668
+ var zoom = useZoomContext().zoom;
8551
8669
  var elementRef = React.useRef(null);
8552
8670
  React.useImperativeHandle(forwardedRef, function () { return elementRef.current; });
8553
8671
  var elementLinkStarted = React.useRef();
@@ -8815,24 +8933,17 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8815
8933
  setPotentialPortPosition(undefined);
8816
8934
  return;
8817
8935
  }
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
8936
+ var paper = windowsPositionToPaperPosition({
8937
+ x: ev.clientX,
8938
+ y: ev.clientY
8939
+ }, container, zoom);
8940
+ var elementAbsPosition_1 = getElementAbsPosition();
8828
8941
  var mousePositionOnElement = {
8829
- x: ev.clientX - (elementBounding.left - elementBBox.x),
8830
- y: ev.clientY - (elementBounding.top - elementBBox.y),
8942
+ x: paper.x - elementAbsPosition_1.x,
8943
+ y: paper.y - elementAbsPosition_1.y,
8831
8944
  };
8832
8945
  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.
8946
+ // Ensure the potential port position is within the element
8836
8947
  if (checkSamePosition(mousePositionOnElement, tempPotentialPortPosition, 5)) {
8837
8948
  setPotentialPortPosition(tempPotentialPortPosition);
8838
8949
  }
@@ -8953,11 +9064,11 @@ var Element = React.forwardRef(function (props, forwardedRef) {
8953
9064
  (React.createElement(SelectionFrame, { container: container, targetSVGElement: ((_g = selectedPort === null || selectedPort === void 0 ? void 0 : selectedPort.ref) === null || _g === void 0 ? void 0 : _g.current) || undefined, resizability: {
8954
9065
  enabled: false,
8955
9066
  keepRatio: false
8956
- }, objectX: elementAbsPosition.x + selectedPort.position.x, objectY: elementAbsPosition.y + selectedPort.position.y, onMove: handlePortMove })),
9067
+ }, objectX: elementAbsPosition.x + selectedPort.position.x, objectY: elementAbsPosition.y + selectedPort.position.y, onMove: handlePortMove, zoom: zoom })),
8957
9068
  hoveredPort && hoveredPort.id === p.id && (React.createElement(SelectionFrame, { container: container, targetSVGElement: ((_h = hoveredPort === null || hoveredPort === void 0 ? void 0 : hoveredPort.ref) === null || _h === void 0 ? void 0 : _h.current) || undefined, resizability: {
8958
9069
  enabled: false,
8959
9070
  keepRatio: false
8960
- } })));
9071
+ }, zoom: zoom })));
8961
9072
  }), texts === null || texts === void 0 ? void 0 :
8962
9073
  texts.map(function (t, index) {
8963
9074
  var _a, _b;
@@ -9280,6 +9391,8 @@ var Paper = function (props) {
9280
9391
  var _j = React.useState(null), selectedElementSVG = _j[0], setSelectedElementSVG = _j[1];
9281
9392
  var _k = React.useState(false), mouseDownedOnPaper = _k[0], setMouseDownedOnPaper = _k[1];
9282
9393
  var paperEventEmitter = React.useContext(paperEventEmitterContext);
9394
+ var zoom = useZoomContext().zoom;
9395
+ var zoomRef = React.useRef(zoom);
9283
9396
  var paperContainerRef = React.useRef(null);
9284
9397
  var tempLinkRef = React.useRef(tempLink); //Cache tempLink to avoid re-render when tempLink changed
9285
9398
  var elementsRef = React.useRef(elements); //Cache elements to avoid re-render when elements changed
@@ -9287,6 +9400,9 @@ var Paper = function (props) {
9287
9400
  var textsRef = React.useRef(texts); //Cache texts to avoid re-render when texts changed
9288
9401
  var size = props.size;
9289
9402
  var selectedElementAbsPosition = React.useMemo(function () { return selectedElement ? getAbsolutePosition(selectedElement) : null; }, [selectedElement, selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.position, selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size]);
9403
+ React.useEffect(function () {
9404
+ zoomRef.current = zoom;
9405
+ }, [zoom]);
9290
9406
  React.useEffect(function () {
9291
9407
  setElements(props.elements);
9292
9408
  }, [props.elements]);
@@ -9399,12 +9515,12 @@ var Paper = function (props) {
9399
9515
  updateElementsTree();
9400
9516
  }, [elements]);
9401
9517
  //Get all child elements of the deleted element
9402
- var getDeletedChildElements = function (deletedElement) {
9403
- if (!deletedElement.childrenElementsInTree)
9518
+ var getChildOfElement = function (element) {
9519
+ if (!element.childrenElementsInTree)
9404
9520
  return [];
9405
- var childElms = deletedElement.childrenElementsInTree;
9521
+ var childElms = element.childrenElementsInTree;
9406
9522
  var childOfChildElements = childElms.reduce(function (acc, ele) {
9407
- return __spreadArray(__spreadArray([], acc, true), getDeletedChildElements(ele), true);
9523
+ return __spreadArray(__spreadArray([], acc, true), getChildOfElement(ele), true);
9408
9524
  }, []);
9409
9525
  return __spreadArray(__spreadArray([], childElms, true), childOfChildElements, true);
9410
9526
  };
@@ -9413,7 +9529,8 @@ var Paper = function (props) {
9413
9529
  var _a;
9414
9530
  var listener = paperEventEmitter.onCommandDeleteSelectedElement(function () {
9415
9531
  if (selectedElement) {
9416
- var deletedChildElements = getDeletedChildElements(selectedElement);
9532
+ selectedElement.parentElement = undefined; //Remove parent element to avoid memory leak. This will remove the element from the parent element's childrenElements array.
9533
+ var deletedChildElements = getChildOfElement(selectedElement);
9417
9534
  var deletedElementIds_1 = __spreadArray(__spreadArray([], deletedChildElements, true), [selectedElement], false).map(function (e) { return e.id; });
9418
9535
  var prevElements = elementsRef.current;
9419
9536
  var newElements = prevElements.filter(function (e) { return !deletedElementIds_1.includes(e.id); });
@@ -9487,11 +9604,10 @@ var Paper = function (props) {
9487
9604
  }, [selectedText, props.onTextsChanged]);
9488
9605
  var handlePaperMouseMove = function (ev) {
9489
9606
  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;
9607
+ var _b = windowsPositionToPaperPosition({
9608
+ x: ev.clientX,
9609
+ y: ev.clientY
9610
+ }, paperContainerRef.current, zoom), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
9495
9611
  //if there is a temp link, update the temp target point
9496
9612
  if (tempLink) {
9497
9613
  var sourceElementAbsPosition = getAbsolutePosition(tempLink.sourceElement);
@@ -9514,15 +9630,14 @@ var Paper = function (props) {
9514
9630
  };
9515
9631
  var handleMouseDownOnPaper = function (ev) {
9516
9632
  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, {
9633
+ var _c = windowsPositionToPaperPosition({
9524
9634
  x: ev.clientX,
9525
9635
  y: ev.clientY
9636
+ }, paperContainerRef.current, zoom), xPosOnPaper = _c.x, yPosOnPaper = _c.y;
9637
+ setMouseDownedOnPaper(true);
9638
+ (_a = props.onPaperClicked) === null || _a === void 0 ? void 0 : _a.call(props, {
9639
+ x: xPosOnPaper,
9640
+ y: yPosOnPaper
9526
9641
  });
9527
9642
  paperEventEmitter.emitPaperClicked(ev);
9528
9643
  //broadcast mouse moved position to parent component
@@ -9533,11 +9648,11 @@ var Paper = function (props) {
9533
9648
  };
9534
9649
  var handleMouseUpOnPaper = function (ev) {
9535
9650
  var _a;
9536
- var currentTarget = ev.currentTarget;
9537
9651
  // 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;
9652
+ var _b = windowsPositionToPaperPosition({
9653
+ x: ev.clientX,
9654
+ y: ev.clientY
9655
+ }, paperContainerRef.current, zoom), xPosOnPaper = _b.x, yPosOnPaper = _b.y;
9541
9656
  if (mouseDownedOnPaper) {
9542
9657
  setSelectedElement(undefined);
9543
9658
  setSelectedElementSVG(null);
@@ -9569,17 +9684,15 @@ var Paper = function (props) {
9569
9684
  props.onLinksChanged(newLinks);
9570
9685
  }
9571
9686
  }, [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);
9687
+ var handlePointsOfLinkChange = React.useCallback(function (points, linkId) {
9688
+ var newLinks = __spreadArray([], linksRef.current, true);
9689
+ var updatedLinkIndex = newLinks.findIndex(function (l) { return l.id === linkId; });
9690
+ newLinks[updatedLinkIndex].points = points;
9578
9691
  setLinks(newLinks);
9579
9692
  if (props.onLinksChanged) {
9580
9693
  props.onLinksChanged(newLinks);
9581
9694
  }
9582
- }, [props.onLinksChanged, links]);
9695
+ }, [props.onLinksChanged]);
9583
9696
  var handlePortMoved = React.useCallback(function (port, elementId, oldPosition, newPosition) {
9584
9697
  var _a;
9585
9698
  var element = elementsRef.current.find(function (e) { return e.id === elementId; });
@@ -9624,9 +9737,14 @@ var Paper = function (props) {
9624
9737
  var _a;
9625
9738
  ev.stopPropagation();
9626
9739
  var element = elementsRef.current.find(function (e) { return e.id === elementId; });
9740
+ var paperPosition = windowsPositionToPaperPosition({
9741
+ x: ev.clientX,
9742
+ y: ev.clientY
9743
+ }, paperContainerRef.current, zoomRef.current);
9744
+ console.log(paperPosition);
9627
9745
  //broadcast port mouse down to parent component
9628
9746
  if (element) {
9629
- (_a = props.onPortMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, port, element);
9747
+ (_a = props.onPortMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, port, element, paperPosition);
9630
9748
  }
9631
9749
  if (!tempLinkRef.current && element) {
9632
9750
  //handle create temp element link;
@@ -9659,9 +9777,13 @@ var Paper = function (props) {
9659
9777
  var _a;
9660
9778
  ev.stopPropagation();
9661
9779
  var element = elementsRef.current.find(function (e) { return e.id === elementId; });
9780
+ var paperPosition = windowsPositionToPaperPosition({
9781
+ x: ev.clientX,
9782
+ y: ev.clientY
9783
+ }, paperContainerRef.current, zoomRef.current);
9662
9784
  //broadcast port mouse down to parent component
9663
9785
  if (element) {
9664
- (_a = props.onPortMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, port, element);
9786
+ (_a = props.onPortMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, port, element, paperPosition);
9665
9787
  }
9666
9788
  //Create new element link, if has tempLink
9667
9789
  if (tempLinkRef.current) {
@@ -9916,29 +10038,45 @@ var Paper = function (props) {
9916
10038
  var handleMouseUp = React.useCallback(function (ev, elementId) {
9917
10039
  var _a;
9918
10040
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10041
+ var paperPosition = windowsPositionToPaperPosition({
10042
+ x: ev.clientX,
10043
+ y: ev.clientY
10044
+ }, paperContainerRef.current, zoomRef.current);
9919
10045
  if (element) {
9920
- (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10046
+ (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9921
10047
  }
9922
10048
  }, [props.onElementMouseUp]);
9923
10049
  var handleMouseDown = React.useCallback(function (ev, elementId) {
9924
10050
  var _a;
9925
10051
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10052
+ var paperPosition = windowsPositionToPaperPosition({
10053
+ x: ev.clientX,
10054
+ y: ev.clientY
10055
+ }, paperContainerRef.current, zoomRef.current);
9926
10056
  if (element) {
9927
- (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10057
+ (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9928
10058
  }
9929
10059
  }, [props.onElementMouseDown]);
9930
10060
  var handleMouseMove = React.useCallback(function (ev, elementId) {
9931
10061
  var _a;
9932
10062
  var element = elementsRef.current.find(function (ele) { return ele.id === elementId; });
10063
+ var paperPosition = windowsPositionToPaperPosition({
10064
+ x: ev.clientX,
10065
+ y: ev.clientY
10066
+ }, paperContainerRef.current, zoomRef.current);
9933
10067
  if (element) {
9934
- (_a = props.onElementMouseMove) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10068
+ (_a = props.onElementMouseMove) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9935
10069
  }
9936
10070
  }, [props.onElementMouseMove]);
9937
10071
  var handleMouseLeave = React.useCallback(function (ev, elementId) {
9938
10072
  var _a;
9939
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);
9940
10078
  if (element) {
9941
- (_a = props.onElementMouseLeave) === null || _a === void 0 ? void 0 : _a.call(props, ev, element);
10079
+ (_a = props.onElementMouseLeave) === null || _a === void 0 ? void 0 : _a.call(props, ev, element, paperPosition);
9942
10080
  }
9943
10081
  }, [props.onElementMouseLeave]);
9944
10082
  var renderElementInTree = React.useCallback(function (element) {
@@ -9953,22 +10091,32 @@ var Paper = function (props) {
9953
10091
  React.createElement(SelectionFrame, { container: paperContainerRef.current, targetSVGElement: selectedElementSVG || undefined, resizability: (selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.resizability) || {
9954
10092
  enabled: true,
9955
10093
  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,
10094
+ }, objectX: selectedElementAbsPosition === null || selectedElementAbsPosition === void 0 ? void 0 : selectedElementAbsPosition.x, objectY: selectedElementAbsPosition === null || selectedElementAbsPosition === void 0 ? void 0 : selectedElementAbsPosition.y, width: selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size.width, height: selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size.height, zoom: zoom,
9957
10095
  //movingOffsetThreshold: ELEMENT_MOVING_OFFSET_THRESHOLD,
9958
10096
  onMouseDown: function (ev) {
9959
10097
  var _a;
9960
10098
  if (selectedElement) {
9961
- (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement);
10099
+ var paperPosition = windowsPositionToPaperPosition({
10100
+ x: ev.clientX,
10101
+ y: ev.clientY
10102
+ }, paperContainerRef.current, zoomRef.current);
10103
+ (_a = props.onElementMouseDown) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement, paperPosition);
9962
10104
  }
9963
10105
  }, onMouseUp: function (ev) {
9964
10106
  var _a;
9965
10107
  if (selectedElement) {
9966
- (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement);
10108
+ var paperPosition = windowsPositionToPaperPosition({
10109
+ x: ev.clientX,
10110
+ y: ev.clientY
10111
+ }, paperContainerRef.current, zoomRef.current);
10112
+ (_a = props.onElementMouseUp) === null || _a === void 0 ? void 0 : _a.call(props, ev, selectedElement, paperPosition);
9967
10113
  }
9968
10114
  }, onMove: function (newX, newY) {
10115
+ var _a;
9969
10116
  if (!selectedElement)
9970
10117
  return;
9971
10118
  var oldPosition = __assign({}, selectedElement.position);
10119
+ // Relative position to the paper container
9972
10120
  var newPosition = {
9973
10121
  x: newX,
9974
10122
  y: newY
@@ -9985,10 +10133,29 @@ var Paper = function (props) {
9985
10133
  //let newElementPosition = updateElementPosition(selectedElement, newPosition.x, newPosition.y, true)
9986
10134
  var indexSelectedElement = elements.findIndex(function (e) { return e.id === selectedElement.id; });
9987
10135
  logger.info("Element ".concat(selectedElement.id, " is moving to relative position ").concat(JSON.stringify(selectedElement.position)));
10136
+ // Start updating the position of links connected to the selected element
10137
+ var childElements = getChildOfElement(selectedElement);
10138
+ var elementIds = __spreadArray(__spreadArray([], childElements.map(function (e) { return e.id; }), true), [selectedElement.id], false);
10139
+ var offsetX = newPosition.x - oldPosition.x;
10140
+ var offsetY = newPosition.y - oldPosition.y;
10141
+ // Update position of all points of links that are connected to the selected element
10142
+ var newLinks = linksRef.current.map(function (link) {
10143
+ var isUpdate = elementIds.includes(link.sourceElement.id) && elementIds.includes(link.targetElement.id);
10144
+ if (link.points && isUpdate) {
10145
+ link.points.forEach(function (p) {
10146
+ p.x += offsetX;
10147
+ p.y += offsetY;
10148
+ });
10149
+ }
10150
+ return link;
10151
+ });
10152
+ (_a = props.onLinksChanged) === null || _a === void 0 ? void 0 : _a.call(props, newLinks);
10153
+ // End updating the position of links connected to the selected element
9988
10154
  //Set state to re-render UI with new position
9989
10155
  setElementsInTree(function (prev) { return __spreadArray([], prev, true); });
9990
10156
  if (props.onElementMoved) {
9991
- props.onElementMoved(selectedElement.position, selectedElement, indexSelectedElement);
10157
+ console.log('onElementMoved', selectedElement.position, newPosition);
10158
+ props.onElementMoved(selectedElement.position, selectedElement, indexSelectedElement, newPosition);
9992
10159
  }
9993
10160
  paperEventEmitter.emitElementMoved(selectedElement, oldPosition, selectedElement.position);
9994
10161
  setMouseDownedOnPaper(false);
@@ -10010,12 +10177,12 @@ var Paper = function (props) {
10010
10177
  paperEventEmitter.emitElementResized(selectedElement, oldSize, newSize);
10011
10178
  setMouseDownedOnPaper(false);
10012
10179
  } }))));
10013
- }, [handlePortsChanged, handleElementClicked, handleContextMenu, handlePortMoved, handlePortMouseDown, handlePortMouseUp, handleMouseUpAtLinkedPortPlaceholder, handleElementTextChange, handleMouseUp, handleMouseMove, handleMouseLeave, selectedElement, selectedElementAbsPosition]);
10180
+ }, [handlePortsChanged, handleElementClicked, handleContextMenu, handlePortMoved, handlePortMouseDown, handlePortMouseUp, handleMouseUpAtLinkedPortPlaceholder, handleElementTextChange, handleMouseUp, handleMouseMove, handleMouseLeave, selectedElement, selectedElementAbsPosition, zoom]);
10014
10181
  var ElementsInTree = React.useMemo(function () {
10015
10182
  return elementsInTree.map(function (element, index) {
10016
10183
  return renderElementInTree(element);
10017
10184
  });
10018
- }, [elementsInTree, renderElementInTree, selectedElement]);
10185
+ }, [elementsInTree, renderElementInTree, selectedElement, zoom]);
10019
10186
  return (React.createElement("div", { style: { position: "relative" } },
10020
10187
  React.createElement(Ruler, { squareSize: 100, border: '1px dashed grey' }),
10021
10188
  React.createElement("svg", { tabIndex: 0, width: size.width, height: size.height, ref: paperContainerRef, id: "paper-container", onMouseMove: handlePaperMouseMove, onMouseDown: handleMouseDownOnPaper, onMouseUp: handleMouseUpOnPaper },
@@ -10043,83 +10210,6 @@ var Paper = function (props) {
10043
10210
  };
10044
10211
  var Paper$1 = React.memo(Paper);
10045
10212
 
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
10213
  var Editor = function (_a) {
10124
10214
  var editorContext = _a.editorContext, width = _a.width, height = _a.height;
10125
10215
  var _b = React.useState([]), elements = _b[0], setElements = _b[1];
@@ -10156,14 +10246,14 @@ var Editor = function (_a) {
10156
10246
  var handlePaperClicked = React.useCallback(function (position) {
10157
10247
  editorContext.onPaperClickedHandler(position);
10158
10248
  }, [editorContext]);
10159
- var handlePortMouseDown = React.useCallback(function (port, element) {
10160
- editorContext.onPortMouseDownHandler(port, element);
10249
+ var handlePortMouseDown = React.useCallback(function (port, element, paperPosition) {
10250
+ editorContext.onPortMouseDownHandler(port, element, paperPosition);
10161
10251
  }, [editorContext]);
10162
- var handlePortMouseUp = React.useCallback(function (port, element) {
10163
- editorContext.onPortMouseUpHandler(port, element);
10252
+ var handlePortMouseUp = React.useCallback(function (port, element, paperPosition) {
10253
+ editorContext.onPortMouseUpHandler(port, element, paperPosition);
10164
10254
  }, [editorContext]);
10165
- var handlePortMoved = React.useCallback(function (position, port, element) {
10166
- editorContext.onPortMovedHandler(position, port, element);
10255
+ var handlePortMoved = React.useCallback(function (relativePosition, port, element) {
10256
+ editorContext.onPortMovedHandler(relativePosition, port, element);
10167
10257
  }, [editorContext]);
10168
10258
  var handlePortSelected = React.useCallback(function (port, element) {
10169
10259
  editorContext.onPortSelectedHandler(port, element);
@@ -10174,8 +10264,9 @@ var Editor = function (_a) {
10174
10264
  var handleElementContextMenu = React.useCallback(function (element, event) {
10175
10265
  editorContext.onElementContextMenuHandler(element, event);
10176
10266
  }, [editorContext]);
10177
- var handleElementMoved = React.useCallback(function (position, element) {
10178
- editorContext.onElementMovedHandler(position, element);
10267
+ var handleElementMoved = React.useCallback(function (relativePosition, element) {
10268
+ console.count('SelectionFrame: handleElementMoved');
10269
+ editorContext.onElementMovedHandler(relativePosition, element);
10179
10270
  }, [editorContext]);
10180
10271
  var handleElementResized = React.useCallback(function (size, element) {
10181
10272
  editorContext.onElementResizedHandler(size, element);
@@ -10183,17 +10274,17 @@ var Editor = function (_a) {
10183
10274
  var handleElementSelected = React.useCallback(function (element) {
10184
10275
  editorContext.onElementSelectedHandler(element);
10185
10276
  }, [editorContext]);
10186
- var handleElementMouseLeave = React.useCallback(function (ev, element) {
10187
- editorContext.onElementMouseLeaveHandler(ev, element);
10277
+ var handleElementMouseLeave = React.useCallback(function (ev, element, paperPosition) {
10278
+ editorContext.onElementMouseLeaveHandler(ev, element, paperPosition);
10188
10279
  }, [editorContext]);
10189
- var handleElementMouseMove = React.useCallback(function (ev, element) {
10190
- editorContext.onElementMouseMoveHandler(ev, element);
10280
+ var handleElementMouseMove = React.useCallback(function (ev, element, paperPosition) {
10281
+ editorContext.onElementMouseMoveHandler(ev, element, paperPosition);
10191
10282
  }, [editorContext]);
10192
- var handleElementMouseDown = React.useCallback(function (ev, element) {
10193
- editorContext.onElementMouseDownHandler(ev, element);
10283
+ var handleElementMouseDown = React.useCallback(function (ev, element, paperPosition) {
10284
+ editorContext.onElementMouseDownHandler(ev, element, paperPosition);
10194
10285
  }, [editorContext]);
10195
- var handleElementMouseUp = React.useCallback(function (ev, element) {
10196
- editorContext.onElementMouseUpHandler(ev, element);
10286
+ var handleElementMouseUp = React.useCallback(function (ev, element, paperPosition) {
10287
+ editorContext.onElementMouseUpHandler(ev, element, paperPosition);
10197
10288
  }, [editorContext]);
10198
10289
  var handleElementsChanged = React.useCallback(function (elements) {
10199
10290
  editorContext.elements = elements;
@@ -10202,7 +10293,6 @@ var Editor = function (_a) {
10202
10293
  editorContext.onLinkSelectedHandler(link);
10203
10294
  }, [editorContext]);
10204
10295
  var handleLinksChanged = React.useCallback(function (links) {
10205
- console.log(links);
10206
10296
  editorContext.links = links;
10207
10297
  }, [editorContext]);
10208
10298
  var handleTextSelected = React.useCallback(function (text) {
@@ -10224,11 +10314,9 @@ var Editor = function (_a) {
10224
10314
  return null;
10225
10315
  }, [editorContext]);
10226
10316
  var handlePaperMouseMoved = React.useCallback(function (position) {
10227
- console.log("handlePaperMouseMoved", position);
10228
10317
  editorContext.onPaperMouseMovedHandler(position);
10229
10318
  }, [editorContext]);
10230
10319
  var handlePaperMouseDown = React.useCallback(function (position) {
10231
- console.log("handlePaperMouseDown", position);
10232
10320
  editorContext.onPaperMouseDownHandler(position);
10233
10321
  }, [editorContext]);
10234
10322
  var handlePaperMouseUp = React.useCallback(function (position) {
@@ -10280,7 +10368,6 @@ exports.getPointsFromPathData = getPointsFromPathData;
10280
10368
  exports.getPointsFromPathElement = getPointsFromPathElement;
10281
10369
  exports.getPortAbsolutePosition = getPortAbsolutePosition;
10282
10370
  exports.getRectangleCorners = getRectangleCorners;
10283
- exports.getRelativePosition = getRelativePosition;
10284
10371
  exports.getRotatedRectangleCoordinates = getRotatedRectangleCoordinates;
10285
10372
  exports.getRotatedSVGBBox = getRotatedSVGBBox;
10286
10373
  exports.getSVGBBoxOutsideTransformedParent = getSVGBBoxOutsideTransformedParent;
@@ -10289,3 +10376,4 @@ exports.pathDataToD = pathDataToD;
10289
10376
  exports.removeDuplicatePosition = removeDuplicatePosition;
10290
10377
  exports.transformAbsPositionToElementRelativePosition = transformAbsPositionToElementRelativePosition;
10291
10378
  exports.transformAbsPositionToRelativePositionInsideElement = transformAbsPositionToRelativePositionInsideElement;
10379
+ exports.windowsPositionToPaperPosition = windowsPositionToPaperPosition;