import type { Component, UIData } from "../types/component";
import { useEffect, useState } from "react";
export function useDragComponent(
selectingComponent: Component | null,
moveComponent: (screenId: string, componentId: string, uiData: UIData) => void,
scale: number,
widgetScale: number
) {
const [componentX, setComponentX] = useState<number>(0);
const [componentY, setComponentY] = useState<number>(0);
const [componentW, setComponentW] = useState<number>(0);
const [componentH, setComponentH] = useState<number>(0);
const baseX = selectingComponent ? selectingComponent.uiData.posX : 0;
const baseY = selectingComponent ? selectingComponent.uiData.posY : 0;
const baseW = selectingComponent ? selectingComponent.uiData.width : 0;
const baseH = selectingComponent ? selectingComponent.uiData.height : 0;
const [prevX, setPrevX] = useState<number>(0);
const [prevY, setPrevY] = useState<number>(0);
const MIN_WIDTH = 50;
const MIN_HEIGHT = 20;
useEffect(() => {
// eslint-disable-next-line react-hooks/set-state-in-effect
setComponentX(baseX);
}, [baseX])
useEffect(() => {
// eslint-disable-next-line react-hooks/set-state-in-effect
setComponentY(baseY)
}, [baseY])
useEffect(() => {
// eslint-disable-next-line react-hooks/set-state-in-effect
setComponentW(baseW);
}, [baseW]);
useEffect(() => {
// eslint-disable-next-line react-hooks/set-state-in-effect
setComponentH(baseH);
}, [baseH])
const onDragStart = (e: React.DragEvent) => {
e.stopPropagation();
setPrevX(e.clientX);
setPrevY(e.clientY);
const img = new Image();
img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMB/VEvKukAAAAASUVORK5CYII="; // 1x1透明PNG
e.dataTransfer.setDragImage(img, 0, 0);
}
const draggingComponent = (e: React.DragEvent) => {
e.stopPropagation();
if (e.clientX == 0 || e.clientY == 0) {
return;
}
setComponentX((prev) => prev + (e.clientX - prevX) / (scale * widgetScale))
setComponentY((prev) => prev + (e.clientY - prevY) / (scale * widgetScale))
setPrevX(e.clientX);
setPrevY(e.clientY);
}
const draggingSquare = (e: React.DragEvent, index: number) => {
e.stopPropagation()
if (e.clientX == 0 || e.clientY == 0) {
return;
}
const dx = (e.clientX - prevX) / (scale * widgetScale);
const dy = (e.clientY - prevY) / (scale * widgetScale);
if (index == 0) {
if (componentW - dx > MIN_WIDTH) {
setComponentX((prev) => prev + dx)
setComponentW((prev) => prev - dx);
}
if (componentH - dy > MIN_HEIGHT) {
setComponentY((prev) => prev + dy)
setComponentH((prev) => prev - dy);
}
} else if (index == 1) {
if (componentW + dx > MIN_WIDTH) {
setComponentW((prev) => prev + dx);
}
if (componentH - dy > MIN_HEIGHT) {
setComponentY((prev) => prev + dy)
setComponentH((prev) => prev - dy);
}
} else if (index == 2) {
if (componentW + dx > MIN_WIDTH) {
setComponentW((prev) => prev + dx);
}
if (componentH + dy > MIN_HEIGHT) {
setComponentH((prev) => prev + dy);
}
} else {
if (componentW - dx > MIN_WIDTH) {
setComponentX((prev) => prev + dx)
setComponentW((prev) => prev - dx);
}
if (componentH + dy > MIN_HEIGHT) {
setComponentH((prev) => prev + dy);
}
}
setPrevX(e.clientX);
setPrevY(e.clientY);
}
const onDragEnd = (e: React.DragEvent) => {
e.stopPropagation();
if (!selectingComponent) return;
const nextUiData: UIData = {
posX: componentX,
posY: componentY,
width: componentW,
height: componentH
}
moveComponent(selectingComponent.screenId, selectingComponent.id, nextUiData);
}
return {
componentX,
componentY,
componentW,
componentH,
onDragStart,
draggingComponent,
draggingSquare,
onDragEnd
};
}