base mask

This commit is contained in:
hamid zarghami
2026-01-04 10:18:49 +03:30
parent b33b7a953d
commit aa6153d289
16 changed files with 435 additions and 52 deletions
@@ -8,6 +8,7 @@ import {
VideoSettings,
TransformSettings,
GridSettings,
MaskSettings,
} from "./settings";
import TextInstruction from "./instructions/TextInstruction";
@@ -33,7 +34,10 @@ const ObjectSettings = ({ selectedObject, onUpdate, onDelete }: ObjectSettingsPr
{selectedObject.type === "text" && <TextInstruction />}
{selectedObject.type === "rectangle" && (
<ShapeSettings selectedObject={selectedObject} onUpdate={onUpdate} />
<>
<MaskSettings objectId={selectedObject.id} />
<ShapeSettings selectedObject={selectedObject} onUpdate={onUpdate} />
</>
)}
{(selectedObject.type === "line" || selectedObject.type === "arrow") && (
@@ -15,7 +15,7 @@ const shapeOptions: Array<{ id: ShapeType; label: string; icon: string; alt: str
];
const RectangleInstruction: FC = () => {
const { activeShape, setActiveShape } = useShapeStore();
const { activeShape, setActiveShape, useAsMask, setUseAsMask } = useShapeStore();
return (
<div>
@@ -44,7 +44,7 @@ const RectangleInstruction: FC = () => {
<div className="mt-9 flex items-center justify-between">
<div className="text-[13px]">استفاده برای ماسک</div>
<Switch />
<Switch checked={useAsMask} onCheckedChange={setUseAsMask} />
</div>
</div>
);
@@ -0,0 +1,77 @@
import { Switch } from "@/components/ui/switch";
import { useEditorStore } from "@/pages/editor/store/editorStore";
type MaskSettingsProps = {
objectId: string;
};
/**
* MaskSettings - تنظیمات mask mode برای shapes
*
* این component اجازه می‌ده کاربر یک shape رو به mask تبدیل کنه
* فقط برای shapes قابل استفاده است (rectangle, circle, triangle, abstract)
*/
const MaskSettings = ({ objectId }: MaskSettingsProps) => {
const { objects, updateObject, selectedObjectId, setSelectedObjectId } = useEditorStore();
const object = objects.find((obj) => obj.id === objectId);
if (!object) return null;
const canBeMask = object.type === "rectangle";
if (!canBeMask) return null;
const isMask = object.isMask || false;
const currentShowGuide = object.showMaskGuide !== false;
const handleToggleMask = (checked: boolean) => {
updateObject(objectId, { isMask: checked, showMaskGuide: checked ? true : undefined });
if (checked && selectedObjectId === objectId) {
setSelectedObjectId(null);
}
};
const handleToggleGuide = (checked: boolean) => {
updateObject(objectId, { showMaskGuide: checked });
};
return (
<div className="p-4 border-b">
<div className="flex items-center justify-between mb-3">
<div className="flex flex-col gap-1">
<span className="text-sm font-medium">استفاده به عنوان ماسک</span>
<span className="text-xs text-gray-500">
ناحیهای که با ماسک همپوشانی دارد مخفی میشود
</span>
</div>
<Switch
checked={isMask}
onCheckedChange={handleToggleMask}
/>
</div>
{isMask && (
<>
<div className="flex items-center justify-between mb-3">
<span className="text-sm">نمایش راهنمای ماسک</span>
<Switch
checked={currentShowGuide}
onCheckedChange={handleToggleGuide}
/>
</div>
<div className="p-2 bg-blue-50 rounded-md">
<p className="text-xs text-blue-700">
💡 قسمتهای همپوشانی با این ماسک مخفی میشوند.
</p>
</div>
</>
)}
</div>
);
};
export default MaskSettings;
@@ -6,4 +6,5 @@ export { default as LinkSettings } from "./LinkSettings";
export { default as VideoSettings } from "./VideoSettings";
export { default as TransformSettings } from "./TransformSettings";
export { default as GridSettings } from "./GridSettings";
export { default as MaskSettings } from "./MaskSettings";