Files
dpage-editor/src/pages/editor/components/canvas/useDrawingHandlers.ts
T
hamid zarghami 1518e83c1d text alignment
2026-05-06 09:32:36 +03:30

149 lines
4.6 KiB
TypeScript

import { useState, useRef, useEffect } from "react";
import Konva from "konva";
import { useEditorStore, type EditorObject } from "@/pages/editor/store/editorStore";
import { useTextDefaultsStore } from "@/pages/editor/store/textDefaultsStore";
import { createDrawingObject } from "./drawingUtils";
export const useDrawingHandlers = () => {
const [isDrawing, setIsDrawing] = useState(false);
const [startPos, setStartPos] = useState({ x: 0, y: 0 });
const [tempObject, setTempObject] = useState<EditorObject | null>(null);
const transformerRef = useRef<Konva.Transformer>(null);
const { tool, addObject, updateObject, setSelectedObjectId, setSelectedObjectIds, selectedObjectIds, setTool, addTable, setSelectedTableId } = useEditorStore();
const { defaults } = useTextDefaultsStore();
useEffect(() => {
setTempObject(null);
setIsDrawing(false);
}, [tool]);
const clearSelection = () => {
setSelectedObjectIds([]);
if (transformerRef.current) {
transformerRef.current.nodes([]);
transformerRef.current.getLayer()?.batchDraw();
}
};
const handleStageMouseDown = (e: Konva.KonvaEventObject<MouseEvent>) => {
const stage = e.target.getStage();
if (!stage) return;
const clickedOnEmpty = e.target === stage;
if (clickedOnEmpty && selectedObjectIds.length > 0) {
clearSelection();
return;
}
if (tool === "select") {
if (clickedOnEmpty) {
clearSelection();
}
return;
}
if (selectedObjectIds.length > 0) {
return;
}
const pointerPos = stage.getPointerPosition();
if (!pointerPos) return;
// تبدیل موقعیت به مختصات واقعی لایه (با در نظر گرفتن scale)
const scaleX = stage.scaleX();
const scaleY = stage.scaleY();
const realPos = {
x: pointerPos.x / scaleX,
y: pointerPos.y / scaleY,
};
setIsDrawing(true);
setStartPos(realPos);
if (tool === "text") {
const newText: EditorObject = {
id: `text-${Date.now()}`,
type: "text",
x: realPos.x,
y: realPos.y,
text: "متن جدید",
fontSize: defaults.fontSize,
lineHeight: 1.2,
textAlign: "right",
fontFamily: defaults.fontFamily,
fontWeight: defaults.fontWeight,
fill: defaults.fill,
opacity: defaults.opacity,
letterSpacing: defaults.letterSpacing,
wordSpacing: defaults.wordSpacing,
width: 150,
height: defaults.fontSize || 24,
};
addObject(newText);
setSelectedObjectId(newText.id);
setTool("select");
}
if (tool === "grid") {
addTable(realPos.x, realPos.y, 4, 5);
setSelectedTableId(null);
setTool("select");
}
};
const handleStageMouseMove = (e: Konva.KonvaEventObject<MouseEvent>) => {
if (!isDrawing || tool === "select" || tool === "text") return;
const stage = e.target.getStage();
if (!stage) return;
const pointerPos = stage.getPointerPosition();
if (!pointerPos) return;
// تبدیل موقعیت به مختصات واقعی لایه (با در نظر گرفتن scale)
const scaleX = stage.scaleX();
const scaleY = stage.scaleY();
const realPos = {
x: pointerPos.x / scaleX,
y: pointerPos.y / scaleY,
};
const newObject = createDrawingObject({ tool, startPos, pointerPos: realPos, tempObject });
if (!newObject) return;
if (!tempObject) {
addObject(newObject);
setTempObject(newObject);
} else {
const updates: Partial<EditorObject> = {
x: newObject.x,
y: newObject.y,
width: newObject.width,
height: newObject.height,
};
updateObject(tempObject.id, updates);
}
};
const handleStageMouseUp = () => {
const lastObjectId = tempObject?.id;
setIsDrawing(false);
setTempObject(null);
if (lastObjectId) {
setSelectedObjectId(lastObjectId);
setTool("select");
}
};
return {
isDrawing,
transformerRef,
handleStageMouseDown,
handleStageMouseMove,
handleStageMouseUp,
};
};