Files
vue-flow/package/src/container/Viewport/Transform.vue
T
Braks f5d245322b feat: Add emits property to store
# What's changed?

* For easier access (and shorter syntax) of event emitters add emits property to store
* Change instance, zoom, hooks, emits and onEvent triggers to readonly
2022-04-24 13:34:22 +02:00

89 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 { Dimensions, FlowExportObject, FlowInstance, XYPosition } from '../../types'
import { pointToRendererPoint } from '../../utils'
const { id, nodes, edges, viewport, snapToGrid, snapGrid, dimensions, setState, fitViewOnInit, emits } = $(useVueFlow())
const untilDimensions = async (dim: Dimensions) => {
// 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(dim).toMatch(({ height, width }) => !isNaN(width) && width > 0 && !isNaN(height) && height > 0)
}
return true
}
let ready = $ref(false)
onMounted(async () => {
// create new instance and set to state
const { fitView, ...rest } = useZoomPanHelper()
let instance: FlowInstance | null = {
fitView: (params = { padding: 0.1 }) => fitView(params),
...rest,
project(position: XYPosition) {
return pointToRendererPoint(position, viewport, snapToGrid, snapGrid)
},
getElements() {
return [...nodes, ...edges]
},
getNodes() {
return nodes
},
getEdges() {
return 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,
edges,
position: [viewport.x, viewport.y],
zoom: viewport.zoom,
} as FlowExportObject),
)
},
}
onScopeDispose(() => (instance = null))
// wait until proper dimensions have been established, otherwise fitView will have wrong bounds when called at paneReady
await untilDimensions(dimensions)
// hide graph until dimensions are ready, so we don't have jumping graphs (ssr for example)
ready = true
setState({
instance,
})
fitViewOnInit && instance.fitView()
emits.paneReady(instance)
})
const transform = computed(() => `translate(${viewport.x}px,${viewport.y}px) scale(${viewport.zoom})`)
</script>
<script lang="ts">
export default {
name: 'Transform',
}
</script>
<template>
<div
:key="`transform-${id}`"
class="vue-flow__transformationpane vue-flow__container"
:style="{ transform, opacity: ready ? undefined : 0 }"
>
<NodeRenderer />
<EdgeRenderer />
<slot />
</div>
</template>