graphicek/client/src/pages/dashboard/hooks/useDragging.ts

69 lines
1.3 KiB
TypeScript
Raw Normal View History

2022-08-23 23:35:36 +02:00
import { useWindowEvent } from '@/utils/hooks/useWindowEvent'
import { useState } from 'preact/hooks'
import { BoxDefinition } from '../types'
import { GRID_WIDTH } from '../constants'
type Props = {
cellWidth: number
boxes: BoxDefinition[]
box: BoxDefinition
}
// TODO: This is not optimized at all
export const useDragging = ({ cellWidth, boxes, box }: Props) => {
const [state, setState] = useState({
active: false,
x: 0,
y: 0,
offsetX: 0,
offsetY: 0,
})
const actualX = Math.max(
0,
Math.min(GRID_WIDTH - box.w, Math.round(state.x / cellWidth))
)
const dragY = Math.round(state.y / 16) * 16
const gridHeights = Array(GRID_WIDTH)
.fill(null)
.map((_, index) => {
return boxes
.filter(
(b) =>
b.id !== box.id &&
b.x <= index &&
b.x + b.w > index &&
((b.y < dragY + box.h && dragY < b.y + b.h) || b.y < dragY)
)
.reduce(
(acc, item) => (item.y + item.h > acc ? item.y + item.h : acc),
0
)
})
useWindowEvent('mousemove', (e) => {
if (state.active) {
setState({
...state,
x: e.clientX - state.offsetX,
y: e.clientY - state.offsetY,
})
}
})
return {
dragging: state,
setDragging: setState,
draggingPosition: {
x: actualX,
y: Math.max(
...Array(box.w)
.fill(null)
.map((_, x) => gridHeights[actualX + x])
),
},
}
}