mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: fractional indexing (#7359)
* Introducing fractional indices as part of `element.index` * Ensuring invalid fractional indices are always synchronized with the array order * Simplifying reconciliation based on the fractional indices * Moving reconciliation inside the `@excalidraw/excalidraw` package --------- Co-authored-by: Marcel Mraz <marcel@excalidraw.com> Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
parent
bbdcd30a73
commit
32df5502ae
50 changed files with 3640 additions and 2047 deletions
|
@ -31,8 +31,9 @@ import {
|
|||
} from "../element/types";
|
||||
import { AppState } from "../types";
|
||||
import { Mutable } from "../utility-types";
|
||||
import { getFontString } from "../utils";
|
||||
import { arrayToMap, getFontString } from "../utils";
|
||||
import { register } from "./register";
|
||||
import { syncMovedIndices } from "../fractionalIndex";
|
||||
|
||||
export const actionUnbindText = register({
|
||||
name: "unbindText",
|
||||
|
@ -180,6 +181,8 @@ const pushTextAboveContainer = (
|
|||
(ele) => ele.id === container.id,
|
||||
);
|
||||
updatedElements.splice(containerIndex + 1, 0, textElement);
|
||||
syncMovedIndices(updatedElements, arrayToMap([container, textElement]));
|
||||
|
||||
return updatedElements;
|
||||
};
|
||||
|
||||
|
@ -198,6 +201,8 @@ const pushContainerBelowText = (
|
|||
(ele) => ele.id === textElement.id,
|
||||
);
|
||||
updatedElements.splice(textElementIndex, 0, container);
|
||||
syncMovedIndices(updatedElements, arrayToMap([container, textElement]));
|
||||
|
||||
return updatedElements;
|
||||
};
|
||||
|
||||
|
@ -304,6 +309,7 @@ export const actionWrapTextInContainer = register({
|
|||
container,
|
||||
textElement,
|
||||
);
|
||||
|
||||
containerIds[container.id] = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import {
|
|||
excludeElementsInFramesFromSelection,
|
||||
getSelectedElements,
|
||||
} from "../scene/selection";
|
||||
import { syncMovedIndices } from "../fractionalIndex";
|
||||
|
||||
export const actionDuplicateSelection = register({
|
||||
name: "duplicateSelection",
|
||||
|
@ -90,6 +91,7 @@ const duplicateElements = (
|
|||
const newElements: ExcalidrawElement[] = [];
|
||||
const oldElements: ExcalidrawElement[] = [];
|
||||
const oldIdToDuplicatedId = new Map();
|
||||
const duplicatedElementsMap = new Map<string, ExcalidrawElement>();
|
||||
|
||||
const duplicateAndOffsetElement = (element: ExcalidrawElement) => {
|
||||
const newElement = duplicateElement(
|
||||
|
@ -101,6 +103,7 @@ const duplicateElements = (
|
|||
y: element.y + GRID_SIZE / 2,
|
||||
},
|
||||
);
|
||||
duplicatedElementsMap.set(newElement.id, newElement);
|
||||
oldIdToDuplicatedId.set(element.id, newElement.id);
|
||||
oldElements.push(element);
|
||||
newElements.push(newElement);
|
||||
|
@ -238,9 +241,10 @@ const duplicateElements = (
|
|||
}
|
||||
|
||||
// step (3)
|
||||
|
||||
const finalElements = finalElementsReversed.reverse();
|
||||
|
||||
syncMovedIndices(finalElements, arrayToMap([...oldElements, ...newElements]));
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
bindTextToShapeAfterDuplication(
|
||||
|
|
|
@ -27,6 +27,7 @@ import {
|
|||
removeElementsFromFrame,
|
||||
replaceAllElementsInFrame,
|
||||
} from "../frame";
|
||||
import { syncMovedIndices } from "../fractionalIndex";
|
||||
|
||||
const allElementsInSameGroup = (elements: readonly ExcalidrawElement[]) => {
|
||||
if (elements.length >= 2) {
|
||||
|
@ -140,11 +141,12 @@ export const actionGroup = register({
|
|||
.filter(
|
||||
(updatedElement) => !isElementInGroup(updatedElement, newGroupId),
|
||||
);
|
||||
nextElements = [
|
||||
const reorderedElements = [
|
||||
...elementsBeforeGroup,
|
||||
...elementsInGroup,
|
||||
...elementsAfterGroup,
|
||||
];
|
||||
syncMovedIndices(reorderedElements, arrayToMap(elementsInGroup));
|
||||
|
||||
return {
|
||||
appState: {
|
||||
|
@ -155,7 +157,7 @@ export const actionGroup = register({
|
|||
getNonDeletedElements(nextElements),
|
||||
),
|
||||
},
|
||||
elements: nextElements,
|
||||
elements: reorderedElements,
|
||||
commitToHistory: true,
|
||||
};
|
||||
},
|
||||
|
|
|
@ -10,6 +10,7 @@ import { newElementWith } from "../element/mutateElement";
|
|||
import { fixBindingsAfterDeletion } from "../element/binding";
|
||||
import { arrayToMap } from "../utils";
|
||||
import { isWindows } from "../constants";
|
||||
import { syncInvalidIndices } from "../fractionalIndex";
|
||||
|
||||
const writeData = (
|
||||
prevElements: readonly ExcalidrawElement[],
|
||||
|
@ -48,6 +49,8 @@ const writeData = (
|
|||
),
|
||||
);
|
||||
fixBindingsAfterDeletion(elements, deletedElements);
|
||||
// TODO: will be replaced in #7348
|
||||
syncInvalidIndices(elements);
|
||||
|
||||
return {
|
||||
elements,
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import React from "react";
|
||||
import {
|
||||
moveOneLeft,
|
||||
moveOneRight,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue