From ff6912449ef0f3d45eaa408192d1f20284fab2ed Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Tue, 6 Jan 2026 15:54:24 +0330 Subject: [PATCH] lock resize in group with a object mask --- src/pages/editor/components/EditorCanvas.tsx | 63 +++++++++++++------ .../components/canvas/ObjectRenderer.tsx | 25 ++------ 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/src/pages/editor/components/EditorCanvas.tsx b/src/pages/editor/components/EditorCanvas.tsx index 22f1786..b3698bd 100644 --- a/src/pages/editor/components/EditorCanvas.tsx +++ b/src/pages/editor/components/EditorCanvas.tsx @@ -655,11 +655,39 @@ const EditorCanvas = () => { const isGroup = selectedObject?.type === "group"; // بررسی امکان group/ungroup با mask - const hasMask = selectedObject?.maskId; - const maskObject = hasMask ? objects.find(m => m.id === selectedObject.maskId) : null; - const isGrouped = selectedObject?.groupId && maskObject?.groupId === selectedObject.groupId; - const canGroup = hasMask && !isGrouped && maskObject && !selectedObject?.isMask; - const canUngroup = isGrouped && selectedObject?.groupId; + let isGroupedWithMask = false; + let hasMask = false; + let maskObject = null; + + if (isGroup) { + // اگر این یک group است، بررسی کن که آیا از یک object با mask تشکیل شده + const groupMembers = objects.filter(o => o.groupId === selectedObject.id); + const objectWithMask = groupMembers.find(m => m.maskId); + if (objectWithMask) { + maskObject = groupMembers.find(m => m.id === objectWithMask.maskId); + isGroupedWithMask = !!maskObject; + } + } else { + // اگر یک object معمولی است + hasMask = !!selectedObject?.maskId; + maskObject = hasMask ? objects.find(m => m.id === selectedObject.maskId) : null; + isGroupedWithMask = selectedObject?.groupId && maskObject?.groupId === selectedObject.groupId; + } + + const canGroup = hasMask && !isGroupedWithMask && maskObject && !selectedObject?.isMask; + const canUngroup = isGroupedWithMask && isGroup; + + // اگر با mask گروه شده، امکان ریسایز نباشد + const enabledAnchors = isGroupedWithMask ? [] : [ + "top-left", + "top-right", + "bottom-left", + "bottom-right", + "top-center", + "bottom-center", + "middle-left", + "middle-right", + ]; return ( <> @@ -669,6 +697,10 @@ const EditorCanvas = () => { if (Math.abs(newBox.width) < 5 || Math.abs(newBox.height) < 5) { return oldBox; } + // اگر با mask گروه شده، هیچ تغییر سایزی مجاز نیست + if (isGroupedWithMask) { + return oldBox; + } return newBox; }} ignoreStroke={isText} @@ -678,17 +710,8 @@ const EditorCanvas = () => { borderStroke="#3b82f6" borderStrokeWidth={2} anchorSize={8} - rotateEnabled={!isGroup} - enabledAnchors={[ - "top-left", - "top-right", - "bottom-left", - "bottom-right", - "top-center", - "bottom-center", - "middle-left", - "middle-right", - ]} + rotateEnabled={!isGroup && !isGroupedWithMask} + enabledAnchors={enabledAnchors} /> {/* دکمه گروه‌بندی */} @@ -739,8 +762,8 @@ const EditorCanvas = () => { shadowColor="black" shadowBlur={10} shadowOpacity={0.2} - onClick={() => handleUngroupFromMask(selectedObject.groupId!)} - onTap={() => handleUngroupFromMask(selectedObject.groupId!)} + onClick={() => handleUngroupFromMask(selectedObject.id)} + onTap={() => handleUngroupFromMask(selectedObject.id)} listening={true} /> { fill="white" align="center" verticalAlign="middle" - onClick={() => handleUngroupFromMask(selectedObject.groupId!)} - onTap={() => handleUngroupFromMask(selectedObject.groupId!)} + onClick={() => handleUngroupFromMask(selectedObject.id)} + onTap={() => handleUngroupFromMask(selectedObject.id)} listening={true} /> diff --git a/src/pages/editor/components/canvas/ObjectRenderer.tsx b/src/pages/editor/components/canvas/ObjectRenderer.tsx index 2fd004a..74d768d 100644 --- a/src/pages/editor/components/canvas/ObjectRenderer.tsx +++ b/src/pages/editor/components/canvas/ObjectRenderer.tsx @@ -319,8 +319,12 @@ const ObjectRenderer = ({ } }; + // بررسی آیا object با mask گروه شده است + const isGroupedWithMask = obj.groupId && maskShape && maskShape.groupId === obj.groupId; + const handleGroupTransformEnd = () => { if (!groupRef.current || !maskShape) return; + const node = groupRef.current; const scaleX = node.scaleX(); const scaleY = node.scaleY(); @@ -398,25 +402,6 @@ const ObjectRenderer = ({ width: newWidth, height: newHeight, }); - - // اگر mask و object در یک گروه هستند، mask را هم scale کن - if (obj.groupId && maskShape.groupId === obj.groupId) { - // محاسبه موقعیت جدید mask - // موقعیت نسبی را scale می‌کنم و به موقعیت جدید object اضافه می‌کنم - // این باعث می‌شود که موقعیت نسبی mask نسبت به object حفظ شود - const newMaskX = finalX + (relativeX * scaleX); - const newMaskY = finalY + (relativeY * scaleY); - const newMaskWidth = (maskShape.width || 100) * scaleX; - const newMaskHeight = (maskShape.height || 100) * scaleY; - - // به‌روزرسانی mask - onUpdate(maskShape.id, { - x: newMaskX, - y: newMaskY, - width: newMaskWidth, - height: newMaskHeight, - }); - } }; return ( @@ -434,7 +419,7 @@ const ObjectRenderer = ({ }} onDragEnd={handleGroupDragEnd} onDragMove={handleGroupDragMove} - onTransformEnd={handleGroupTransformEnd} + {...(!isGroupedWithMask && { onTransformEnd: handleGroupTransformEnd })} > {shapeElement}