automated_admin/src/modules/fixtures/static/js/DraggableResizableClass.ts

160 lines
5.1 KiB
TypeScript
Raw Normal View History

2025-01-09 16:40:36 +08:00
export class DraggableResizableClass {
private container: HTMLElement;
private items: any[];
private containerRect: DOMRect;
constructor(container: HTMLElement, items: any[]) {
this.container = container;
this.items = items;
this.containerRect = this.container.getBoundingClientRect();
this.init();
}
private init() {
this.updateListeners();
}
public updateListeners() {
const elements = this.container.querySelectorAll(".draggable-resizable");
elements.forEach((el, index) => {
const handles = (el as HTMLElement).querySelectorAll(".resize-handle");
handles.forEach(handle => {
handle.addEventListener("mousedown", (e) => this.onResizeMouseDown(e, index, handle as HTMLElement));
});
(el as HTMLElement).addEventListener("mousedown", (e) => this.onMouseDown(e, index));
});
}
private onMouseDown(event: MouseEvent, index: number) {
if ((event.target as HTMLElement).classList.contains("resize-handle")) {
return;
}
const item = this.items[index];
const startX = event.clientX;
const startY = event.clientY;
const startLeft = item.x;
const startTop = item.y;
const onMouseMove = (e: MouseEvent) => {
const dx = e.clientX - startX;
const dy = e.clientY - startY;
item.x = Math.min(
Math.max(startLeft + dx, 0),
this.containerRect.width - item.w
);
item.y = Math.min(
Math.max(startTop + dy, 0),
this.containerRect.height - item.h
);
this.updateStyles(index);
};
const onMouseUp = () => {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
}
private onResizeMouseDown(event: MouseEvent, index: number, handle: HTMLElement) {
event.stopPropagation(); // Prevent triggering drag event
const item = this.items[index];
const startX = event.clientX;
const startY = event.clientY;
const startWidth = item.w;
const startHeight = item.h;
const startLeft = item.x;
const startTop = item.y;
const handleClass = handle.classList[1]; // Get the class of the handle
const onMouseMove = (e: MouseEvent) => {
let newWidth = startWidth;
let newHeight = startHeight;
let newLeft = startLeft;
let newTop = startTop;
switch (handleClass) {
case 'top-left':
newWidth = Math.max(startWidth - (e.clientX - startX), 60);
newHeight = Math.max(startHeight - (e.clientY - startY), 30);
newLeft = startLeft + (startWidth - newWidth);
newTop = startTop + (startHeight - newHeight);
break;
case 'top-right':
newWidth = Math.max(startWidth + (e.clientX - startX), 60);
newHeight = Math.max(startHeight - (e.clientY - startY), 30);
newTop = startTop + (startHeight - newHeight);
break;
case 'bottom-left':
newWidth = Math.max(startWidth - (e.clientX - startX), 60);
newHeight = Math.max(startHeight + (e.clientY - startY), 30);
newLeft = startLeft + (startWidth - newWidth);
break;
case 'bottom-right':
newWidth = Math.max(startWidth + (e.clientX - startX), 60);
newHeight = Math.max(startHeight + (e.clientY - startY), 30);
break;
case 'top':
newHeight = Math.max(startHeight - (e.clientY - startY), 30);
newTop = startTop + (startHeight - newHeight);
break;
case 'right':
newWidth = Math.max(startWidth + (e.clientX - startX), 60);
break;
case 'bottom':
newHeight = Math.max(startHeight + (e.clientY - startY), 30);
break;
case 'left':
newWidth = Math.max(startWidth - (e.clientX - startX), 60);
newLeft = startLeft + (startWidth - newWidth);
break;
}
// Ensure resizing does not go outside container boundaries
newWidth = Math.min(Math.max(newWidth, 60), this.containerRect.width - newLeft);
newHeight = Math.min(Math.max(newHeight, 30), this.containerRect.height - newTop);
newLeft = Math.max(Math.min(newLeft, this.containerRect.width - newWidth), 0);
newTop = Math.max(Math.min(newTop, this.containerRect.height - newHeight), 0);
item.w = newWidth;
item.h = newHeight;
item.x = newLeft;
item.y = newTop;
this.updateStyles(index);
};
const onMouseUp = () => {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
}
private updateStyles(index: number) {
const item = this.items[index];
const element = this.container.querySelectorAll(".draggable-resizable")[index] as HTMLElement;
element.style.left = `${item.x}px`;
element.style.top = `${item.y}px`;
element.style.width = `${item.w}px`;
element.style.height = `${item.h}px`;
}
}