From 2d2f642c82e397265870fe7b60799d4f5baf63b9 Mon Sep 17 00:00:00 2001
From: Peter
Date: Thu, 5 Oct 2023 10:34:58 +0200
Subject: [PATCH] feat(react) added screenToFlowCoordinate &
flowToScreenCoordinate
---
.../react/src/examples/DragNDrop/index.tsx | 4 +-
packages/react/src/hooks/useViewportHelper.ts | 38 ++++++++++++++++++-
packages/react/src/types/general.ts | 2 +
3 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/examples/react/src/examples/DragNDrop/index.tsx b/examples/react/src/examples/DragNDrop/index.tsx
index 16e9737e..a3e09d8d 100644
--- a/examples/react/src/examples/DragNDrop/index.tsx
+++ b/examples/react/src/examples/DragNDrop/index.tsx
@@ -49,9 +49,9 @@ const DnDFlow = () => {
if (reactFlowInstance) {
const type = event.dataTransfer.getData('application/reactflow');
- const position = reactFlowInstance.project({
+ const position = reactFlowInstance.screenToFlowCoordinate({
x: event.clientX,
- y: event.clientY - 40,
+ y: event.clientY,
});
const newNode: Node = {
id: getId(),
diff --git a/packages/react/src/hooks/useViewportHelper.ts b/packages/react/src/hooks/useViewportHelper.ts
index aded1f17..1872d414 100644
--- a/packages/react/src/hooks/useViewportHelper.ts
+++ b/packages/react/src/hooks/useViewportHelper.ts
@@ -1,5 +1,11 @@
import { useMemo } from 'react';
-import { pointToRendererPoint, getTransformForBounds, fitView, type XYPosition } from '@xyflow/system';
+import {
+ pointToRendererPoint,
+ getTransformForBounds,
+ fitView,
+ type XYPosition,
+ rendererPointToPoint,
+} from '@xyflow/system';
import { useStoreApi, useStore } from '../hooks/useStore';
import type { ViewportHelperFunctions, ReactFlowState } from '../types';
@@ -85,6 +91,36 @@ const useViewportHelper = (): ViewportHelperFunctions => {
const { transform, snapToGrid, snapGrid } = store.getState();
return pointToRendererPoint(position, transform, snapToGrid, snapGrid);
},
+ screenToFlowCoordinate: (position: XYPosition) => {
+ const { transform, snapToGrid, snapGrid, domNode } = store.getState();
+ if (domNode) {
+ const { x: domX, y: domY } = domNode.getBoundingClientRect();
+
+ const correctedPosition = {
+ x: position.x - domX,
+ y: position.y - domY,
+ };
+
+ return pointToRendererPoint(correctedPosition, transform, snapToGrid, snapGrid || [1, 1]);
+ }
+
+ return { x: 0, y: 0 };
+ },
+ flowToScreenCoordinate: (position: XYPosition) => {
+ const { transform, domNode } = store.getState();
+ if (domNode) {
+ const { x: domX, y: domY } = domNode.getBoundingClientRect();
+
+ const rendererPosition = rendererPointToPoint(position, transform);
+
+ return {
+ x: rendererPosition.x + domX,
+ y: rendererPosition.y + domY,
+ };
+ }
+
+ return { x: 0, y: 0 };
+ },
viewportInitialized: panZoomInitialized,
};
}, [panZoomInitialized]);
diff --git a/packages/react/src/types/general.ts b/packages/react/src/types/general.ts
index 8108c3dd..2b2945a6 100644
--- a/packages/react/src/types/general.ts
+++ b/packages/react/src/types/general.ts
@@ -55,5 +55,7 @@ export type ViewportHelperFunctions = {
setCenter: SetCenter;
fitBounds: FitBounds;
project: Project;
+ screenToFlowCoordinate: Project;
+ flowToScreenCoordinate: Project;
viewportInitialized: boolean;
};