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