fix mask in image

This commit is contained in:
hamid zarghami
2026-01-04 15:08:02 +03:30
parent 0c6bf2b52b
commit cb42dd6968
2 changed files with 69 additions and 7 deletions
+8 -3
View File
@@ -56,8 +56,11 @@ const EditorCanvas = () => {
setSelectedTableId(null); setSelectedTableId(null);
} }
setSelectedCellId(null); setSelectedCellId(null);
if (transformerRef.current) { if (transformerRef.current && layerRef.current) {
transformerRef.current.nodes([node]); // اگر object با mask گروه شده، transformer را به Group متصل کن
const maskedGroup = layerRef.current.findOne(`#masked-${id}`);
const targetNode = maskedGroup || node;
transformerRef.current.nodes([targetNode]);
transformerRef.current.getLayer()?.batchDraw(); transformerRef.current.getLayer()?.batchDraw();
} }
}; };
@@ -146,7 +149,9 @@ const EditorCanvas = () => {
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
if (!layerRef.current || !transformerRef.current) return; if (!layerRef.current || !transformerRef.current) return;
const node = layerRef.current.findOne(`#${selectedObjectId}`); // اگر object با mask گروه شده، transformer را به Group متصل کن
const maskedGroup = layerRef.current.findOne(`#masked-${selectedObjectId}`);
const node = maskedGroup || layerRef.current.findOne(`#${selectedObjectId}`);
if (node && transformerRef.current) { if (node && transformerRef.current) {
transformerRef.current.nodes([node]); transformerRef.current.nodes([node]);
@@ -75,13 +75,19 @@ const ObjectRenderer = ({
return null; return null;
} }
// برای objectهای با mask، یک obj جدید با موقعیت (0, 0) ایجاد کن
const shapeObj = shouldApplyMask
? { ...obj, x: 0, y: 0 }
: obj;
const commonProps = { const commonProps = {
obj, obj: shapeObj,
isSelected, isSelected,
transformerRef, transformerRef,
onSelect, onSelect,
onUpdate, onUpdate,
draggable, // اگر mask اعمال شده، shape را غیر draggable کن (Group drag می‌شود)
draggable: shouldApplyMask ? false : draggable,
}; };
const renderMaskShape = (mask: EditorObject) => { const renderMaskShape = (mask: EditorObject) => {
@@ -93,8 +99,9 @@ const ObjectRenderer = ({
// موقعیت mask نسبت به object - برای overlap صحیح // موقعیت mask نسبت به object - برای overlap صحیح
// mask در موقعیت مطلق است، پس باید آن را relative به object کنیم // mask در موقعیت مطلق است، پس باید آن را relative به object کنیم
const relativeX = (mask.x || 0); // چون shape در موقعیت (0, 0) است، باید موقعیت mask را نسبت به shape محاسبه کنم
const relativeY = (mask.y || 0); const relativeX = (mask.x || 0) - (obj.x || 0);
const relativeY = (mask.y || 0) - (obj.y || 0);
if (mask.type === "rectangle" && mask.shapeType === "circle") { if (mask.type === "rectangle" && mask.shapeType === "circle") {
return ( return (
@@ -223,11 +230,61 @@ const ObjectRenderer = ({
// Default: destination-out (overlap مخفی می‌شود) // Default: destination-out (overlap مخفی می‌شود)
const compositeOp = obj.maskInvert === false ? "destination-in" : "destination-out"; const compositeOp = obj.maskInvert === false ? "destination-in" : "destination-out";
const handleGroupDragEnd = (e: Konva.KonvaEventObject<DragEvent>) => {
const node = e.target;
onUpdate(obj.id, {
x: node.x(),
y: node.y(),
});
};
const handleGroupDragMove = (e: Konva.KonvaEventObject<DragEvent>) => {
const node = e.target;
onUpdate(obj.id, {
x: node.x(),
y: node.y(),
});
// به‌روزرسانی transformer در حین drag
if (transformerRef.current && isSelected) {
transformerRef.current.nodes([node]);
transformerRef.current.getLayer()?.batchDraw();
}
};
const handleGroupTransformEnd = () => {
if (!groupRef.current) return;
const node = groupRef.current;
const scaleX = node.scaleX();
const scaleY = node.scaleY();
node.scaleX(1);
node.scaleY(1);
onUpdate(obj.id, {
x: node.x(),
y: node.y(),
rotation: node.rotation(),
width: Math.max(5, (obj.width || 100) * scaleX),
height: Math.max(5, (obj.height || 100) * scaleY),
});
};
return ( return (
<Group <Group
ref={groupRef} ref={groupRef}
id={`masked-${obj.id}`} id={`masked-${obj.id}`}
name="masked-group" name="masked-group"
x={obj.x}
y={obj.y}
draggable={draggable}
onClick={() => {
if (groupRef.current) {
onSelect(obj.id, groupRef.current);
}
}}
onDragEnd={handleGroupDragEnd}
onDragMove={handleGroupDragMove}
onTransformEnd={handleGroupTransformEnd}
> >
{shapeElement} {shapeElement}
<Group globalCompositeOperation={compositeOp} listening={false}> <Group globalCompositeOperation={compositeOp} listening={false}>