feat(core): expose wheelDelta utility (#1918)

* feat(core): expose wheelDelta utility

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* chore(changeset): add

* fix(minimap): apply wheel delta to zoom

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>

* chore(changeset): add

---------

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
Braks
2025-08-11 12:46:49 +02:00
parent 5dc276af52
commit 5fbbc826e5
7 changed files with 52 additions and 9 deletions

View File

@@ -0,0 +1,5 @@
---
"@vue-flow/core": minor
---
Expose `wheelDelta` utility fn

View File

@@ -0,0 +1,5 @@
---
"@vue-flow/minimap": patch
---
Apply wheelDelta to zoom

View File

@@ -0,0 +1,30 @@
<script setup>
import { Handle, Position } from '@vue-flow/core'
const props = defineProps({ handleCount: { type: Number } })
</script>
<template>
<div class="custom-node">
<Handle
v-for="n in props.handleCount"
:id="String(n - 1)"
:key="`${n}-${props.handleCount}`"
type="target"
:position="Position.Top"
:style="{ left: `${100 * (n / (props.handleCount + 1))}%` }"
/>
Custom
</div>
</template>
<style>
.custom-node {
min-width: 100px;
gap: 4px;
padding: 8px;
background: white;
border: 1px solid black;
border-radius: 4px;
}
</style>

View File

@@ -8,7 +8,7 @@ import { PanOnScrollMode } from '../../types'
import { useKeyPress } from '../../composables/useKeyPress'
import { useVueFlow } from '../../composables/useVueFlow'
import { useResizeHandler } from '../../composables/useResizeHandler'
import { clamp, isMacOs, warn } from '../../utils'
import { clamp, isMacOs, warn, wheelDelta } from '../../utils'
import Pane from '../Pane/Pane.vue'
import Transform from './Transform.vue'
@@ -380,12 +380,6 @@ function isRightClickPan(pan: boolean | number[], usedButton: number) {
return usedButton === 2 && Array.isArray(pan) && pan.includes(2)
}
function wheelDelta(event: any) {
const factor = event.ctrlKey && isMacOs() ? 10 : 1
return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * factor
}
function viewChanged(prevViewport: ViewportTransform, eventTransform: ZoomTransform) {
return (
(prevViewport.x !== eventTransform.x && !Number.isNaN(eventTransform.x)) ||

View File

@@ -48,6 +48,7 @@ export {
getBoundsofRects,
connectionExists,
clamp,
wheelDelta,
} from './utils/graph'
/**

View File

@@ -21,7 +21,7 @@ import type {
XYPosition,
XYZPosition,
} from '../types'
import { isDef, snapPosition, warn } from '.'
import { isDef, isMacOs, snapPosition, warn } from '.'
export function nodeToRect(node: GraphNode): Rect {
return {
@@ -504,3 +504,9 @@ export function getMarkerId(marker: EdgeMarkerType | undefined, vueFlowId?: stri
.map((key) => `${key}=${marker[<keyof EdgeMarkerType>key]}`)
.join('&')}`
}
export function wheelDelta(event: any) {
const factor = event.ctrlKey && isMacOs() ? 10 : 1
return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * factor
}

View File

@@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { CoordinateExtent, GraphNode, PanelPosition } from '@vue-flow/core'
import { Panel, getBoundsofRects, getConnectedEdges, getRectOfNodes, useVueFlow } from '@vue-flow/core'
import { Panel, getBoundsofRects, getConnectedEdges, getRectOfNodes, useVueFlow, wheelDelta } from '@vue-flow/core'
import { zoom, zoomIdentity } from 'd3-zoom'
import type { D3ZoomEvent } from 'd3-zoom'
import { pointer, select } from 'd3-selection'
@@ -159,6 +159,7 @@ watchEffect(
}
const zoomAndPanHandler = zoom()
.wheelDelta((event) => wheelDelta(event) * (zoomStep / 10))
.on('zoom', pannable ? panHandler : () => {})
.on('zoom.wheel', zoomable ? zoomHandler : () => {})
@@ -232,6 +233,7 @@ export default {
v-for="node of getNodesInitialized"
:id="node.id"
:key="node.id"
f
:position="node.computedPosition"
:dimensions="node.dimensions"
:selected="node.selected"