62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
import { useCallback } from "react";
|
|
import { useEditorStore, type EditorObject } from "../../store/editorStore";
|
|
|
|
export const useObjectHandlers = () => {
|
|
// All handlers read live state via getState() and are wrapped in useCallback
|
|
// with empty deps so their references never change between renders.
|
|
// This prevents ObjectsLayer (and every ObjectRenderer inside it) from
|
|
// re-rendering whenever unrelated EditorCanvas state (e.g. active guide IDs)
|
|
// changes during drag — eliminating lag and flickering on masked groups.
|
|
|
|
const handleObjectUpdate = useCallback((id: string, updates: Partial<EditorObject>) => {
|
|
const { objects, updateObject } = useEditorStore.getState();
|
|
const obj = objects.find((o) => o.id === id);
|
|
if (!obj) return;
|
|
|
|
if (obj.type === "group" && (updates.x !== undefined || updates.y !== undefined)) {
|
|
const groupMembers = objects.filter((o) => o.groupId === id);
|
|
const deltaX = updates.x !== undefined ? updates.x - (obj.x || 0) : 0;
|
|
const deltaY = updates.y !== undefined ? updates.y - (obj.y || 0) : 0;
|
|
|
|
updateObject(id, updates);
|
|
|
|
groupMembers.forEach((member) => {
|
|
updateObject(member.id, {
|
|
x: (member.x || 0) + deltaX,
|
|
y: (member.y || 0) + deltaY,
|
|
});
|
|
});
|
|
} else {
|
|
updateObject(id, updates);
|
|
}
|
|
}, []);
|
|
|
|
const handleGroupWithMask = useCallback((objectId: string, maskId: string) => {
|
|
useEditorStore.getState().groupObjects([objectId, maskId]);
|
|
}, []);
|
|
|
|
const handleUngroupFromMask = useCallback((groupId: string) => {
|
|
useEditorStore.getState().ungroupObjects(groupId);
|
|
}, []);
|
|
|
|
const handleCellEditorSave = useCallback((text: string) => {
|
|
const { editingCell, updateCellValue, setEditingCell } = useEditorStore.getState();
|
|
if (editingCell) {
|
|
updateCellValue(editingCell.tableId, editingCell.cellId, text);
|
|
setEditingCell(null);
|
|
}
|
|
}, []);
|
|
|
|
const handleCellEditorCancel = useCallback(() => {
|
|
useEditorStore.getState().setEditingCell(null);
|
|
}, []);
|
|
|
|
return {
|
|
handleObjectUpdate,
|
|
handleGroupWithMask,
|
|
handleUngroupFromMask,
|
|
handleCellEditorSave,
|
|
handleCellEditorCancel,
|
|
};
|
|
};
|