fix text box size
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -35,12 +35,9 @@ const getColorWithOpacity = (fill?: string, opacity?: number): string => {
|
||||
|
||||
const TextShape = ({
|
||||
obj,
|
||||
isSelected,
|
||||
transformerRef,
|
||||
onSelect,
|
||||
onUpdate,
|
||||
draggable,
|
||||
layerRef,
|
||||
}: TextShapeProps) => {
|
||||
const shapeRef = useRef<Konva.Text>(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 (
|
||||
<Text
|
||||
ref={shapeRef}
|
||||
id={obj.id}
|
||||
name="text-object"
|
||||
x={obj.x}
|
||||
y={obj.y}
|
||||
text={obj.text || ""}
|
||||
@@ -68,8 +92,6 @@ const TextShape = ({
|
||||
fontFamily={fontFamily}
|
||||
fontStyle={fontWeight}
|
||||
letterSpacing={obj.letterSpacing ?? 0}
|
||||
width={obj.width}
|
||||
height={obj.height}
|
||||
align="right"
|
||||
rotation={obj.rotation || 0}
|
||||
draggable={draggable}
|
||||
@@ -95,71 +117,17 @@ const TextShape = ({
|
||||
node.scaleX(1);
|
||||
node.scaleY(1);
|
||||
|
||||
// محاسبه اندازه واقعی متن بعد از transform
|
||||
const clientRect = node.getClientRect({ skipTransform: true });
|
||||
const newWidth = clientRect.width * scaleX;
|
||||
const newHeight = clientRect.height * scaleY;
|
||||
|
||||
onUpdate(obj.id, {
|
||||
x: node.x(),
|
||||
y: node.y(),
|
||||
rotation: node.rotation(),
|
||||
width: obj.width ? Math.max(5, obj.width * scaleX) : undefined,
|
||||
height: obj.height ? Math.max(5, obj.height * scaleY) : undefined,
|
||||
});
|
||||
}}
|
||||
onDblClick={(e) => {
|
||||
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),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -696,10 +696,25 @@ export const useEditorStore = create<EditorStoreType>((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
|
||||
|
||||
Reference in New Issue
Block a user