Files
vue-flow/src/container/ZoomPane/ZoomPane.vue
T

66 lines
1.9 KiB
Vue

<script lang="ts" setup>
import { KeyCode, PanOnScrollMode } from '~/types'
import { useZoom, useZoomPanHelper } from '~/composables'
import { Hooks, Store } from '~/context'
import { onLoadGetElements, onLoadProject, onLoadToObject } from '~/utils/graph'
interface ZoomPaneProps {
selectionKeyCode?: KeyCode
zoomActivationKeyCode?: KeyCode
paneMoveable?: boolean
defaultZoom?: number
defaultPosition?: [number, number]
zoomOnScroll?: boolean
zoomOnPinch?: boolean
panOnScroll?: boolean
panOnScrollSpeed?: number
panOnScrollMode?: PanOnScrollMode
zoomOnDoubleClick?: boolean
}
const props = withDefaults(defineProps<ZoomPaneProps>(), {
selectionKeyCode: 'Shift',
zoomActivationKeyCode: 'Meta',
defaultZoom: 1,
defaultPosition: () => [0, 0],
zoomOnScroll: true,
zoomOnPinch: true,
zoomOnDoubleClick: true,
panOnScroll: false,
panOnScrollSpeed: 0.5,
panOnScrollMode: PanOnScrollMode.Free,
paneMoveable: true,
})
const store = inject(Store)!
const hooks = inject(Hooks)!
const zoomPaneEl = templateRef<HTMLDivElement>('zoom-pane', null)
const { transform } = useZoom(zoomPaneEl, props)
const { width, height } = useElementBounding(zoomPaneEl)
watch(width, (val) => (store.dimensions.width = val))
watch(height, (val) => (store.dimensions.height = val))
watch(transform, (val) => (store.transform = val))
store.transform = transform.value
store.dimensions = {
width: width.value,
height: height.value,
}
const { zoomIn, zoomOut, zoomTo, transform: setTransform, fitView } = useZoomPanHelper()
hooks.load.trigger({
fitView: (params = { padding: 0.1 }) => fitView(params),
zoomIn,
zoomOut,
zoomTo,
setTransform,
project: onLoadProject(store),
getElements: onLoadGetElements(store),
toObject: onLoadToObject(store),
})
</script>
<template>
<div ref="zoom-pane" class="revue-flow__renderer revue-flow__zoompane">
<slot v-bind="{ transform, dimensions: { width, height } }"></slot>
</div>
</template>