generate real fractional index after z-index actions
This commit is contained in:
parent
d1a9c593cc
commit
093e684d9e
@ -43,6 +43,7 @@ import {
|
||||
measureBaseline,
|
||||
} from "../element/textElement";
|
||||
import { normalizeLink } from "./url";
|
||||
import { normalizeFractionalIndicies } from "../fractionalIndex";
|
||||
|
||||
type RestoredAppState = Omit<
|
||||
AppState,
|
||||
@ -460,7 +461,7 @@ export const restoreElements = (
|
||||
}
|
||||
}
|
||||
|
||||
return restoredElements;
|
||||
return normalizeFractionalIndicies(restoredElements) as ExcalidrawElement[];
|
||||
};
|
||||
|
||||
const coalesceAppStateValue = <
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { mutateElement } from "./element/mutateElement";
|
||||
import { ExcalidrawElement } from "./element/types";
|
||||
import { generateKeyBetween } from "fractional-indexing";
|
||||
import { generateKeyBetween, generateNKeysBetween } from "fractional-indexing";
|
||||
|
||||
type FractionalIndex = ExcalidrawElement["fractionalIndex"];
|
||||
|
||||
@ -28,6 +28,80 @@ const isValidFractionalIndex = (
|
||||
return false;
|
||||
};
|
||||
|
||||
const getContiguousMovedIndices = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
movedElementsMap: Record<string, ExcalidrawElement>,
|
||||
) => {
|
||||
const result: number[][] = [];
|
||||
const contiguous: number[] = [];
|
||||
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
const element = elements[i];
|
||||
if (movedElementsMap[element.id]) {
|
||||
if (contiguous.length) {
|
||||
if (contiguous[contiguous.length - 1] + 1 === i) {
|
||||
contiguous.push(i);
|
||||
} else {
|
||||
result.push(contiguous.slice());
|
||||
contiguous.length = 0;
|
||||
contiguous.push(i);
|
||||
}
|
||||
} else {
|
||||
contiguous.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (contiguous.length > 0) {
|
||||
result.push(contiguous.slice());
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const fixFractionalIndices = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
movedElementsMap: Record<string, ExcalidrawElement>,
|
||||
) => {
|
||||
const fixedElements = elements.slice();
|
||||
const contiguousMovedIndices = getContiguousMovedIndices(
|
||||
fixedElements,
|
||||
movedElementsMap,
|
||||
);
|
||||
|
||||
for (const movedIndices of contiguousMovedIndices) {
|
||||
try {
|
||||
const predecessor =
|
||||
fixedElements[movedIndices[0] - 1]?.fractionalIndex || null;
|
||||
const successor =
|
||||
fixedElements[movedIndices[movedIndices.length - 1] + 1]
|
||||
?.fractionalIndex || null;
|
||||
|
||||
const newKeys = generateNKeysBetween(
|
||||
predecessor,
|
||||
successor,
|
||||
movedIndices.length,
|
||||
);
|
||||
|
||||
for (let i = 0; i < movedIndices.length; i++) {
|
||||
const element = fixedElements[movedIndices[i]];
|
||||
|
||||
mutateElement(
|
||||
element,
|
||||
{
|
||||
fractionalIndex: newKeys[i],
|
||||
},
|
||||
false,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("error generating fractional indices", e);
|
||||
}
|
||||
}
|
||||
|
||||
return fixedElements;
|
||||
};
|
||||
|
||||
const generateFractionalIndex = (
|
||||
index: FractionalIndex,
|
||||
predecessor: FractionalIndex,
|
||||
|
@ -328,7 +328,9 @@ class Scene {
|
||||
if (element.frameId) {
|
||||
this.insertElementAtIndex(element, this.getElementIndex(element.frameId));
|
||||
} else {
|
||||
this.replaceAllElements([...this.elements, element]);
|
||||
this.replaceAllElements(
|
||||
normalizeFractionalIndicies([...this.elements, element]),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { bumpVersion } from "./element/mutateElement";
|
||||
import { isFrameLikeElement } from "./element/typeChecks";
|
||||
import { ExcalidrawElement, ExcalidrawFrameLikeElement } from "./element/types";
|
||||
import { fixFractionalIndices } from "./fractionalIndex";
|
||||
import { getElementsInGroup } from "./groups";
|
||||
import { getSelectedElements } from "./scene";
|
||||
import Scene from "./scene/Scene";
|
||||
@ -312,12 +313,7 @@ const shiftElementsByOne = (
|
||||
];
|
||||
});
|
||||
|
||||
return elements.map((element) => {
|
||||
if (targetElementsMap[element.id]) {
|
||||
return bumpVersion(element);
|
||||
}
|
||||
return element;
|
||||
});
|
||||
return fixFractionalIndices(elements, targetElementsMap);
|
||||
};
|
||||
|
||||
const shiftElementsToEnd = (
|
||||
@ -390,7 +386,8 @@ const shiftElementsToEnd = (
|
||||
const leadingElements = elements.slice(0, leadingIndex);
|
||||
const trailingElements = elements.slice(trailingIndex + 1);
|
||||
|
||||
return direction === "left"
|
||||
return fixFractionalIndices(
|
||||
direction === "left"
|
||||
? [
|
||||
...leadingElements,
|
||||
...targetElements,
|
||||
@ -402,7 +399,9 @@ const shiftElementsToEnd = (
|
||||
...displacedElements,
|
||||
...targetElements,
|
||||
...trailingElements,
|
||||
];
|
||||
],
|
||||
targetElementsMap,
|
||||
);
|
||||
};
|
||||
|
||||
function shiftElementsAccountingForFrames(
|
||||
|
Loading…
x
Reference in New Issue
Block a user