refactor(zoom): Move paneReady event to transformation pane mounted hook
* await dimensions in fitView function
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { zoomIdentity } from 'd3-zoom'
|
||||
import useVueFlow from './useVueFlow'
|
||||
import useWindow from './useWindow'
|
||||
import { getRectOfNodes, pointToRendererPoint, getTransformForBounds } from '~/utils'
|
||||
import { GraphNode, FlowStore, UseZoomPanHelper, D3Selection } from '~/types'
|
||||
|
||||
@@ -21,13 +22,18 @@ export default (store: FlowStore = useVueFlow().store): UseZoomPanHelper => ({
|
||||
y: store.transform[1],
|
||||
zoom: store.transform[2],
|
||||
}),
|
||||
fitView: (
|
||||
fitView: async (
|
||||
options = {
|
||||
padding: DEFAULT_PADDING,
|
||||
includeHiddenNodes: false,
|
||||
duration: 0,
|
||||
},
|
||||
) => {
|
||||
// if ssr we can't wait for dimensions, they'll never really exist
|
||||
const window = useWindow()
|
||||
if ('screen' in window)
|
||||
await until(store.dimensions).toMatch(({ height, width }) => !isNaN(width) && width > 0 && !isNaN(height) && height > 0)
|
||||
|
||||
if (!store.getNodes.length) return
|
||||
|
||||
let nodes: GraphNode[] = []
|
||||
|
||||
@@ -1,11 +1,36 @@
|
||||
<script lang="ts" setup>
|
||||
import NodeRenderer from '../NodeRenderer/NodeRenderer.vue'
|
||||
import EdgeRenderer from '../EdgeRenderer/EdgeRenderer.vue'
|
||||
import { useVueFlow } from '../../composables'
|
||||
import { useVueFlow, useZoomPanHelper } from '../../composables'
|
||||
import { FlowInstance } from '../../types'
|
||||
import { onLoadGetEdges, onLoadGetElements, onLoadGetNodes, onLoadProject, onLoadToObject } from '../../utils'
|
||||
|
||||
const { id, store } = useVueFlow()
|
||||
|
||||
const transform = computed(() => `translate(${store.transform[0]}px,${store.transform[1]}px) scale(${store.transform[2]})`)
|
||||
|
||||
onMounted(async () => {
|
||||
const { zoomIn, zoomOut, zoomTo, setTransform, getTransform, fitView, fitBounds, setCenter } = useZoomPanHelper(store)
|
||||
const instance: FlowInstance = {
|
||||
fitView: (params = { padding: 0.1 }) => fitView(params),
|
||||
zoomIn,
|
||||
zoomOut,
|
||||
zoomTo,
|
||||
setTransform,
|
||||
getTransform,
|
||||
setCenter,
|
||||
fitBounds,
|
||||
project: onLoadProject(store),
|
||||
getElements: onLoadGetElements(store),
|
||||
getNodes: onLoadGetNodes(store),
|
||||
getEdges: onLoadGetEdges(store),
|
||||
toObject: onLoadToObject(store),
|
||||
}
|
||||
store.instance = instance
|
||||
store.fitViewOnInit && instance.fitView()
|
||||
store.paneReady = true
|
||||
store.hooks.paneReady.trigger(instance)
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div :key="`transformation-pane-${id}`" class="vue-flow__transformation-pane vue-flow__container" :style="{ transform }">
|
||||
|
||||
@@ -66,7 +66,7 @@ export default {
|
||||
</script>
|
||||
<template>
|
||||
<div class="vue-flow">
|
||||
<ZoomPane :key="`renderer-${id}`" :fit-view-on-init="fitViewOnInit">
|
||||
<ZoomPane :key="`renderer-${id}`">
|
||||
<template v-for="nodeName of Object.keys(getNodeTypes)" #[`node-${nodeName}`]="nodeProps" :key="`node-${nodeName}-${id}`">
|
||||
<slot :name="`node-${nodeName}`" v-bind="nodeProps" />
|
||||
</template>
|
||||
|
||||
@@ -1,22 +1,12 @@
|
||||
<script lang="ts" setup>
|
||||
import { D3ZoomEvent, zoom, zoomIdentity, ZoomTransform } from 'd3-zoom'
|
||||
import { pointer, select } from 'd3-selection'
|
||||
import { FlowInstance, FlowTransform, PanOnScrollMode } from '../../types'
|
||||
import { useKeyPress, useWindow, useZoomPanHelper, useVueFlow } from '../../composables'
|
||||
import {
|
||||
clamp,
|
||||
clampPosition,
|
||||
onLoadGetEdges,
|
||||
onLoadGetElements,
|
||||
onLoadGetNodes,
|
||||
onLoadProject,
|
||||
onLoadToObject,
|
||||
} from '../../utils'
|
||||
import { FlowTransform, PanOnScrollMode } from '../../types'
|
||||
import { useKeyPress, useVueFlow } from '../../composables'
|
||||
import { clamp, clampPosition } from '../../utils'
|
||||
import SelectionPane from '../SelectionPane/SelectionPane.vue'
|
||||
import TransformationPane from '../TransformationPane/TransformationPane.vue'
|
||||
|
||||
const props = defineProps<{ fitViewOnInit?: boolean }>()
|
||||
|
||||
const { id, store } = useVueFlow()
|
||||
const zoomPaneEl = templateRef<HTMLDivElement>('zoomPane', null)
|
||||
|
||||
@@ -55,22 +45,6 @@ onMounted(async () => {
|
||||
store.d3ZoomHandler = d3ZoomHandler
|
||||
store.transform = [updatedTransform.x, updatedTransform.y, updatedTransform.k]
|
||||
|
||||
d3z.on('start', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||
if (viewChanged(transform.value, event.transform)) {
|
||||
const flowTransform = eventToFlowTransform(event.transform)
|
||||
transform.value = flowTransform
|
||||
store.hooks.moveStart.trigger(flowTransform)
|
||||
}
|
||||
})
|
||||
|
||||
d3z.on('end', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||
if (viewChanged(transform.value, event.transform)) {
|
||||
const flowTransform = eventToFlowTransform(event.transform)
|
||||
transform.value = flowTransform
|
||||
store.hooks.moveEnd.trigger(flowTransform)
|
||||
}
|
||||
})
|
||||
|
||||
const selectionKeyPressed = useKeyPress(store.selectionKeyCode, (keyPress) => {
|
||||
if (keyPress) {
|
||||
d3z.on('zoom', null)
|
||||
@@ -87,6 +61,22 @@ onMounted(async () => {
|
||||
|
||||
const zoomKeyPressed = store.zoomActivationKeyCode ? useKeyPress(store.zoomActivationKeyCode) : ref(true)
|
||||
|
||||
d3z.on('start', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||
if (viewChanged(transform.value, event.transform)) {
|
||||
const flowTransform = eventToFlowTransform(event.transform)
|
||||
transform.value = flowTransform
|
||||
store.hooks.moveStart.trigger(flowTransform)
|
||||
}
|
||||
})
|
||||
|
||||
d3z.on('end', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||
if (viewChanged(transform.value, event.transform)) {
|
||||
const flowTransform = eventToFlowTransform(event.transform)
|
||||
transform.value = flowTransform
|
||||
store.hooks.moveEnd.trigger(flowTransform)
|
||||
}
|
||||
})
|
||||
|
||||
d3s
|
||||
?.on('wheel', (event: WheelEvent) => {
|
||||
if (zoomKeyPressed.value) {
|
||||
@@ -163,51 +153,24 @@ onMounted(async () => {
|
||||
// default filter for d3-zoom
|
||||
return (!event.ctrlKey || event.type === 'wheel') && !event.button
|
||||
})
|
||||
|
||||
watch(
|
||||
[width, height],
|
||||
([newWidth, newHeight]) => {
|
||||
store.dimensions.width = newWidth
|
||||
store.dimensions.height = newHeight
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
watch(
|
||||
transform,
|
||||
(val) => {
|
||||
const { x, y } = clampPosition(val, store.translateExtent)
|
||||
store.transform = [x, y, clamp(val.zoom, store.minZoom, store.maxZoom)]
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
store.paneReady = true
|
||||
|
||||
// if ssr we can't wait for dimensions, they'll never really exist
|
||||
const window = useWindow()
|
||||
if ('screen' in window)
|
||||
await until(store.dimensions).toMatch(({ height, width }) => !isNaN(width) && width > 0 && !isNaN(height) && height > 0)
|
||||
|
||||
const { zoomIn, zoomOut, zoomTo, setTransform, getTransform, fitView, fitBounds, setCenter } = useZoomPanHelper(store)
|
||||
const instance: FlowInstance = {
|
||||
fitView: (params = { padding: 0.1 }) => fitView(params),
|
||||
zoomIn,
|
||||
zoomOut,
|
||||
zoomTo,
|
||||
setTransform,
|
||||
getTransform,
|
||||
setCenter,
|
||||
fitBounds,
|
||||
project: onLoadProject(store),
|
||||
getElements: onLoadGetElements(store),
|
||||
getNodes: onLoadGetNodes(store),
|
||||
getEdges: onLoadGetEdges(store),
|
||||
toObject: onLoadToObject(store),
|
||||
}
|
||||
store.instance = instance
|
||||
props.fitViewOnInit && instance.fitView()
|
||||
store.hooks.paneReady.trigger(instance)
|
||||
})
|
||||
|
||||
watch(
|
||||
[width, height],
|
||||
([newWidth, newHeight]) => {
|
||||
store.dimensions.width = newWidth
|
||||
store.dimensions.height = newHeight
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
watch(
|
||||
transform,
|
||||
(val) => {
|
||||
const { x, y } = clampPosition(val, store.translateExtent)
|
||||
store.transform = [x, y, clamp(val.zoom, store.minZoom, store.maxZoom)]
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
</script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
|
||||
Reference in New Issue
Block a user