refactor(zoom): Move paneReady event to transformation pane mounted hook

* await dimensions in fitView function
This commit is contained in:
Braks
2022-03-16 16:02:26 +01:00
parent 93e3d8b84f
commit 05929299d3
4 changed files with 70 additions and 76 deletions
+7 -1
View File
@@ -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 }">
+1 -1
View File
@@ -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>
+36 -73
View File
@@ -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 {