fix mask in image
This commit is contained in:
@@ -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}>
|
||||||
|
|||||||
Reference in New Issue
Block a user