Files
vue-flow/package/src/container/Viewport/Transform.vue
T
Braks b6d8b57859 chore: Performance optimizations
# What's changed?

* Remove keys
* Stabilize props
* Force reset store on unmount
2022-04-24 13:34:22 +02:00

84 lines
2.5 KiB
Vue

<script lang="ts" setup>
import NodeRenderer from '../NodeRenderer/NodeRenderer.vue'
import EdgeRenderer from '../EdgeRenderer/EdgeRenderer.vue'
import { useVueFlow, useZoomPanHelper, useWindow } from '../../composables'
import { FlowExportObject, FlowInstance, Store, XYPosition } from '../../types'
import { pointToRendererPoint } from '../../utils'
const { store } = useVueFlow()
const untilDimensions = async (store: Store) => {
// if ssr we can't wait for dimensions, they'll never really exist
const window = useWindow()
if ('screen' in window) {
// wait until viewport dimensions has been established
await until(store.dimensions).toMatch(({ height, width }) => !isNaN(width) && width > 0 && !isNaN(height) && height > 0)
}
return true
}
const ready = ref(false)
onMounted(async () => {
const { fitView, ...rest } = useZoomPanHelper(store)
let instance: FlowInstance | null = {
fitView: (params = { padding: 0.1 }) => fitView(params),
...rest,
project(position: XYPosition) {
return pointToRendererPoint(position, store.viewport, store.snapToGrid, store.snapGrid)
},
getElements() {
return [...store.nodes, ...store.edges]
},
getNodes() {
return store.nodes
},
getEdges() {
return store.edges
},
toObject() {
// we have to stringify/parse so objects containing refs (like nodes and edges) can potentially be saved in a storage
return JSON.parse(
JSON.stringify({
nodes: store.nodes,
edges: store.edges,
position: [store.viewport.x, store.viewport.y],
zoom: store.viewport.zoom,
} as FlowExportObject),
)
},
}
onScopeDispose(() => (instance = null))
await untilDimensions(store)
ready.value = true
store.instance = instance as FlowInstance
store.fitViewOnInit && instance.fitView()
store.hooks.paneReady.trigger(instance as FlowInstance)
})
const transform = computed(() => `translate(${store.viewport.x}px,${store.viewport.y}px) scale(${store.viewport.zoom})`)
</script>
<script lang="ts">
export default {
name: 'Transform',
}
</script>
<template>
<div class="vue-flow__transformationpane vue-flow__container" :style="{ transform, opacity: ready ? undefined : 0 }">
<NodeRenderer
:draggable="store.nodesDraggable"
:selectable="store.elementsSelectable"
:connectable="store.nodesConnectable"
:nodes="store.getNodes"
:snap-to-grid="store.snapToGrid"
:snap-grid="store.snapGrid"
/>
<EdgeRenderer />
<slot />
</div>
</template>