Skip to content

Commit 86957a0

Browse files
committed
fix(core): horizontal scroll on windows
1 parent 0364a83 commit 86957a0

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

packages/core/src/container/Viewport/Viewport.vue

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ const selectionKeyPressed = ref(false)
4848
4949
const isZoomingOrPanning = ref(false)
5050
51+
const isPanScrolling = ref(false)
52+
53+
const panScrollTimeout = ref<ReturnType<typeof setTimeout>>()
54+
5155
let zoomedWithRightMouseButton = false
5256
5357
let mouseButton = 0
@@ -183,12 +187,13 @@ onMounted(() => {
183187
event.stopImmediatePropagation()
184188
185189
const currentZoom = d3Selection.property('__zoom').k || 1
190+
const _isMacOs = isMacOs()
186191
187-
if (event.ctrlKey && zoomOnPinch.value && isMacOs()) {
192+
// macOS sets ctrlKey=true for pinch gesture on a trackpad
193+
if (event.ctrlKey && zoomOnPinch && _isMacOs) {
188194
const point = pointer(event)
189195
const pinchDelta = wheelDelta(event)
190196
const zoom = currentZoom * 2 ** pinchDelta
191-
192197
// @ts-expect-error d3-zoom types are not up to date
193198
d3Zoom.scaleTo(d3Selection, zoom, point, event)
194199
@@ -198,14 +203,47 @@ onMounted(() => {
198203
// increase scroll speed in firefox
199204
// firefox: deltaMode === 1; chrome: deltaMode === 0
200205
const deltaNormalize = event.deltaMode === 1 ? 20 : 1
201-
const deltaX = panOnScrollMode.value === PanOnScrollMode.Vertical ? 0 : event.deltaX * deltaNormalize
202-
const deltaY = panOnScrollMode.value === PanOnScrollMode.Horizontal ? 0 : event.deltaY * deltaNormalize
206+
207+
let deltaX = panOnScrollMode.value === PanOnScrollMode.Vertical ? 0 : event.deltaX * deltaNormalize
208+
let deltaY = panOnScrollMode.value === PanOnScrollMode.Horizontal ? 0 : event.deltaY * deltaNormalize
209+
210+
// this enables vertical scrolling with shift + scroll on windows
211+
if (!_isMacOs && event.shiftKey && panOnScrollMode.value !== PanOnScrollMode.Vertical && !deltaX && deltaY) {
212+
deltaX = deltaY
213+
deltaY = 0
214+
}
203215
204216
d3Zoom.translateBy(
205217
d3Selection,
206218
-(deltaX / currentZoom) * panOnScrollSpeed.value,
207219
-(deltaY / currentZoom) * panOnScrollSpeed.value,
208220
)
221+
222+
const nextViewport = eventToFlowTransform(d3Selection.property('__zoom'))
223+
224+
clearTimeout(panScrollTimeout.value)
225+
226+
// for pan on scroll we need to handle the event calls on our own
227+
// we can't use the start, zoom and end events from d3-zoom
228+
// because start and move gets called on every scroll event and not once at the beginning
229+
if (!isPanScrolling.value) {
230+
isPanScrolling.value = true
231+
232+
emits.moveStart({ event, flowTransform: nextViewport })
233+
emits.viewportChangeStart(nextViewport)
234+
}
235+
236+
if (isPanScrolling.value) {
237+
emits.move({ event, flowTransform: nextViewport })
238+
emits.viewportChange(nextViewport)
239+
240+
panScrollTimeout.value = setTimeout(() => {
241+
emits.moveEnd({ event, flowTransform: nextViewport })
242+
emits.viewportChangeEnd(nextViewport)
243+
244+
isPanScrolling.value = false
245+
}, 150)
246+
}
209247
},
210248
{ passive: false },
211249
)

packages/core/src/types/hooks.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ export interface FlowEvents {
6464
} & OnConnectStartParams
6565
clickConnectEnd: MouseEvent | TouchEvent | undefined
6666
paneReady: VueFlowStore
67-
move: { event: D3ZoomEvent<HTMLDivElement, any>; flowTransform: ViewportTransform }
68-
moveStart: { event: D3ZoomEvent<HTMLDivElement, any>; flowTransform: ViewportTransform }
69-
moveEnd: { event: D3ZoomEvent<HTMLDivElement, any>; flowTransform: ViewportTransform }
67+
move: { event: D3ZoomEvent<HTMLDivElement, any> | WheelEvent; flowTransform: ViewportTransform }
68+
moveStart: { event: D3ZoomEvent<HTMLDivElement, any> | WheelEvent; flowTransform: ViewportTransform }
69+
moveEnd: { event: D3ZoomEvent<HTMLDivElement, any> | WheelEvent; flowTransform: ViewportTransform }
7070
selectionDragStart: NodeDragEvent
7171
selectionDrag: NodeDragEvent
7272
selectionDragStop: NodeDragEvent

0 commit comments

Comments
 (0)