2022-08-23 23:35:36 +02:00
|
|
|
import { useWindowEvent } from '@/utils/hooks/useWindowEvent'
|
|
|
|
|
import { useState } from 'preact/hooks'
|
|
|
|
|
import { BoxDefinition } from '../types'
|
2022-08-24 09:02:52 +02:00
|
|
|
import { GRID_H_SNAP, GRID_WIDTH } from '../constants'
|
2022-08-23 23:35:36 +02:00
|
|
|
|
|
|
|
|
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))
|
|
|
|
|
)
|
|
|
|
|
|
2022-08-24 09:02:52 +02:00
|
|
|
const dragY = Math.round(state.y / GRID_H_SNAP) * GRID_H_SNAP
|
2022-08-23 23:35:36 +02:00
|
|
|
|
|
|
|
|
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])
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|