You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
success/packages/excalidraw/actions/actionFlip.ts

103 lines
2.8 KiB
TypeScript

import { register } from "./register";
import { getSelectedElements } from "../scene";
import { getNonDeletedElements } from "../element";
import { ExcalidrawElement, NonDeleted } from "../element/types";
feat: add flipping for multiple elements (#5578) * feat: add flipping when resizing multiple elements * fix: image elements not flipping its content * test: fix accidental resizing in grouping test * fix: angles not flipping vertically when resizing * feat: add flipping multiple elements with a command * revert: image elements not flipping its content This reverts commit cb989a6c66e62a02a8c04ce41f12507806c8d0a0. * fix: add special cases for flipping text & images * fix: a few corner cases for flipping * fix: remove angle flip * fix: bound text scaling when resizing * fix: linear elements drifting away after multiple flips * revert: fix linear elements drifting away after multiple flips This reverts commit bffc33dd3ffe56c72029eee6aca843d992bac7ab. * fix: linear elements unstable bounds * revert: linear elements unstable bounds This reverts commit 22ae9b02c4a49f0ed6448c27abe1969cf6abb1e3. * fix: hand-drawn lines shift after flipping * test: fix flipping tests * test: fix the number of context menu items * fix: incorrect scaling due to ignoring bound text when finding selection bounds * fix: bound text coordinates not being updated * fix: lines bound text rotation * fix: incorrect placement of bound lines on flip * remove redundant predicates in actionFlip * update test * refactor resizeElement with some renaming and comments * fix grouped bounded text elements not being flipped correctly * combine mutation for bounded text element * remove incorrect return * fix: linear elements bindings after flipping * revert: remove incorrect return This reverts commit e6b205ca900b504fe982e4ac1b3b19dcfca246b8. * fix: minimum size for all elements in selection --------- Co-authored-by: Ryan Di <ryan.weihao.di@gmail.com>
2 years ago
import { resizeMultipleElements } from "../element/resizeElements";
import { AppState, PointerDownState } from "../types";
import { arrayToMap } from "../utils";
import { CODES, KEYS } from "../keys";
feat: add flipping for multiple elements (#5578) * feat: add flipping when resizing multiple elements * fix: image elements not flipping its content * test: fix accidental resizing in grouping test * fix: angles not flipping vertically when resizing * feat: add flipping multiple elements with a command * revert: image elements not flipping its content This reverts commit cb989a6c66e62a02a8c04ce41f12507806c8d0a0. * fix: add special cases for flipping text & images * fix: a few corner cases for flipping * fix: remove angle flip * fix: bound text scaling when resizing * fix: linear elements drifting away after multiple flips * revert: fix linear elements drifting away after multiple flips This reverts commit bffc33dd3ffe56c72029eee6aca843d992bac7ab. * fix: linear elements unstable bounds * revert: linear elements unstable bounds This reverts commit 22ae9b02c4a49f0ed6448c27abe1969cf6abb1e3. * fix: hand-drawn lines shift after flipping * test: fix flipping tests * test: fix the number of context menu items * fix: incorrect scaling due to ignoring bound text when finding selection bounds * fix: bound text coordinates not being updated * fix: lines bound text rotation * fix: incorrect placement of bound lines on flip * remove redundant predicates in actionFlip * update test * refactor resizeElement with some renaming and comments * fix grouped bounded text elements not being flipped correctly * combine mutation for bounded text element * remove incorrect return * fix: linear elements bindings after flipping * revert: remove incorrect return This reverts commit e6b205ca900b504fe982e4ac1b3b19dcfca246b8. * fix: minimum size for all elements in selection --------- Co-authored-by: Ryan Di <ryan.weihao.di@gmail.com>
2 years ago
import { getCommonBoundingBox } from "../element/bounds";
import {
bindOrUnbindSelectedElements,
isBindingEnabled,
unbindLinearElements,
} from "../element/binding";
import { updateFrameMembershipOfSelectedElements } from "../frame";
export const actionFlipHorizontal = register({
name: "flipHorizontal",
trackEvent: { category: "element" },
perform: (elements, appState, _, app) => {
return {
elements: updateFrameMembershipOfSelectedElements(
flipSelectedElements(elements, appState, "horizontal"),
appState,
app,
),
appState,
commitToHistory: true,
};
},
keyTest: (event) => event.shiftKey && event.code === CODES.H,
contextItemLabel: "labels.flipHorizontal",
});
export const actionFlipVertical = register({
name: "flipVertical",
trackEvent: { category: "element" },
perform: (elements, appState, _, app) => {
return {
elements: updateFrameMembershipOfSelectedElements(
flipSelectedElements(elements, appState, "vertical"),
appState,
app,
),
appState,
commitToHistory: true,
};
},
keyTest: (event) =>
event.shiftKey && event.code === CODES.V && !event[KEYS.CTRL_OR_CMD],
contextItemLabel: "labels.flipVertical",
});
const flipSelectedElements = (
elements: readonly ExcalidrawElement[],
appState: Readonly<AppState>,
flipDirection: "horizontal" | "vertical",
) => {
const selectedElements = getSelectedElements(
getNonDeletedElements(elements),
appState,
{
includeBoundTextElement: true,
includeElementsInFrames: true,
},
);
const updatedElements = flipElements(
selectedElements,
appState,
flipDirection,
);
const updatedElementsMap = arrayToMap(updatedElements);
return elements.map(
(element) => updatedElementsMap.get(element.id) || element,
);
};
const flipElements = (
elements: NonDeleted<ExcalidrawElement>[],
appState: AppState,
flipDirection: "horizontal" | "vertical",
): ExcalidrawElement[] => {
feat: add flipping for multiple elements (#5578) * feat: add flipping when resizing multiple elements * fix: image elements not flipping its content * test: fix accidental resizing in grouping test * fix: angles not flipping vertically when resizing * feat: add flipping multiple elements with a command * revert: image elements not flipping its content This reverts commit cb989a6c66e62a02a8c04ce41f12507806c8d0a0. * fix: add special cases for flipping text & images * fix: a few corner cases for flipping * fix: remove angle flip * fix: bound text scaling when resizing * fix: linear elements drifting away after multiple flips * revert: fix linear elements drifting away after multiple flips This reverts commit bffc33dd3ffe56c72029eee6aca843d992bac7ab. * fix: linear elements unstable bounds * revert: linear elements unstable bounds This reverts commit 22ae9b02c4a49f0ed6448c27abe1969cf6abb1e3. * fix: hand-drawn lines shift after flipping * test: fix flipping tests * test: fix the number of context menu items * fix: incorrect scaling due to ignoring bound text when finding selection bounds * fix: bound text coordinates not being updated * fix: lines bound text rotation * fix: incorrect placement of bound lines on flip * remove redundant predicates in actionFlip * update test * refactor resizeElement with some renaming and comments * fix grouped bounded text elements not being flipped correctly * combine mutation for bounded text element * remove incorrect return * fix: linear elements bindings after flipping * revert: remove incorrect return This reverts commit e6b205ca900b504fe982e4ac1b3b19dcfca246b8. * fix: minimum size for all elements in selection --------- Co-authored-by: Ryan Di <ryan.weihao.di@gmail.com>
2 years ago
const { minX, minY, maxX, maxY } = getCommonBoundingBox(elements);
resizeMultipleElements(
{ originalElements: arrayToMap(elements) } as PointerDownState,
elements,
"nw",
true,
flipDirection === "horizontal" ? maxX : minX,
flipDirection === "horizontal" ? minY : maxY,
);
feat: add flipping for multiple elements (#5578) * feat: add flipping when resizing multiple elements * fix: image elements not flipping its content * test: fix accidental resizing in grouping test * fix: angles not flipping vertically when resizing * feat: add flipping multiple elements with a command * revert: image elements not flipping its content This reverts commit cb989a6c66e62a02a8c04ce41f12507806c8d0a0. * fix: add special cases for flipping text & images * fix: a few corner cases for flipping * fix: remove angle flip * fix: bound text scaling when resizing * fix: linear elements drifting away after multiple flips * revert: fix linear elements drifting away after multiple flips This reverts commit bffc33dd3ffe56c72029eee6aca843d992bac7ab. * fix: linear elements unstable bounds * revert: linear elements unstable bounds This reverts commit 22ae9b02c4a49f0ed6448c27abe1969cf6abb1e3. * fix: hand-drawn lines shift after flipping * test: fix flipping tests * test: fix the number of context menu items * fix: incorrect scaling due to ignoring bound text when finding selection bounds * fix: bound text coordinates not being updated * fix: lines bound text rotation * fix: incorrect placement of bound lines on flip * remove redundant predicates in actionFlip * update test * refactor resizeElement with some renaming and comments * fix grouped bounded text elements not being flipped correctly * combine mutation for bounded text element * remove incorrect return * fix: linear elements bindings after flipping * revert: remove incorrect return This reverts commit e6b205ca900b504fe982e4ac1b3b19dcfca246b8. * fix: minimum size for all elements in selection --------- Co-authored-by: Ryan Di <ryan.weihao.di@gmail.com>
2 years ago
(isBindingEnabled(appState)
? bindOrUnbindSelectedElements
: unbindLinearElements)(elements);
feat: add flipping for multiple elements (#5578) * feat: add flipping when resizing multiple elements * fix: image elements not flipping its content * test: fix accidental resizing in grouping test * fix: angles not flipping vertically when resizing * feat: add flipping multiple elements with a command * revert: image elements not flipping its content This reverts commit cb989a6c66e62a02a8c04ce41f12507806c8d0a0. * fix: add special cases for flipping text & images * fix: a few corner cases for flipping * fix: remove angle flip * fix: bound text scaling when resizing * fix: linear elements drifting away after multiple flips * revert: fix linear elements drifting away after multiple flips This reverts commit bffc33dd3ffe56c72029eee6aca843d992bac7ab. * fix: linear elements unstable bounds * revert: linear elements unstable bounds This reverts commit 22ae9b02c4a49f0ed6448c27abe1969cf6abb1e3. * fix: hand-drawn lines shift after flipping * test: fix flipping tests * test: fix the number of context menu items * fix: incorrect scaling due to ignoring bound text when finding selection bounds * fix: bound text coordinates not being updated * fix: lines bound text rotation * fix: incorrect placement of bound lines on flip * remove redundant predicates in actionFlip * update test * refactor resizeElement with some renaming and comments * fix grouped bounded text elements not being flipped correctly * combine mutation for bounded text element * remove incorrect return * fix: linear elements bindings after flipping * revert: remove incorrect return This reverts commit e6b205ca900b504fe982e4ac1b3b19dcfca246b8. * fix: minimum size for all elements in selection --------- Co-authored-by: Ryan Di <ryan.weihao.di@gmail.com>
2 years ago
return elements;
};