feat(node-toolbar): add align prop

This commit is contained in:
braks
2023-05-25 20:48:26 +02:00
committed by Braks
parent 5820fcd8d9
commit f5152a9fd3
2 changed files with 38 additions and 20 deletions
+35 -20
View File
@@ -4,43 +4,58 @@ import type { GraphNode, Rect, ViewportTransform } from '@vue-flow/core'
import { NodeIdInjection, Position, getRectOfNodes, useVueFlow } from '@vue-flow/core' import { NodeIdInjection, Position, getRectOfNodes, useVueFlow } from '@vue-flow/core'
import type { CSSProperties } from 'vue' import type { CSSProperties } from 'vue'
import type { NodeToolbarProps } from './types' import type { Align, NodeToolbarProps } from './types'
const props = withDefaults(defineProps<NodeToolbarProps>(), { const props = withDefaults(defineProps<NodeToolbarProps>(), {
position: Position.Top, position: Position.Top,
offset: 10, offset: 10,
align: 'center',
}) })
const contextNodeId = inject(NodeIdInjection, null) const contextNodeId = inject(NodeIdInjection, null)
const { viewportRef, viewport, getSelectedNodes, findNode } = useVueFlow() const { viewportRef, viewport, getSelectedNodes, findNode } = useVueFlow()
function getTransform(nodeRect: Rect, transform: ViewportTransform, position: Position, offset: number): string { function getTransform(nodeRect: Rect, transform: ViewportTransform, position: Position, offset: number, align: Align): string {
let xPos = (nodeRect.x + nodeRect.width / 2) * transform.zoom + transform.x let alignmentOffset = 0.5
let yPos = nodeRect.y * transform.zoom + transform.y - offset
let xShift = -50 if (align === 'start') {
let yShift = -100 alignmentOffset = 0
} else if (align === 'end') {
alignmentOffset = 1
}
// position === Position.Top
// we set the x any y position of the toolbar based on the nodes position
let pos = [
(nodeRect.x + nodeRect.width * alignmentOffset) * transform.zoom + transform.x,
nodeRect.y * transform.zoom + transform.y - offset,
]
// and then shift it based on the alignment. The shift values are in %.
let shift = [-100 * alignmentOffset, -100]
switch (position) { switch (position) {
case Position.Right: case Position.Right:
xPos = (nodeRect.x + nodeRect.width) * transform.zoom + transform.x + offset pos = [
yPos = (nodeRect.y + nodeRect.height / 2) * transform.zoom + transform.y (nodeRect.x + nodeRect.width) * transform.zoom + transform.x + offset,
xShift = 0 (nodeRect.y + nodeRect.height * alignmentOffset) * transform.zoom + transform.y,
yShift = -50 ]
shift = [0, -100 * alignmentOffset]
break break
case Position.Bottom: case Position.Bottom:
yPos = (nodeRect.y + nodeRect.height) * transform.zoom + transform.y + offset pos[1] = (nodeRect.y + nodeRect.height) * transform.zoom + transform.y + offset
yShift = 0 shift[1] = 0
break break
case Position.Left: case Position.Left:
xPos = nodeRect.x * transform.zoom + transform.x - offset pos = [
yPos = (nodeRect.y + nodeRect.height / 2) * transform.zoom + transform.y nodeRect.x * transform.zoom + transform.x - offset,
xShift = -100 (nodeRect.y + nodeRect.height * alignmentOffset) * transform.zoom + transform.y,
yShift = -50 ]
shift = [-100, -100 * alignmentOffset]
break break
} }
return `translate(${xPos}px, ${yPos}px) translate(${xShift}%, ${yShift}%)` return `translate(${pos[0]}px, ${pos[1]}px) translate(${shift[0]}%, ${shift[1]}%)`
} }
const nodes = computed(() => { const nodes = computed(() => {
@@ -63,13 +78,13 @@ const isActive = computed(() =>
: nodes.value.length === 1 && nodes.value[0].selected && getSelectedNodes.value.length === 1, : nodes.value.length === 1 && nodes.value[0].selected && getSelectedNodes.value.length === 1,
) )
const nodeRect = computed<Rect>(() => getRectOfNodes(nodes.value)) const nodeRect = computed(() => getRectOfNodes(nodes.value))
const zIndex = computed<number>(() => Math.max(...nodes.value.map((node) => (node.computedPosition.z || 1) + 1))) const zIndex = computed(() => Math.max(...nodes.value.map((node) => (node.computedPosition.z || 1) + 1)))
const wrapperStyle = computed<CSSProperties>(() => ({ const wrapperStyle = computed<CSSProperties>(() => ({
position: 'absolute', position: 'absolute',
transform: getTransform(nodeRect.value, viewport.value, props.position, props.offset), transform: getTransform(nodeRect.value, viewport.value, props.position, props.offset, props.align),
zIndex: zIndex.value, zIndex: zIndex.value,
})) }))
</script> </script>
+3
View File
@@ -5,4 +5,7 @@ export interface NodeToolbarProps {
isVisible?: boolean isVisible?: boolean
position?: Position position?: Position
offset?: number offset?: number
align?: 'center' | 'start' | 'end'
} }
export type Align = 'center' | 'start' | 'end'