fix group mask image

This commit is contained in:
hamid zarghami
2026-01-04 15:25:21 +03:30
parent 19258395a0
commit bbf7167993
3 changed files with 45 additions and 18 deletions
@@ -53,23 +53,44 @@ const ObjectRenderer = ({
useEffect(() => { useEffect(() => {
if (!groupRef.current || !shouldApplyMask) return; if (!groupRef.current || !shouldApplyMask) return;
// Use requestAnimationFrame to ensure shapes are rendered before caching // Use double requestAnimationFrame to ensure all changes (including stroke) are rendered before caching
const rafId = requestAnimationFrame(() => { let rafId1: number;
if (!groupRef.current) return; const rafId2 = requestAnimationFrame(() => {
rafId1 = requestAnimationFrame(() => {
if (!groupRef.current) return;
// Clear cache first // Clear cache first
groupRef.current.clearCache(); groupRef.current.clearCache();
// Apply cache - Konva will automatically calculate bounds // Apply cache - Konva will automatically calculate bounds
groupRef.current.cache(); groupRef.current.cache();
groupRef.current.getLayer()?.batchDraw(); groupRef.current.getLayer()?.batchDraw();
});
}); });
return () => { return () => {
cancelAnimationFrame(rafId); cancelAnimationFrame(rafId2);
if (rafId1) cancelAnimationFrame(rafId1);
groupRef.current?.clearCache(); groupRef.current?.clearCache();
}; };
}, [shouldApplyMask, maskShape?.x, maskShape?.y, maskShape?.width, maskShape?.height, maskShape?.rotation, obj.x, obj.y, obj.width, obj.height, obj.rotation]); }, [shouldApplyMask, isSelected, maskShape?.x, maskShape?.y, maskShape?.width, maskShape?.height, maskShape?.rotation, obj.x, obj.y, obj.width, obj.height, obj.rotation, obj.maskInvert]);
// Refresh cache after transformer is attached (when isSelected changes)
useEffect(() => {
if (!groupRef.current || !shouldApplyMask || !isSelected) return;
// Wait for transformer to attach, then refresh cache
const timeoutId = setTimeout(() => {
if (!groupRef.current) return;
groupRef.current.clearCache();
groupRef.current.cache();
groupRef.current.getLayer()?.batchDraw();
}, 150);
return () => {
clearTimeout(timeoutId);
};
}, [shouldApplyMask, isSelected, transformerRef]);
if (obj.visible === false) { if (obj.visible === false) {
return null; return null;
@@ -56,7 +56,7 @@ const MaskSettings = ({ objectId }: MaskSettingsProps) => {
return ( return (
<div className={clx( <div className={clx(
"p-4 border-b space-y-4", "p-4 border-b space-y-4",
!canBeMask && "hidden" !canBeMask && "border-b-0 p-0"
)}> )}>
{/* Section 1: Convert shape to mask (only for shapes) */} {/* Section 1: Convert shape to mask (only for shapes) */}
{canBeMask && ( {canBeMask && (
@@ -16,11 +16,15 @@ const ImageObject = ({
const shapeRef = useRef<Konva.Image>(null); const shapeRef = useRef<Konva.Image>(null);
useEffect(() => { useEffect(() => {
// اگر draggable=false باشد، یعنی mask اعمال شده و transformer باید به Group متصل شود (نه Image)
// پس این useEffect را اجرا نکن
if (!draggable) return;
if (isSelected && shapeRef.current && transformerRef.current && image) { if (isSelected && shapeRef.current && transformerRef.current && image) {
transformerRef.current.nodes([shapeRef.current]); transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw(); transformerRef.current.getLayer()?.batchDraw();
} }
}, [isSelected, transformerRef, image]); }, [isSelected, transformerRef, image, draggable]);
if (!image) return null; if (!image) return null;
@@ -33,15 +37,17 @@ const ImageObject = ({
image={image} image={image}
width={obj.width || image.width} width={obj.width || image.width}
height={obj.height || image.height} height={obj.height || image.height}
stroke={isSelected ? "#3b82f6" : undefined} // اگر draggable=false باشد، یعنی mask اعمال شده و نباید stroke نمایش داده شود (Group stroke دارد)
strokeWidth={isSelected ? 3 : 0} stroke={isSelected && draggable ? "#3b82f6" : undefined}
strokeWidth={isSelected && draggable ? 3 : 0}
rotation={obj.rotation || 0} rotation={obj.rotation || 0}
draggable={draggable} draggable={draggable}
onClick={() => { onClick={draggable ? () => {
// فقط وقتی mask اعمال نشده onClick handler را فعال کن
if (shapeRef.current) { if (shapeRef.current) {
onSelect(obj.id, shapeRef.current); onSelect(obj.id, shapeRef.current);
} }
}} } : undefined}
onDragEnd={(e) => { onDragEnd={(e) => {
const node = e.target; const node = e.target;
onUpdate(obj.id, { onUpdate(obj.id, {