Group/ungroup (#1648)

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Pete Hunt 2020-05-26 13:07:46 -07:00 committed by GitHub
parent 5252726307
commit 61e5b66dac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 964 additions and 86 deletions

View file

@ -5,10 +5,13 @@ import {
ExcalidrawGenericElement,
NonDeleted,
TextAlign,
GroupId,
} from "../element/types";
import { measureText } from "../utils";
import { randomInteger, randomId } from "../random";
import { newElementWith } from "./mutateElement";
import nanoid from "nanoid";
import { getNewGroupIdsForDuplication } from "../groups";
type ElementConstructorOpts = {
x: ExcalidrawGenericElement["x"];
@ -61,6 +64,7 @@ const _newElementBase = <T extends ExcalidrawElement>(
version: rest.version || 1,
versionNonce: rest.versionNonce ?? 0,
isDeleted: false as false,
groupIds: [],
});
export const newElement = (
@ -148,13 +152,39 @@ export const deepCopyElement = (val: any, depth: number = 0) => {
return val;
};
/**
* Duplicate an element, often used in the alt-drag operation.
* Note that this method has gotten a bit complicated since the
* introduction of gruoping/ungrouping elements.
* @param editingGroupId The current group being edited. The new
* element will inherit this group and its
* parents.
* @param groupIdMapForOperation A Map that maps old group IDs to
* duplicated ones. If you are duplicating
* multiple elements at once, share this map
* amongst all of them
* @param element Element to duplicate
* @param overrides Any element properties to override
*/
export const duplicateElement = <TElement extends Mutable<ExcalidrawElement>>(
editingGroupId: GroupId | null,
groupIdMapForOperation: Map<GroupId, GroupId>,
element: TElement,
overrides?: Partial<TElement>,
): TElement => {
let copy: TElement = deepCopyElement(element);
copy.id = randomId();
copy.seed = randomInteger();
copy.groupIds = getNewGroupIdsForDuplication(
copy.groupIds,
editingGroupId,
(groupId) => {
if (!groupIdMapForOperation.has(groupId)) {
groupIdMapForOperation.set(groupId, nanoid());
}
return groupIdMapForOperation.get(groupId)!;
},
);
if (overrides) {
copy = Object.assign(copy, overrides);
}