base group

This commit is contained in:
hamid zarghami
2026-01-05 12:27:58 +03:30
parent e683b30fa1
commit 61d8e5a814
17 changed files with 607 additions and 231 deletions
@@ -6,12 +6,7 @@ import type { ShapeProps } from "./types";
const AbstractShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, draggable }: ShapeProps) => {
const shapeRef = useRef<Konva.Star>(null);
useEffect(() => {
if (isSelected && shapeRef.current && transformerRef.current) {
transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw();
}
}, [isSelected, transformerRef]);
// Transformer is managed in EditorCanvas for multi-select support
const isMask = obj.isMask || false;
const showGuide = obj.showMaskGuide !== false;
@@ -44,9 +39,9 @@ const AbstractShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, dr
dash={isMask && showGuide ? [10, 5] : undefined}
rotation={obj.rotation || 0}
draggable={draggable}
onClick={() => {
onClick={(e) => {
if (shapeRef.current) {
onSelect(obj.id, shapeRef.current);
onSelect(obj.id, shapeRef.current, e);
}
}}
onDragMove={(e) => {
@@ -6,12 +6,7 @@ import type { ShapeProps } from "./types";
const ArrowShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, draggable }: ShapeProps) => {
const shapeRef = useRef<Konva.Arrow>(null);
useEffect(() => {
if (isSelected && shapeRef.current && transformerRef.current) {
transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw();
}
}, [isSelected, transformerRef]);
// Transformer is managed in EditorCanvas for multi-select support
const startX = obj.x;
const startY = obj.y;
@@ -32,9 +27,9 @@ const ArrowShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, dragg
perfectDrawEnabled={false}
rotation={obj.rotation || 0}
draggable={draggable}
onClick={() => {
onClick={(e) => {
if (shapeRef.current) {
onSelect(obj.id, shapeRef.current);
onSelect(obj.id, shapeRef.current, e);
}
}}
onDragEnd={(e) => {
@@ -6,12 +6,7 @@ import type { ShapeProps } from "./types";
const CircleShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, draggable }: ShapeProps) => {
const shapeRef = useRef<Konva.Circle>(null);
useEffect(() => {
if (isSelected && shapeRef.current && transformerRef.current) {
transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw();
}
}, [isSelected, transformerRef]);
// Transformer is managed in EditorCanvas for multi-select support
const isMask = obj.isMask || false;
const showGuide = obj.showMaskGuide !== false;
@@ -38,9 +33,9 @@ const CircleShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, drag
dash={isMask && showGuide ? [10, 5] : undefined}
rotation={obj.rotation || 0}
draggable={draggable}
onClick={() => {
onClick={(e) => {
if (shapeRef.current) {
onSelect(obj.id, shapeRef.current);
onSelect(obj.id, shapeRef.current, e);
}
}}
onDragMove={(e) => {
@@ -15,16 +15,7 @@ const ImageObject = ({
const [image] = useImage(obj.imageUrl || "");
const shapeRef = useRef<Konva.Image>(null);
useEffect(() => {
// اگر draggable=false باشد، یعنی mask اعمال شده و transformer باید به Group متصل شود (نه Image)
// پس این useEffect را اجرا نکن
if (!draggable) return;
if (isSelected && shapeRef.current && transformerRef.current && image) {
transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw();
}
}, [isSelected, transformerRef, image, draggable]);
// Transformer is managed in EditorCanvas for multi-select support
if (!image) return null;
@@ -42,10 +33,10 @@ const ImageObject = ({
strokeWidth={isSelected && draggable ? 3 : 0}
rotation={obj.rotation || 0}
draggable={draggable}
onClick={draggable ? () => {
onClick={draggable ? (e) => {
// فقط وقتی mask اعمال نشده onClick handler را فعال کن
if (shapeRef.current) {
onSelect(obj.id, shapeRef.current);
onSelect(obj.id, shapeRef.current, e);
}
} : undefined}
onDragEnd={(e) => {
@@ -6,12 +6,7 @@ import type { ShapeProps } from "./types";
const LineShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, draggable }: ShapeProps) => {
const shapeRef = useRef<Konva.Line>(null);
useEffect(() => {
if (isSelected && shapeRef.current && transformerRef.current) {
transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw();
}
}, [isSelected, transformerRef]);
// Transformer is managed in EditorCanvas for multi-select support
const startX = obj.x;
const startY = obj.y;
@@ -30,9 +25,9 @@ const LineShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, dragga
perfectDrawEnabled={false}
rotation={obj.rotation || 0}
draggable={draggable}
onClick={() => {
onClick={(e) => {
if (shapeRef.current) {
onSelect(obj.id, shapeRef.current);
onSelect(obj.id, shapeRef.current, e);
}
}}
onDragEnd={(e) => {
@@ -23,12 +23,7 @@ const LinkShape = ({
const shapeRef = useRef<Konva.Text>(null);
const fontWeight = useMemo(() => getFontWeight(obj.fontWeight), [obj.fontWeight]);
useEffect(() => {
if (isSelected && shapeRef.current && transformerRef.current) {
transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw();
}
}, [isSelected, transformerRef]);
// Transformer is managed in EditorCanvas for multi-select support
return (
<Text
@@ -43,11 +38,11 @@ const LinkShape = ({
underline={true}
rotation={obj.rotation || 0}
draggable={draggable}
onClick={() => {
onClick={(e) => {
// در حالت editor، لینک‌ها قابل کلیک نیستند
// این قابلیت در viewer اضافه خواهد شد
if (shapeRef.current) {
onSelect(obj.id, shapeRef.current);
onSelect(obj.id, shapeRef.current, e);
}
}}
onDragEnd={(e) => {
@@ -6,12 +6,7 @@ import type { ShapeProps } from "./types";
const RectangleShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, draggable }: ShapeProps) => {
const shapeRef = useRef<Konva.Rect>(null);
useEffect(() => {
if (isSelected && shapeRef.current && transformerRef.current) {
transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw();
}
}, [isSelected, transformerRef]);
// Transformer is managed in EditorCanvas for multi-select support
const isMask = obj.isMask || false;
const showGuide = obj.showMaskGuide !== false;
@@ -39,9 +34,9 @@ const RectangleShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, d
dash={isMask && showGuide ? [10, 5] : undefined}
rotation={obj.rotation || 0}
draggable={draggable}
onClick={() => {
onClick={(e) => {
if (shapeRef.current) {
onSelect(obj.id, shapeRef.current);
onSelect(obj.id, shapeRef.current, e);
}
}}
onDragMove={(e) => {
@@ -44,25 +44,14 @@ const TextShape = ({
}: TextShapeProps) => {
const shapeRef = useRef<Konva.Text>(null);
// Transformer is managed in EditorCanvas for multi-select support
// Set offset for text node
useEffect(() => {
if (isSelected && shapeRef.current && transformerRef.current) {
const textNode = shapeRef.current;
// تنظیم offset برای حذف فضای خالی
textNode.offsetX(0);
textNode.offsetY(0);
transformerRef.current.nodes([textNode]);
// به‌روزرسانی transformer بعد از یک تیک برای محاسبه دقیق bounds
setTimeout(() => {
if (transformerRef.current && shapeRef.current) {
transformerRef.current.forceUpdate();
transformerRef.current.getLayer()?.batchDraw();
}
}, 0);
if (shapeRef.current) {
shapeRef.current.offsetX(0);
shapeRef.current.offsetY(0);
}
}, [isSelected, transformerRef, obj.text, obj.width, obj.height, obj.fontSize, obj.fontFamily, obj.fontWeight]);
}, []);
const fontFamily = useMemo(() => getFontFamily(obj.fontFamily), [obj.fontFamily]);
const fontWeight = useMemo(() => getFontWeight(obj.fontWeight), [obj.fontWeight]);
@@ -84,9 +73,9 @@ const TextShape = ({
align="right"
rotation={obj.rotation || 0}
draggable={draggable}
onClick={() => {
onClick={(e) => {
if (shapeRef.current) {
onSelect(obj.id, shapeRef.current);
onSelect(obj.id, shapeRef.current, e);
}
}}
onDragEnd={(e) => {
@@ -6,12 +6,7 @@ import type { ShapeProps } from "./types";
const TriangleShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, draggable }: ShapeProps) => {
const shapeRef = useRef<Konva.RegularPolygon>(null);
useEffect(() => {
if (isSelected && shapeRef.current && transformerRef.current) {
transformerRef.current.nodes([shapeRef.current]);
transformerRef.current.getLayer()?.batchDraw();
}
}, [isSelected, transformerRef]);
// Transformer is managed in EditorCanvas for multi-select support
const isMask = obj.isMask || false;
const showGuide = obj.showMaskGuide !== false;
@@ -40,9 +35,9 @@ const TriangleShape = ({ obj, isSelected, transformerRef, onSelect, onUpdate, dr
dash={isMask && showGuide ? [10, 5] : undefined}
rotation={obj.rotation || 0}
draggable={draggable}
onClick={() => {
onClick={(e) => {
if (shapeRef.current) {
onSelect(obj.id, shapeRef.current);
onSelect(obj.id, shapeRef.current, e);
}
}}
onDragMove={(e) => {
@@ -54,12 +54,7 @@ const VideoShape = ({
};
}, [obj.videoUrl]);
useEffect(() => {
if (isSelected && groupRef.current && transformerRef.current && image) {
transformerRef.current.nodes([groupRef.current]);
transformerRef.current.getLayer()?.batchDraw();
}
}, [isSelected, transformerRef, image]);
// Transformer is managed in EditorCanvas for multi-select support
useEffect(() => {
if (!showVideoModal) return;
@@ -101,7 +96,7 @@ const VideoShape = ({
}
}
if (groupRef.current) {
onSelect(obj.id, groupRef.current);
onSelect(obj.id, groupRef.current, e);
}
};
+1 -1
View File
@@ -5,7 +5,7 @@ export type ShapeProps = {
obj: EditorObject;
isSelected: boolean;
transformerRef: React.RefObject<Konva.Transformer | null>;
onSelect: (id: string, node: Konva.Node) => void;
onSelect: (id: string, node: Konva.Node, e?: Konva.KonvaEventObject<MouseEvent>) => void;
onUpdate: (id: string, updates: Partial<EditorObject>) => void;
draggable: boolean;
};