alignment setting
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
|
||||
import {
|
||||
AlignBottom,
|
||||
AlignHorizontally,
|
||||
AlignLeft,
|
||||
AlignRight,
|
||||
AlignTop,
|
||||
AlignVertically,
|
||||
} from "iconsax-react";
|
||||
import { useEditorStore, type EditorObject } from "../../../store/editorStore";
|
||||
import type { AlignKind } from "./alignmentUtils";
|
||||
import {
|
||||
deltasForAlign,
|
||||
pageBounds,
|
||||
unionBoundsOfAlignTargets,
|
||||
computeGroupFrameUpdate,
|
||||
updatesFromDeltas,
|
||||
} from "./alignmentUtils";
|
||||
|
||||
type AlignmentSettingsProps = {
|
||||
pageWidth: number;
|
||||
pageHeight: number;
|
||||
onUpdate: (id: string, updates: Partial<EditorObject>) => void;
|
||||
};
|
||||
|
||||
|
||||
|
||||
const alignIconProps = { size: 24, color: "currentColor" as const, variant: "Linear" as const };
|
||||
|
||||
const AlignmentSettings = ({
|
||||
pageWidth,
|
||||
pageHeight,
|
||||
onUpdate,
|
||||
}: AlignmentSettingsProps) => {
|
||||
// const selectedObjectIds = useEditorStore((s) => s.selectedObjectIds);
|
||||
|
||||
/** دقیقاً دو شیٔ مجزا (هنوز یک گروه نشدهاند) → مرز همان دو شی؛ یک شی یا گروه یا بیش از دو تا → صفحه */
|
||||
// const alignToSelection = selectedObjectIds.length === 2;
|
||||
|
||||
const applyAlign = (kind: AlignKind) => {
|
||||
const { objects: objs, selectedObjectIds: ids, layerRef } = useEditorStore.getState();
|
||||
const layer = layerRef?.current ?? null;
|
||||
|
||||
const initial = new Map<string, EditorObject>();
|
||||
for (const id of ids) {
|
||||
const o = objs.find((x) => x.id === id);
|
||||
if (o && o.visible !== false) initial.set(id, { ...o });
|
||||
}
|
||||
if (initial.size === 0) return;
|
||||
|
||||
const initialList = [...initial.values()];
|
||||
const useSelectionBounds = ids.length === 2;
|
||||
const target =
|
||||
useSelectionBounds && initialList.length === 2
|
||||
? unionBoundsOfAlignTargets(initialList, objs, layer)
|
||||
: pageBounds(pageWidth, pageHeight);
|
||||
|
||||
if (!target) return;
|
||||
|
||||
const alignedGroupIds = new Set<string>();
|
||||
|
||||
for (const id of initial.keys()) {
|
||||
const obj = initial.get(id)!;
|
||||
const { dx, dy } = deltasForAlign(obj, kind, target, objs, layer);
|
||||
const updates = updatesFromDeltas(obj, dx, dy);
|
||||
if (Object.keys(updates).length === 0) continue;
|
||||
onUpdate(id, updates);
|
||||
if (obj.type === "group") {
|
||||
alignedGroupIds.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
const { updateObject } = useEditorStore.getState();
|
||||
const afterObjects = useEditorStore.getState().objects;
|
||||
for (const gid of alignedGroupIds) {
|
||||
const patch = computeGroupFrameUpdate(gid, afterObjects, layer);
|
||||
if (patch) updateObject(gid, patch);
|
||||
}
|
||||
};
|
||||
|
||||
// const hint = alignToSelection ? "نسبت به دو شی انتخابشده" : "نسبت به صفحه";
|
||||
|
||||
return (
|
||||
<div className="space-y-3 border-t border-border pt-4">
|
||||
<div>
|
||||
<h4 className="text-sm font-bold text-foreground">ابزار جابهجایی</h4>
|
||||
{/* <p className="mt-1 text-xs text-muted-foreground">{hint}</p> */}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<p className="text-xs font-medium text-muted-foreground">افقی</p>
|
||||
<div className="flex gap-12 items-center mt-4">
|
||||
<AlignRight onClick={() => applyAlign("right")} {...alignIconProps} />
|
||||
<AlignHorizontally onClick={() => applyAlign("centerH")} {...alignIconProps} />
|
||||
<AlignLeft onClick={() => applyAlign("left")} {...alignIconProps} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<p className="text-xs font-medium text-muted-foreground mt-4">عمودی</p>
|
||||
<div className="flex gap-12 items-center mt-4">
|
||||
|
||||
<AlignTop onClick={() => applyAlign("top")} {...alignIconProps} />
|
||||
|
||||
<AlignVertically onClick={() => applyAlign("centerV")} {...alignIconProps} />
|
||||
|
||||
<AlignBottom onClick={() => applyAlign("bottom")} {...alignIconProps} />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AlignmentSettings;
|
||||
Reference in New Issue
Block a user