1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- import { ExcalidrawElement } from "./element/types";
- import { newElementWith } from "./element/mutateElement";
- import { Box, getCommonBoundingBox } from "./element/bounds";
- import { getMaximumGroups } from "./groups";
- export interface Alignment {
- position: "start" | "center" | "end";
- axis: "x" | "y";
- }
- export const alignElements = (
- selectedElements: ExcalidrawElement[],
- alignment: Alignment,
- ): ExcalidrawElement[] => {
- const groups: ExcalidrawElement[][] = getMaximumGroups(selectedElements);
- const selectionBoundingBox = getCommonBoundingBox(selectedElements);
- return groups.flatMap((group) => {
- const translation = calculateTranslation(
- group,
- selectionBoundingBox,
- alignment,
- );
- return group.map((element) =>
- newElementWith(element, {
- x: element.x + translation.x,
- y: element.y + translation.y,
- }),
- );
- });
- };
- const calculateTranslation = (
- group: ExcalidrawElement[],
- selectionBoundingBox: Box,
- { axis, position }: Alignment,
- ): { x: number; y: number } => {
- const groupBoundingBox = getCommonBoundingBox(group);
- const [min, max]: ["minX" | "minY", "maxX" | "maxY"] =
- axis === "x" ? ["minX", "maxX"] : ["minY", "maxY"];
- const noTranslation = { x: 0, y: 0 };
- if (position === "start") {
- return {
- ...noTranslation,
- [axis]: selectionBoundingBox[min] - groupBoundingBox[min],
- };
- } else if (position === "end") {
- return {
- ...noTranslation,
- [axis]: selectionBoundingBox[max] - groupBoundingBox[max],
- };
- } // else if (position === "center") {
- return {
- ...noTranslation,
- [axis]:
- (selectionBoundingBox[min] + selectionBoundingBox[max]) / 2 -
- (groupBoundingBox[min] + groupBoundingBox[max]) / 2,
- };
- };
|