mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Moved selection in element, refactor common
This commit is contained in:
parent
e7a0a7e0b7
commit
dfd48c221c
19 changed files with 67 additions and 110 deletions
|
@ -4,6 +4,8 @@ import {
|
|||
type LocalPoint,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import type { NullableGridSize } from "@excalidraw/excalidraw/types";
|
||||
|
||||
export const getSizeFromPoints = (
|
||||
points: readonly (GlobalPoint | LocalPoint)[],
|
||||
) => {
|
||||
|
@ -61,3 +63,18 @@ export const rescalePoints = <Point extends GlobalPoint | LocalPoint>(
|
|||
|
||||
return nextPoints;
|
||||
};
|
||||
|
||||
// TODO: Rounding this point causes some shake when free drawing
|
||||
export const getGridPoint = (
|
||||
x: number,
|
||||
y: number,
|
||||
gridSize: NullableGridSize,
|
||||
): [number, number] => {
|
||||
if (gridSize) {
|
||||
return [
|
||||
Math.round(x / gridSize) * gridSize,
|
||||
Math.round(y / gridSize) * gridSize,
|
||||
];
|
||||
}
|
||||
return [x, y];
|
||||
};
|
||||
|
|
|
@ -1206,59 +1206,3 @@ export const escapeDoubleQuotes = (str: string) => {
|
|||
|
||||
export const castArray = <T>(value: T | T[]): T[] =>
|
||||
Array.isArray(value) ? value : [value];
|
||||
|
||||
// TODO_SEP: perhaps could be refactored away
|
||||
|
||||
// TODO: Rounding this point causes some shake when free drawing
|
||||
export const getGridPoint = (
|
||||
x: number,
|
||||
y: number,
|
||||
gridSize: NullableGridSize,
|
||||
): [number, number] => {
|
||||
if (gridSize) {
|
||||
return [
|
||||
Math.round(x / gridSize) * gridSize,
|
||||
Math.round(y / gridSize) * gridSize,
|
||||
];
|
||||
}
|
||||
return [x, y];
|
||||
};
|
||||
|
||||
export const elementsAreInSameGroup = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
) => {
|
||||
const allGroups = elements.flatMap((element) => element.groupIds);
|
||||
const groupCount = new Map<string, number>();
|
||||
let maxGroup = 0;
|
||||
|
||||
for (const group of allGroups) {
|
||||
groupCount.set(group, (groupCount.get(group) ?? 0) + 1);
|
||||
if (groupCount.get(group)! > maxGroup) {
|
||||
maxGroup = groupCount.get(group)!;
|
||||
}
|
||||
}
|
||||
|
||||
return maxGroup === elements.length;
|
||||
};
|
||||
|
||||
export const isInGroup = (element: NonDeletedExcalidrawElement) => {
|
||||
return element.groupIds.length > 0;
|
||||
};
|
||||
|
||||
export const getNewGroupIdsForDuplication = (
|
||||
groupIds: ExcalidrawElement["groupIds"],
|
||||
editingGroupId: AppState["editingGroupId"],
|
||||
mapper: (groupId: GroupId) => GroupId,
|
||||
) => {
|
||||
const copy = [...groupIds];
|
||||
const positionOfEditingGroupId = editingGroupId
|
||||
? groupIds.indexOf(editingGroupId)
|
||||
: -1;
|
||||
const endIndex =
|
||||
positionOfEditingGroupId > -1 ? positionOfEditingGroupId : groupIds.length;
|
||||
for (let index = 0; index < endIndex; index++) {
|
||||
copy[index] = mapper(copy[index]);
|
||||
}
|
||||
|
||||
return copy;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,9 @@ import type {
|
|||
OrderedExcalidrawElement,
|
||||
} from "@excalidraw/element/types";
|
||||
|
||||
import { InvalidFractionalIndexError } from "../../excalidraw/errors";
|
||||
export class InvalidFractionalIndexError extends Error {
|
||||
public code = "ELEMENT_HAS_INVALID_INDEX" as const;
|
||||
}
|
||||
|
||||
/**
|
||||
* Envisioned relation between array order and fractional indices:
|
||||
|
|
|
@ -5,11 +5,6 @@ import {
|
|||
elementsOverlappingBBox,
|
||||
} from "@excalidraw/utils";
|
||||
|
||||
import {
|
||||
getElementsWithinSelection,
|
||||
getSelectedElements,
|
||||
} from "@excalidraw/excalidraw/scene";
|
||||
|
||||
import { getElementAbsoluteCoords, isTextElement } from "@excalidraw/element";
|
||||
|
||||
import type {
|
||||
|
@ -31,6 +26,7 @@ import type {
|
|||
|
||||
import type { ReadonlySetLike } from "@excalidraw/common/utility-types";
|
||||
|
||||
import { getElementsWithinSelection, getSelectedElements } from "./selection";
|
||||
import { getElementsInGroup, selectGroupsFromGivenElements } from "./groups";
|
||||
|
||||
import { getElementLineSegments, getCommonBounds } from "./bounds";
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import { getBoundTextElement } from "@excalidraw/element/textElement";
|
||||
|
||||
import { getSelectedElements } from "@excalidraw/excalidraw/scene";
|
||||
import { makeNextSelectedElementIds } from "@excalidraw/excalidraw/scene/selection";
|
||||
|
||||
import type {
|
||||
GroupId,
|
||||
ExcalidrawElement,
|
||||
|
@ -19,6 +16,8 @@ import type {
|
|||
} from "@excalidraw/excalidraw/types";
|
||||
import type { Mutable } from "@excalidraw/common/utility-types";
|
||||
|
||||
import { makeNextSelectedElementIds, getSelectedElements } from "./selection";
|
||||
|
||||
export const selectGroup = (
|
||||
groupId: GroupId,
|
||||
appState: InteractiveCanvasAppState,
|
||||
|
|
|
@ -11,7 +11,6 @@ import {
|
|||
import {
|
||||
MIN_FONT_SIZE,
|
||||
SHIFT_LOCKING_ANGLE,
|
||||
isInGroup,
|
||||
rescalePoints,
|
||||
getFontString,
|
||||
} from "@excalidraw/common";
|
||||
|
@ -59,6 +58,8 @@ import {
|
|||
isTextElement,
|
||||
} from "./typeChecks";
|
||||
|
||||
import { isInGroup } from "./groups";
|
||||
|
||||
import type { BoundingBox } from "./bounds";
|
||||
import type {
|
||||
MaybeTransformHandleType,
|
||||
|
|
|
@ -1,17 +1,3 @@
|
|||
import {
|
||||
getElementAbsoluteCoords,
|
||||
getElementBounds,
|
||||
} from "@excalidraw/element/bounds";
|
||||
import { isElementInViewport } from "@excalidraw/element/sizeHelpers";
|
||||
import {
|
||||
isBoundToContainer,
|
||||
isFrameLikeElement,
|
||||
} from "@excalidraw/element/typeChecks";
|
||||
import {
|
||||
elementOverlapsWithFrame,
|
||||
getContainingFrame,
|
||||
getFrameChildren,
|
||||
} from "@excalidraw/element/frame";
|
||||
import { isShallowEqual } from "@excalidraw/common";
|
||||
|
||||
import type {
|
||||
|
@ -21,7 +7,19 @@ import type {
|
|||
NonDeletedExcalidrawElement,
|
||||
} from "@excalidraw/element/types";
|
||||
|
||||
import type { AppState, InteractiveCanvasAppState } from "../types";
|
||||
import type {
|
||||
AppState,
|
||||
InteractiveCanvasAppState,
|
||||
} from "@excalidraw/excalidraw/types";
|
||||
|
||||
import { getElementAbsoluteCoords, getElementBounds } from "./bounds";
|
||||
import { isElementInViewport } from "./sizeHelpers";
|
||||
import { isBoundToContainer, isFrameLikeElement } from "./typeChecks";
|
||||
import {
|
||||
elementOverlapsWithFrame,
|
||||
getContainingFrame,
|
||||
getFrameChildren,
|
||||
} from "./frame";
|
||||
|
||||
/**
|
||||
* Frames and their containing elements are not to be selected at the same time.
|
|
@ -1,7 +1,7 @@
|
|||
import { getSelectedElements } from "@excalidraw/excalidraw/scene";
|
||||
|
||||
import type { UIAppState } from "@excalidraw/excalidraw/types";
|
||||
|
||||
import { getSelectedElements } from "./selection";
|
||||
|
||||
import type { NonDeletedExcalidrawElement } from "./types";
|
||||
|
||||
export const showSelectedShapeActions = (
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { makeNextSelectedElementIds } from "./selection";
|
||||
import { makeNextSelectedElementIds } from "../src/selection";
|
||||
|
||||
describe("makeNextSelectedElementIds", () => {
|
||||
const _makeNextSelectedElementIds = (
|
|
@ -39,6 +39,11 @@ import {
|
|||
getElementsInGroup,
|
||||
} from "@excalidraw/element/groups";
|
||||
|
||||
import {
|
||||
excludeElementsInFramesFromSelection,
|
||||
getSelectedElements,
|
||||
} from "@excalidraw/element/selection";
|
||||
|
||||
import type { ExcalidrawElement } from "@excalidraw/element/types";
|
||||
|
||||
import { ToolButton } from "../components/ToolButton";
|
||||
|
@ -46,10 +51,6 @@ import { DuplicateIcon } from "../components/icons";
|
|||
|
||||
import { t } from "../i18n";
|
||||
import { isSomeElementSelected } from "../scene";
|
||||
import {
|
||||
excludeElementsInFramesFromSelection,
|
||||
getSelectedElements,
|
||||
} from "../scene/selection";
|
||||
import { CaptureUpdateAction } from "../store";
|
||||
|
||||
import { register } from "./register";
|
||||
|
|
|
@ -289,6 +289,11 @@ import {
|
|||
syncMovedIndices,
|
||||
} from "@excalidraw/element/fractionalIndex";
|
||||
|
||||
import {
|
||||
excludeElementsInFramesFromSelection,
|
||||
makeNextSelectedElementIds,
|
||||
} from "@excalidraw/element/selection";
|
||||
|
||||
import type { LocalPoint, Radians } from "@excalidraw/math";
|
||||
|
||||
import type {
|
||||
|
@ -420,10 +425,6 @@ import {
|
|||
|
||||
import { Fonts } from "../fonts";
|
||||
import { getLineHeight } from "../fonts/FontMetadata";
|
||||
import {
|
||||
excludeElementsInFramesFromSelection,
|
||||
makeNextSelectedElementIds,
|
||||
} from "../scene/selection";
|
||||
import { editorJotaiStore } from "../editor-jotai";
|
||||
import { ImageSceneDataError } from "../errors";
|
||||
import {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { isInGroup } from "@excalidraw/common";
|
||||
|
||||
import { degreesToRadians, radiansToDegrees } from "@excalidraw/math";
|
||||
|
||||
import { mutateElement } from "@excalidraw/element/mutateElement";
|
||||
|
@ -7,6 +5,8 @@ import { mutateElement } from "@excalidraw/element/mutateElement";
|
|||
import { getBoundTextElement } from "@excalidraw/element/textElement";
|
||||
import { isArrowElement } from "@excalidraw/element/typeChecks";
|
||||
|
||||
import { isInGroup } from "@excalidraw/element/groups";
|
||||
|
||||
import type { Degrees } from "@excalidraw/math";
|
||||
|
||||
import type { ExcalidrawElement } from "@excalidraw/element/types";
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { isInGroup } from "@excalidraw/common";
|
||||
|
||||
import { isTextElement, redrawTextBoundingBox } from "@excalidraw/element";
|
||||
import { mutateElement } from "@excalidraw/element/mutateElement";
|
||||
import { getBoundTextElement } from "@excalidraw/element/textElement";
|
||||
import { hasBoundTextElement } from "@excalidraw/element/typeChecks";
|
||||
|
||||
import { isInGroup } from "@excalidraw/element/groups";
|
||||
|
||||
import type {
|
||||
ExcalidrawElement,
|
||||
ExcalidrawTextElement,
|
||||
|
|
|
@ -5,7 +5,9 @@ import { vi } from "vitest";
|
|||
|
||||
import { getCommonBounds, isTextElement } from "@excalidraw/element";
|
||||
|
||||
import { setDateTimeForTests, isInGroup, reseed } from "@excalidraw/common";
|
||||
import { setDateTimeForTests, reseed } from "@excalidraw/common";
|
||||
|
||||
import { isInGroup } from "@excalidraw/element/groups";
|
||||
|
||||
import type { Degrees } from "@excalidraw/math";
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { isInGroup } from "@excalidraw/common";
|
||||
import { pointFrom, pointRotateRads } from "@excalidraw/math";
|
||||
|
||||
import {
|
||||
|
@ -16,6 +15,7 @@ import {
|
|||
import {
|
||||
getSelectedGroupIds,
|
||||
getElementsInGroup,
|
||||
isInGroup,
|
||||
} from "@excalidraw/element/groups";
|
||||
|
||||
import type { Radians } from "@excalidraw/math";
|
||||
|
|
|
@ -33,10 +33,6 @@ export class ImageSceneDataError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
export class InvalidFractionalIndexError extends Error {
|
||||
public code = "ELEMENT_HAS_INVALID_INDEX" as const;
|
||||
}
|
||||
|
||||
type WorkerErrorCodes = "WORKER_URL_NOT_DEFINED" | "WORKER_IN_THE_MAIN_CHUNK";
|
||||
|
||||
export class WorkerUrlNotDefinedError extends Error {
|
||||
|
|
|
@ -17,6 +17,8 @@ import {
|
|||
validateFractionalIndices,
|
||||
} from "@excalidraw/element/fractionalIndex";
|
||||
|
||||
import { getSelectedElements } from "@excalidraw/element/selection";
|
||||
|
||||
import type { LinearElementEditor } from "@excalidraw/element/linearElementEditor";
|
||||
import type {
|
||||
ExcalidrawElement,
|
||||
|
@ -32,8 +34,6 @@ import type {
|
|||
|
||||
import type { Assert, SameType } from "@excalidraw/common/utility-types";
|
||||
|
||||
import { getSelectedElements } from "./selection";
|
||||
|
||||
import type { AppState } from "../types";
|
||||
|
||||
type ElementIdKey = InstanceType<typeof LinearElementEditor>["elementId"];
|
||||
|
|
|
@ -4,7 +4,7 @@ export {
|
|||
getCommonAttributeOfSelectedElements,
|
||||
getSelectedElements,
|
||||
getTargetElements,
|
||||
} from "./selection";
|
||||
} from "@excalidraw/element/selection";
|
||||
export { calculateScrollCenter } from "./scroll";
|
||||
export {
|
||||
hasBackground,
|
||||
|
|
|
@ -20,6 +20,11 @@ import {
|
|||
|
||||
import { getMaximumGroups } from "@excalidraw/element/groups";
|
||||
|
||||
import {
|
||||
getSelectedElements,
|
||||
getVisibleAndNonSelectedElements,
|
||||
} from "@excalidraw/element/selection";
|
||||
|
||||
import type { InclusiveRange } from "@excalidraw/math";
|
||||
|
||||
import type { Bounds } from "@excalidraw/element/bounds";
|
||||
|
@ -30,11 +35,6 @@ import type {
|
|||
NonDeletedExcalidrawElement,
|
||||
} from "@excalidraw/element/types";
|
||||
|
||||
import {
|
||||
getSelectedElements,
|
||||
getVisibleAndNonSelectedElements,
|
||||
} from "./scene/selection";
|
||||
|
||||
import type {
|
||||
AppClassProperties,
|
||||
AppState,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue