mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
fractionalIndex as a byproduct or zIndex
This commit is contained in:
parent
c7ee46e7f8
commit
02dc00a47e
7 changed files with 128 additions and 24 deletions
125
src/zindex.ts
125
src/zindex.ts
|
@ -485,6 +485,99 @@ function shiftElementsAccountingForFrames(
|
|||
);
|
||||
}
|
||||
|
||||
// fractional indexing
|
||||
// -----------------------------------------------------------------------------
|
||||
const FRACTIONAL_INDEX_FLOOR = 0;
|
||||
const FRACTIONAL_INDEX_CEILING = 1;
|
||||
|
||||
const isFractionalIndexInValidRange = (index: number) => {
|
||||
return index > FRACTIONAL_INDEX_FLOOR && index < FRACTIONAL_INDEX_CEILING;
|
||||
};
|
||||
|
||||
const getFractionalIndex = (
|
||||
element: ExcalidrawElement | undefined,
|
||||
fallbackValue: number,
|
||||
) => {
|
||||
return element && isFractionalIndexInValidRange(element.fractionalIndex)
|
||||
? element.fractionalIndex
|
||||
: fallbackValue;
|
||||
};
|
||||
|
||||
const isValidFractionalIndex = (
|
||||
index: number,
|
||||
predecessorElement: ExcalidrawElement | undefined,
|
||||
successorElement: ExcalidrawElement | undefined,
|
||||
) => {
|
||||
return (
|
||||
isFractionalIndexInValidRange(index) &&
|
||||
index > getFractionalIndex(predecessorElement, FRACTIONAL_INDEX_FLOOR) &&
|
||||
index < getFractionalIndex(successorElement, FRACTIONAL_INDEX_CEILING)
|
||||
);
|
||||
};
|
||||
|
||||
const randomNumInBetween = (start: number, end: number) => {
|
||||
return Math.random() * (end - start) + start;
|
||||
};
|
||||
|
||||
export const generateFractionalIndex = ({
|
||||
start = FRACTIONAL_INDEX_FLOOR,
|
||||
end = FRACTIONAL_INDEX_CEILING,
|
||||
}: {
|
||||
start?: number;
|
||||
end?: number;
|
||||
}) => {
|
||||
const nextTemp = randomNumInBetween(start, end);
|
||||
return (
|
||||
(randomNumInBetween(nextTemp, end) + randomNumInBetween(start, nextTemp)) /
|
||||
2
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* normalize the fractional indicies of the elements in the given array such that
|
||||
* a. all elements have a fraction index between floor and ceiling as defined above
|
||||
* b. for every element, its fractional index is greater than its predecessor's and smaller than its successor's
|
||||
*/
|
||||
|
||||
export const normalizeFractionalIndexing = (
|
||||
allElements: readonly ExcalidrawElement[],
|
||||
) => {
|
||||
let predecessor = -1;
|
||||
let successor = 1;
|
||||
|
||||
const normalizedElements: ExcalidrawElement[] = [];
|
||||
|
||||
for (const element of allElements) {
|
||||
const predecessorElement = allElements[predecessor];
|
||||
const successorElement = allElements[successor];
|
||||
|
||||
if (
|
||||
!isValidFractionalIndex(
|
||||
element.fractionalIndex,
|
||||
predecessorElement,
|
||||
successorElement,
|
||||
)
|
||||
) {
|
||||
const nextFractionalIndex = generateFractionalIndex({
|
||||
start: getFractionalIndex(predecessorElement, FRACTIONAL_INDEX_FLOOR),
|
||||
end: getFractionalIndex(successorElement, FRACTIONAL_INDEX_CEILING),
|
||||
});
|
||||
|
||||
normalizedElements.push({
|
||||
...element,
|
||||
fractionalIndex: nextFractionalIndex,
|
||||
});
|
||||
} else {
|
||||
normalizedElements.push(element);
|
||||
}
|
||||
|
||||
predecessor++;
|
||||
successor++;
|
||||
}
|
||||
|
||||
return normalizedElements;
|
||||
};
|
||||
|
||||
// public API
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
@ -492,25 +585,31 @@ export const moveOneLeft = (
|
|||
allElements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
) => {
|
||||
return shiftElementsByOne(allElements, appState, "left");
|
||||
return normalizeFractionalIndexing(
|
||||
shiftElementsByOne(allElements, appState, "left"),
|
||||
);
|
||||
};
|
||||
|
||||
export const moveOneRight = (
|
||||
allElements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
) => {
|
||||
return shiftElementsByOne(allElements, appState, "right");
|
||||
return normalizeFractionalIndexing(
|
||||
shiftElementsByOne(allElements, appState, "right"),
|
||||
);
|
||||
};
|
||||
|
||||
export const moveAllLeft = (
|
||||
allElements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
) => {
|
||||
return shiftElementsAccountingForFrames(
|
||||
allElements,
|
||||
appState,
|
||||
"left",
|
||||
shiftElementsToEnd,
|
||||
return normalizeFractionalIndexing(
|
||||
shiftElementsAccountingForFrames(
|
||||
allElements,
|
||||
appState,
|
||||
"left",
|
||||
shiftElementsToEnd,
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -518,10 +617,12 @@ export const moveAllRight = (
|
|||
allElements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
) => {
|
||||
return shiftElementsAccountingForFrames(
|
||||
allElements,
|
||||
appState,
|
||||
"right",
|
||||
shiftElementsToEnd,
|
||||
return normalizeFractionalIndexing(
|
||||
shiftElementsAccountingForFrames(
|
||||
allElements,
|
||||
appState,
|
||||
"right",
|
||||
shiftElementsToEnd,
|
||||
),
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue