generate real fractional index after z-index actions
This commit is contained in:
parent
d1a9c593cc
commit
84c1de7a03
@ -43,6 +43,7 @@ import {
|
|||||||
measureBaseline,
|
measureBaseline,
|
||||||
} from "../element/textElement";
|
} from "../element/textElement";
|
||||||
import { normalizeLink } from "./url";
|
import { normalizeLink } from "./url";
|
||||||
|
import { normalizeFractionalIndicies } from "../fractionalIndex";
|
||||||
|
|
||||||
type RestoredAppState = Omit<
|
type RestoredAppState = Omit<
|
||||||
AppState,
|
AppState,
|
||||||
@ -460,7 +461,7 @@ export const restoreElements = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return restoredElements;
|
return normalizeFractionalIndicies(restoredElements) as ExcalidrawElement[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const coalesceAppStateValue = <
|
const coalesceAppStateValue = <
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { mutateElement } from "./element/mutateElement";
|
import { mutateElement } from "./element/mutateElement";
|
||||||
import { ExcalidrawElement } from "./element/types";
|
import { ExcalidrawElement } from "./element/types";
|
||||||
import { generateKeyBetween } from "fractional-indexing";
|
import { generateKeyBetween, generateNKeysBetween } from "fractional-indexing";
|
||||||
|
|
||||||
type FractionalIndex = ExcalidrawElement["fractionalIndex"];
|
type FractionalIndex = ExcalidrawElement["fractionalIndex"];
|
||||||
|
|
||||||
@ -28,6 +28,80 @@ const isValidFractionalIndex = (
|
|||||||
return false;
|
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 = (
|
const generateFractionalIndex = (
|
||||||
index: FractionalIndex,
|
index: FractionalIndex,
|
||||||
predecessor: FractionalIndex,
|
predecessor: FractionalIndex,
|
||||||
|
@ -315,11 +315,11 @@ class Scene {
|
|||||||
"insertElementAtIndex can only be called with index >= 0",
|
"insertElementAtIndex can only be called with index >= 0",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const nextElements = [
|
const nextElements = normalizeFractionalIndicies([
|
||||||
...this.elements.slice(0, index),
|
...this.elements.slice(0, index),
|
||||||
...elements,
|
...elements,
|
||||||
...this.elements.slice(index),
|
...this.elements.slice(index),
|
||||||
];
|
]);
|
||||||
|
|
||||||
this.replaceAllElements(nextElements);
|
this.replaceAllElements(nextElements);
|
||||||
}
|
}
|
||||||
@ -328,7 +328,9 @@ class Scene {
|
|||||||
if (element.frameId) {
|
if (element.frameId) {
|
||||||
this.insertElementAtIndex(element, this.getElementIndex(element.frameId));
|
this.insertElementAtIndex(element, this.getElementIndex(element.frameId));
|
||||||
} else {
|
} else {
|
||||||
this.replaceAllElements([...this.elements, element]);
|
this.replaceAllElements(
|
||||||
|
normalizeFractionalIndicies([...this.elements, element]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { bumpVersion } from "./element/mutateElement";
|
import { bumpVersion } from "./element/mutateElement";
|
||||||
import { isFrameLikeElement } from "./element/typeChecks";
|
import { isFrameLikeElement } from "./element/typeChecks";
|
||||||
import { ExcalidrawElement, ExcalidrawFrameLikeElement } from "./element/types";
|
import { ExcalidrawElement, ExcalidrawFrameLikeElement } from "./element/types";
|
||||||
|
import { fixFractionalIndices } from "./fractionalIndex";
|
||||||
import { getElementsInGroup } from "./groups";
|
import { getElementsInGroup } from "./groups";
|
||||||
import { getSelectedElements } from "./scene";
|
import { getSelectedElements } from "./scene";
|
||||||
import Scene from "./scene/Scene";
|
import Scene from "./scene/Scene";
|
||||||
@ -312,12 +313,7 @@ const shiftElementsByOne = (
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
return elements.map((element) => {
|
return fixFractionalIndices(elements, targetElementsMap);
|
||||||
if (targetElementsMap[element.id]) {
|
|
||||||
return bumpVersion(element);
|
|
||||||
}
|
|
||||||
return element;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const shiftElementsToEnd = (
|
const shiftElementsToEnd = (
|
||||||
@ -390,7 +386,8 @@ const shiftElementsToEnd = (
|
|||||||
const leadingElements = elements.slice(0, leadingIndex);
|
const leadingElements = elements.slice(0, leadingIndex);
|
||||||
const trailingElements = elements.slice(trailingIndex + 1);
|
const trailingElements = elements.slice(trailingIndex + 1);
|
||||||
|
|
||||||
return direction === "left"
|
return fixFractionalIndices(
|
||||||
|
direction === "left"
|
||||||
? [
|
? [
|
||||||
...leadingElements,
|
...leadingElements,
|
||||||
...targetElements,
|
...targetElements,
|
||||||
@ -402,7 +399,9 @@ const shiftElementsToEnd = (
|
|||||||
...displacedElements,
|
...displacedElements,
|
||||||
...targetElements,
|
...targetElements,
|
||||||
...trailingElements,
|
...trailingElements,
|
||||||
];
|
],
|
||||||
|
targetElementsMap,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function shiftElementsAccountingForFrames(
|
function shiftElementsAccountingForFrames(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user