diff --git a/src/pages/editor/components/canvas/useDrawingHandlers.ts b/src/pages/editor/components/canvas/useDrawingHandlers.ts index 8f2d454..bfacc5c 100644 --- a/src/pages/editor/components/canvas/useDrawingHandlers.ts +++ b/src/pages/editor/components/canvas/useDrawingHandlers.ts @@ -76,6 +76,8 @@ export const useDrawingHandlers = () => { opacity: defaults.opacity, letterSpacing: defaults.letterSpacing, wordSpacing: defaults.wordSpacing, + width: 150, + height: defaults.fontSize || 24, }; addObject(newText); setSelectedObjectId(newText.id); diff --git a/src/pages/editor/components/tools/TextShape.tsx b/src/pages/editor/components/tools/TextShape.tsx index 9361095..90f69ff 100644 --- a/src/pages/editor/components/tools/TextShape.tsx +++ b/src/pages/editor/components/tools/TextShape.tsx @@ -35,12 +35,9 @@ const getColorWithOpacity = (fill?: string, opacity?: number): string => { const TextShape = ({ obj, - isSelected, - transformerRef, onSelect, onUpdate, draggable, - layerRef, }: TextShapeProps) => { const shapeRef = useRef(null); @@ -53,6 +50,31 @@ const TextShape = ({ } }, []); + // Update actual text dimensions after render + useEffect(() => { + if (shapeRef.current) { + const node = shapeRef.current; + const clientRect = node.getClientRect({ skipTransform: true }); + + // اگر width یا height واقعی با مقدار ذخیره شده متفاوت است، آپدیت کن + if (clientRect.width && clientRect.height) { + const needsUpdate = + !obj.width || + !obj.height || + Math.abs((obj.width || 0) - clientRect.width) > 5 || + Math.abs((obj.height || 0) - clientRect.height) > 5; + + if (needsUpdate) { + onUpdate(obj.id, { + width: Math.ceil(clientRect.width), + height: Math.ceil(clientRect.height), + }); + } + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [obj.text, obj.fontSize, obj.fontFamily, obj.fontWeight, obj.letterSpacing]); + const fontFamily = useMemo(() => getFontFamily(obj.fontFamily), [obj.fontFamily]); const fontWeight = useMemo(() => getFontWeight(obj.fontWeight), [obj.fontWeight]); const fillColor = useMemo(() => getColorWithOpacity(obj.fill, obj.opacity), [obj.fill, obj.opacity]); @@ -60,6 +82,8 @@ const TextShape = ({ return ( { - const textNode = e.target as Konva.Text; - const stage = textNode.getStage(); - if (!stage) return; - - const stageBox = stage.container().getBoundingClientRect(); - const textPosition = textNode.absolutePosition(); - const scaleX = stage.scaleX() || 1; - const scaleY = stage.scaleY() || 1; - const areaPosition = { - x: stageBox.left + textPosition.x * scaleX, - y: stageBox.top + textPosition.y * scaleY, - }; - - const textarea = document.createElement("textarea"); - document.body.appendChild(textarea); - textNode.hide(); - layerRef.current?.draw(); - textarea.value = textNode.text(); - textarea.style.position = "absolute"; - textarea.style.top = `${areaPosition.y}px`; - textarea.style.left = `${areaPosition.x}px`; - textarea.style.width = `${textNode.width() * scaleX}px`; - textarea.style.fontSize = `${textNode.fontSize() * scaleY}px`; - textarea.style.border = "none"; - textarea.style.padding = "0px"; - textarea.style.margin = "0px"; - textarea.style.overflow = "hidden"; - textarea.style.background = "transparent"; - textarea.style.outline = "none"; - textarea.style.resize = "none"; - textarea.style.fontFamily = fontFamily; - textarea.style.fontWeight = fontWeight === "bold" ? "bold" : "normal"; - textarea.style.letterSpacing = `${obj.letterSpacing ?? 0}px`; - textarea.style.textAlign = textNode.align() || "right"; - textarea.style.direction = "rtl"; - textarea.focus(); - - const removeTextarea = () => { - document.body.removeChild(textarea); - textNode.show(); - textNode.text(textarea.value); - onUpdate(obj.id, { text: textarea.value }); - layerRef.current?.draw(); - }; - - textarea.addEventListener("keydown", (e) => { - if (e.key === "Enter" && !e.shiftKey) { - removeTextarea(); - } - if (e.key === "Escape") { - removeTextarea(); - } - }); - - textarea.addEventListener("blur", () => { - removeTextarea(); + width: Math.max(5, newWidth), + height: Math.max(5, newHeight), }); }} /> diff --git a/src/pages/editor/store/editorStore.ts b/src/pages/editor/store/editorStore.ts index 1c41b4d..7c9ca0f 100644 --- a/src/pages/editor/store/editorStore.ts +++ b/src/pages/editor/store/editorStore.ts @@ -696,10 +696,25 @@ export const useEditorStore = create((set, get) => { let maxY = -Infinity; objectsToGroup.forEach((obj) => { - const cx = (obj.x || 0) + (obj.width || 0) / 2; - const cy = (obj.y || 0) + (obj.height || 0) / 2; - const w = obj.width || 0; - const h = obj.height || 0; + // برای متن‌هایی که width و height ندارند، از مقادیر پیش‌فرض استفاده کن + let w = obj.width || 0; + let h = obj.height || 0; + + if (obj.type === "text") { + // اگر متن width نداره، از fontSize و طول متن برای تخمین استفاده کن + if (!w) { + const textLength = (obj.text || "").length; + const fontSize = obj.fontSize || 24; + w = Math.max(textLength * fontSize * 0.6, 50); + } + // اگر height نداره، از fontSize استفاده کن + if (!h) { + h = obj.fontSize || 24; + } + } + + const cx = (obj.x || 0) + w / 2; + const cy = (obj.y || 0) + h / 2; const rot = ((obj.rotation || 0) * Math.PI) / 180; // محاسبه چهار گوشه rectangle با rotation