feat(core): implement figma controls

Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
braks
2022-12-25 17:38:56 +01:00
committed by Braks
parent f319f6249d
commit fd79ab141d
21 changed files with 381 additions and 317 deletions
@@ -1,25 +0,0 @@
<script lang="ts" setup>
const { width, height, x, y } = defineProps<{
width: number
height: number
x: number
y: number
}>()
</script>
<script lang="ts">
export default {
name: 'SelectionRect',
}
</script>
<template>
<div
class="vue-flow__selection"
:style="{
width: `${width}px`,
height: `${height}px`,
transform: `translate(${x}px, ${y}px)`,
}"
/>
</template>
@@ -1,103 +1,14 @@
<script lang="ts" setup>
import type { SelectionRect as Rect } from '../../types'
import SelectionRect from './SelectionRect.vue'
import { getMousePosition } from './utils'
const { userSelectionActive, nodesSelectionActive, getNodes, getEdges, viewport, addSelectedElements } = useVueFlow()
let prevNodes = $ref(0)
let prevEdges = $ref(0)
const initialRect = () => ({
width: 0,
height: 0,
startX: 0,
startY: 0,
x: 0,
y: 0,
draw: false,
})
let rect = $ref<Rect>(initialRect())
const reset = () => {
rect = initialRect()
prevNodes = 0
prevEdges = 0
userSelectionActive.value = false
}
const onMouseDown = (event: MouseEvent) => {
const mousePos = getMousePosition(event)
if (!mousePos) return
rect = {
width: 0,
height: 0,
startX: mousePos.x,
startY: mousePos.y,
x: mousePos.x,
y: mousePos.y,
draw: true,
}
userSelectionActive.value = true
}
const onMouseMove = (event: MouseEvent) => {
if (!userSelectionActive || !rect.draw) return
const mousePos = getMousePosition(event)
if (!mousePos) return
const startX = rect.startX
const startY = rect.startY
const nextUserSelectRect: Rect = {
...rect,
x: mousePos.x < startX ? mousePos.x : rect.x,
y: mousePos.y < startY ? mousePos.y : rect.y,
width: Math.abs(mousePos.x - startX),
height: Math.abs(mousePos.y - startY),
}
const selectedNodes = getNodesInside(getNodes.value, rect, viewport.value)
const selectedEdges = getConnectedEdges(selectedNodes, getEdges.value)
rect = nextUserSelectRect
addSelectedElements([...selectedNodes, ...selectedEdges])
prevNodes = selectedNodes.length
prevEdges = selectedEdges.length
}
const onMouseUp = () => {
rect = initialRect()
nodesSelectionActive.value = prevNodes > 0
userSelectionActive.value = false
}
onBeforeUnmount(reset)
</script>
<script lang="ts">
export default {
name: 'UserSelection',
}
const { userSelectionRect } = useVueFlow()
</script>
<template>
<div
class="vue-flow__selectionpane vue-flow__container"
@mousedown="onMouseDown"
@mousemove="onMouseMove"
@click="onMouseUp"
@mouseup="onMouseUp"
>
<SelectionRect v-if="rect.draw" :width="rect.width" :height="rect.height" :x="rect.x" :y="rect.y" />
</div>
class="vue-flow__selection react-flow__container"
:style="{
width: `${userSelectionRect?.width}px`,
height: `${userSelectionRect?.height}px`,
transform: `translate(${userSelectionRect?.x}px, ${userSelectionRect?.y}px)`,
}"
/>
</template>
@@ -1,13 +0,0 @@
import type { XYPosition } from '../../types'
export function getMousePosition(event: MouseEvent): XYPosition | void {
const flowNode = (event.target as Element).closest('.vue-flow')
if (!flowNode) return
const containerBounds = flowNode.getBoundingClientRect()
return {
x: event.clientX - containerBounds.left,
y: event.clientY - containerBounds.top,
}
}