feat(options): add preventScrolling option
Signed-off-by: Braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
|||||||
FlowState,
|
FlowState,
|
||||||
FlowInstance,
|
FlowInstance,
|
||||||
Loading,
|
Loading,
|
||||||
|
FlowOptions,
|
||||||
} from '../../types'
|
} from '../../types'
|
||||||
import ZoomPane from '../ZoomPane/ZoomPane.vue'
|
import ZoomPane from '../ZoomPane/ZoomPane.vue'
|
||||||
import SelectionPane from '../SelectionPane/SelectionPane.vue'
|
import SelectionPane from '../SelectionPane/SelectionPane.vue'
|
||||||
@@ -24,7 +25,7 @@ import LoadingIndicator from '../../components/Loading/LoadingIndicator.vue'
|
|||||||
import { createHooks, initFlow, useWindow, useZoomPanHelper } from '../../composables'
|
import { createHooks, initFlow, useWindow, useZoomPanHelper } from '../../composables'
|
||||||
import { onLoadGetElements, onLoadProject, onLoadToObject } from '../../utils'
|
import { onLoadGetElements, onLoadProject, onLoadToObject } from '../../utils'
|
||||||
|
|
||||||
interface FlowProps {
|
interface FlowProps extends FlowOptions {
|
||||||
id?: string
|
id?: string
|
||||||
store?: FlowStore
|
store?: FlowStore
|
||||||
modelValue?: Elements
|
modelValue?: Elements
|
||||||
@@ -95,6 +96,7 @@ const props = withDefaults(defineProps<FlowProps>(), {
|
|||||||
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
||||||
],
|
],
|
||||||
arrowHeadColor: '#b1b1b7',
|
arrowHeadColor: '#b1b1b7',
|
||||||
|
preventScrolling: true,
|
||||||
zoomOnScroll: true,
|
zoomOnScroll: true,
|
||||||
zoomOnPinch: true,
|
zoomOnPinch: true,
|
||||||
zoomOnDoubleClick: true,
|
zoomOnDoubleClick: true,
|
||||||
@@ -182,6 +184,7 @@ const transitionName = computed(() => {
|
|||||||
<template #default>
|
<template #default>
|
||||||
<ZoomPane
|
<ZoomPane
|
||||||
:key="`zoom-pane-${store.$id}`"
|
:key="`zoom-pane-${store.$id}`"
|
||||||
|
:prevent-scrolling="store.preventScrolling"
|
||||||
:selection-key-code="store.selectionKeyCode"
|
:selection-key-code="store.selectionKeyCode"
|
||||||
:zoom-activation-key-code="store.zoomActivationKeyCode"
|
:zoom-activation-key-code="store.zoomActivationKeyCode"
|
||||||
:default-zoom="store.defaultZoom"
|
:default-zoom="store.defaultZoom"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ interface ZoomPaneProps {
|
|||||||
panOnScrollSpeed?: number
|
panOnScrollSpeed?: number
|
||||||
panOnScrollMode?: PanOnScrollMode
|
panOnScrollMode?: PanOnScrollMode
|
||||||
zoomOnDoubleClick?: boolean
|
zoomOnDoubleClick?: boolean
|
||||||
|
preventScrolling?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<ZoomPaneProps>(), {
|
const props = withDefaults(defineProps<ZoomPaneProps>(), {
|
||||||
@@ -32,6 +33,7 @@ const props = withDefaults(defineProps<ZoomPaneProps>(), {
|
|||||||
panOnScrollSpeed: 0.5,
|
panOnScrollSpeed: 0.5,
|
||||||
panOnScrollMode: PanOnScrollMode.Free,
|
panOnScrollMode: PanOnScrollMode.Free,
|
||||||
paneMoveable: true,
|
paneMoveable: true,
|
||||||
|
preventScrolling: true,
|
||||||
})
|
})
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const zoomPaneEl = templateRef<HTMLDivElement>('zoomPane', null)
|
const zoomPaneEl = templateRef<HTMLDivElement>('zoomPane', null)
|
||||||
@@ -47,6 +49,8 @@ const eventToFlowTransform = (eventTransform: ZoomTransform): FlowTransform => (
|
|||||||
zoom: eventTransform.k,
|
zoom: eventTransform.k,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const noWheel = (event: Event) => (event.target as Element).closest('.nowheel')
|
||||||
|
|
||||||
const clampedX = clamp(props.defaultPosition[0], store.translateExtent[0][0], store.translateExtent[1][0])
|
const clampedX = clamp(props.defaultPosition[0], store.translateExtent[0][0], store.translateExtent[1][0])
|
||||||
const clampedY = clamp(props.defaultPosition[1], store.translateExtent[0][1], store.translateExtent[1][1])
|
const clampedY = clamp(props.defaultPosition[1], store.translateExtent[0][1], store.translateExtent[1][1])
|
||||||
const clampedZoom = clamp(props.defaultZoom, store.minZoom, store.maxZoom)
|
const clampedZoom = clamp(props.defaultZoom, store.minZoom, store.maxZoom)
|
||||||
@@ -102,6 +106,8 @@ invoke(async () => {
|
|||||||
if (props.panOnScroll && keyPress) {
|
if (props.panOnScroll && keyPress) {
|
||||||
d3s
|
d3s
|
||||||
?.on('wheel', (event: WheelEvent) => {
|
?.on('wheel', (event: WheelEvent) => {
|
||||||
|
console.log('wheel')
|
||||||
|
if (noWheel(event)) return
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
event.stopImmediatePropagation()
|
event.stopImmediatePropagation()
|
||||||
|
|
||||||
@@ -132,7 +138,12 @@ invoke(async () => {
|
|||||||
})
|
})
|
||||||
.on('wheel.zoom', null)
|
.on('wheel.zoom', null)
|
||||||
} else if (typeof d3ZoomHandler !== 'undefined') {
|
} else if (typeof d3ZoomHandler !== 'undefined') {
|
||||||
d3s?.on('wheel', null).on('wheel.zoom', d3ZoomHandler)
|
d3s
|
||||||
|
?.on('wheel', (event: WheelEvent) => {
|
||||||
|
if (!props.preventScrolling || noWheel(event)) return
|
||||||
|
event.preventDefault()
|
||||||
|
})
|
||||||
|
.on('wheel.zoom', d3ZoomHandler)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -150,7 +161,7 @@ invoke(async () => {
|
|||||||
// if zoom on double click is disabled, we prevent the double click event
|
// if zoom on double click is disabled, we prevent the double click event
|
||||||
if (!props.zoomOnDoubleClick && event.type === 'dblclick') return false
|
if (!props.zoomOnDoubleClick && event.type === 'dblclick') return false
|
||||||
|
|
||||||
if ((event.target as Element).closest('.nowheel') && event.type === 'wheel') return false
|
if (noWheel(event) && event.type === 'wheel') return false
|
||||||
|
|
||||||
// when the target element is a node, we still allow zooming
|
// when the target element is a node, we still allow zooming
|
||||||
if (
|
if (
|
||||||
@@ -209,11 +220,7 @@ export default {
|
|||||||
<div ref="zoomPane" class="vue-flow__renderer vue-flow__zoompane">
|
<div ref="zoomPane" class="vue-flow__renderer vue-flow__zoompane">
|
||||||
<slot
|
<slot
|
||||||
v-bind="{
|
v-bind="{
|
||||||
transform: [
|
transform: store.transform,
|
||||||
clamp(transform.x, store.translateExtent[0][0], store.translateExtent[1][0]),
|
|
||||||
clamp(transform.y, store.translateExtent[0][0], store.translateExtent[1][0]),
|
|
||||||
clamp(transform.zoom, store.translateExtent[0][0], store.translateExtent[1][0]),
|
|
||||||
],
|
|
||||||
dimensions: { width, height },
|
dimensions: { width, height },
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ export interface FlowOptions {
|
|||||||
panOnScrollSpeed?: number
|
panOnScrollSpeed?: number
|
||||||
panOnScrollMode?: PanOnScrollMode
|
panOnScrollMode?: PanOnScrollMode
|
||||||
zoomOnDoubleClick?: boolean
|
zoomOnDoubleClick?: boolean
|
||||||
|
preventScrolling?: boolean
|
||||||
edgeUpdaterRadius?: number
|
edgeUpdaterRadius?: number
|
||||||
storageKey?: string
|
storageKey?: string
|
||||||
loading?: Loading
|
loading?: Loading
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ export const initialState = (): FlowState => ({
|
|||||||
[Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
[Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
||||||
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
||||||
],
|
],
|
||||||
|
preventScrolling: true,
|
||||||
zoomOnScroll: true,
|
zoomOnScroll: true,
|
||||||
zoomOnPinch: true,
|
zoomOnPinch: true,
|
||||||
zoomOnDoubleClick: true,
|
zoomOnDoubleClick: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user