11import { until } from '@vueuse/core'
22import { zoomIdentity } from 'd3-zoom'
33import { computed , ref } from 'vue'
4- import type { ComputedGetters , D3Selection , GraphNode , State , ViewportFunctions } from '~/types'
5- import { clampPosition , getRectOfNodes , getTransformForBounds , pointToRendererPoint } from '~/utils'
4+ import type { ComputedGetters , D3Selection , GraphNode , Project , State , ViewportFunctions } from '~/types'
5+ import { clampPosition , getRectOfNodes , getTransformForBounds , pointToRendererPoint , rendererPointToPoint } from '~/utils'
66
77interface ExtendedViewport extends ViewportFunctions {
88 initialized : boolean
9+ screenToFlowCoordinate : Project
10+ flowToScreenCoordinate : Project
911}
1012
1113const DEFAULT_PADDING = 0.1
@@ -22,6 +24,8 @@ const initialViewportHelper: ExtendedViewport = {
2224 setCenter : noop ,
2325 fitBounds : noop ,
2426 project : ( position ) => position ,
27+ screenToFlowCoordinate : ( position ) => position ,
28+ flowToScreenCoordinate : ( position ) => position ,
2529 setViewport : noop ,
2630 setTransform : noop ,
2731 getViewport : ( ) => ( { x : 0 , y : 0 , zoom : 1 } ) ,
@@ -30,7 +34,19 @@ const initialViewportHelper: ExtendedViewport = {
3034}
3135
3236export function useViewport ( state : State , getters : ComputedGetters ) {
33- const { nodes, d3Zoom, d3Selection, dimensions, translateExtent, minZoom, maxZoom, viewport, snapToGrid, snapGrid } = $ ( state )
37+ const {
38+ vueFlowRef : domNode ,
39+ nodes,
40+ d3Zoom,
41+ d3Selection,
42+ dimensions,
43+ translateExtent,
44+ minZoom,
45+ maxZoom,
46+ viewport,
47+ snapToGrid,
48+ snapGrid,
49+ } = $ ( state )
3450
3551 const { getNodes } = getters
3652
@@ -176,6 +192,34 @@ export function useViewport(state: State, getters: ComputedGetters) {
176192 return transformViewport ( x , y , zoom , options ?. duration )
177193 } ,
178194 project : ( position ) => pointToRendererPoint ( position , viewport , snapToGrid , snapGrid ) ,
195+ screenToFlowCoordinate : ( position ) => {
196+ if ( domNode ) {
197+ const { x : domX , y : domY } = domNode . getBoundingClientRect ( )
198+
199+ const correctedPosition = {
200+ x : position . x - domX ,
201+ y : position . y - domY ,
202+ }
203+
204+ return pointToRendererPoint ( correctedPosition , viewport , snapToGrid , snapGrid )
205+ }
206+
207+ return { x : 0 , y : 0 }
208+ } ,
209+ flowToScreenCoordinate : ( position ) => {
210+ if ( domNode ) {
211+ const { x : domX , y : domY } = domNode . getBoundingClientRect ( )
212+
213+ const correctedPosition = {
214+ x : position . x + domX ,
215+ y : position . y + domY ,
216+ }
217+
218+ return rendererPointToPoint ( correctedPosition , viewport )
219+ }
220+
221+ return { x : 0 , y : 0 }
222+ } ,
179223 }
180224 }
181225
0 commit comments