fix fractional indices on adding new elements
This commit is contained in:
parent
5bc23d6dee
commit
7dfba985f9
@ -268,6 +268,7 @@ import {
|
|||||||
muteFSAbortError,
|
muteFSAbortError,
|
||||||
isTestEnv,
|
isTestEnv,
|
||||||
easeOut,
|
easeOut,
|
||||||
|
arrayToMap,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
import {
|
import {
|
||||||
createSrcDoc,
|
createSrcDoc,
|
||||||
@ -2921,7 +2922,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
...newElements,
|
...newElements,
|
||||||
];
|
];
|
||||||
|
|
||||||
this.scene.replaceAllElements(nextElements);
|
this.scene.replaceAllElements(nextElements, arrayToMap(newElements));
|
||||||
|
|
||||||
newElements.forEach((newElement) => {
|
newElements.forEach((newElement) => {
|
||||||
if (isTextElement(newElement) && isBoundToContainer(newElement)) {
|
if (isTextElement(newElement) && isBoundToContainer(newElement)) {
|
||||||
@ -3147,10 +3148,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
this.scene.getElementIndex(frameId),
|
this.scene.getElementIndex(frameId),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.scene.replaceAllElements([
|
this.scene.replaceAllElements(
|
||||||
...this.scene.getElementsIncludingDeleted(),
|
[...this.scene.getElementsIncludingDeleted(), ...textElements],
|
||||||
...textElements,
|
arrayToMap(textElements),
|
||||||
]);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -6137,10 +6138,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
height,
|
height,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.scene.replaceAllElements([
|
this.scene.replaceAllElements(
|
||||||
...this.scene.getElementsIncludingDeleted(),
|
[...this.scene.getElementsIncludingDeleted(), element],
|
||||||
element,
|
arrayToMap([element]),
|
||||||
]);
|
);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
};
|
};
|
||||||
@ -6192,10 +6193,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
validated: null,
|
validated: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.scene.replaceAllElements([
|
this.scene.replaceAllElements(
|
||||||
...this.scene.getElementsIncludingDeleted(),
|
[...this.scene.getElementsIncludingDeleted(), element],
|
||||||
element,
|
arrayToMap([element]),
|
||||||
]);
|
);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
};
|
};
|
||||||
@ -6473,10 +6474,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
? newMagicFrameElement(constructorOpts)
|
? newMagicFrameElement(constructorOpts)
|
||||||
: newFrameElement(constructorOpts);
|
: newFrameElement(constructorOpts);
|
||||||
|
|
||||||
this.scene.replaceAllElements([
|
this.scene.replaceAllElements(
|
||||||
...this.scene.getElementsIncludingDeleted(),
|
[...this.scene.getElementsIncludingDeleted(), frame],
|
||||||
frame,
|
arrayToMap([frame]),
|
||||||
]);
|
);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
multiElement: null,
|
multiElement: null,
|
||||||
|
@ -30,14 +30,14 @@ const isValidFractionalIndex = (
|
|||||||
|
|
||||||
const getContiguousMovedIndices = (
|
const getContiguousMovedIndices = (
|
||||||
elements: readonly ExcalidrawElement[],
|
elements: readonly ExcalidrawElement[],
|
||||||
movedElementsMap: Record<string, ExcalidrawElement>,
|
movedElementsMap: Map<string, ExcalidrawElement>,
|
||||||
) => {
|
) => {
|
||||||
const result: number[][] = [];
|
const result: number[][] = [];
|
||||||
const contiguous: number[] = [];
|
const contiguous: number[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < elements.length; i++) {
|
for (let i = 0; i < elements.length; i++) {
|
||||||
const element = elements[i];
|
const element = elements[i];
|
||||||
if (movedElementsMap[element.id]) {
|
if (movedElementsMap.has(element.id)) {
|
||||||
if (contiguous.length) {
|
if (contiguous.length) {
|
||||||
if (contiguous[contiguous.length - 1] + 1 === i) {
|
if (contiguous[contiguous.length - 1] + 1 === i) {
|
||||||
contiguous.push(i);
|
contiguous.push(i);
|
||||||
@ -59,9 +59,22 @@ const getContiguousMovedIndices = (
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const generateFractionalIndexBetween = (
|
||||||
|
predecessor: FractionalIndex,
|
||||||
|
successor: FractionalIndex,
|
||||||
|
) => {
|
||||||
|
if (predecessor && successor) {
|
||||||
|
if (predecessor < successor) {
|
||||||
|
return generateKeyBetween(predecessor, successor);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return generateKeyBetween(predecessor, successor);
|
||||||
|
};
|
||||||
|
|
||||||
export const fixFractionalIndices = (
|
export const fixFractionalIndices = (
|
||||||
elements: readonly ExcalidrawElement[],
|
elements: readonly ExcalidrawElement[],
|
||||||
movedElementsMap: Record<string, ExcalidrawElement>,
|
movedElementsMap: Map<string, ExcalidrawElement>,
|
||||||
) => {
|
) => {
|
||||||
const fixedElements = elements.slice();
|
const fixedElements = elements.slice();
|
||||||
const contiguousMovedIndices = getContiguousMovedIndices(
|
const contiguousMovedIndices = getContiguousMovedIndices(
|
||||||
@ -95,7 +108,7 @@ export const fixFractionalIndices = (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("error generating fractional indices", e);
|
console.error("error fixing fractional indices", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +177,8 @@ export const normalizeFractionalIndicies = (
|
|||||||
let pre = -1;
|
let pre = -1;
|
||||||
let suc = 1;
|
let suc = 1;
|
||||||
|
|
||||||
|
const normalized: ExcalidrawElement[] = [];
|
||||||
|
|
||||||
for (const element of allElements) {
|
for (const element of allElements) {
|
||||||
const predecessor = allElements[pre]?.fractionalIndex || null;
|
const predecessor = allElements[pre]?.fractionalIndex || null;
|
||||||
const successor = allElements[suc]?.fractionalIndex || null;
|
const successor = allElements[suc]?.fractionalIndex || null;
|
||||||
@ -178,20 +193,20 @@ export const normalizeFractionalIndicies = (
|
|||||||
successor,
|
successor,
|
||||||
);
|
);
|
||||||
|
|
||||||
mutateElement(
|
normalized.push({
|
||||||
element,
|
...element,
|
||||||
{
|
fractionalIndex: nextFractionalIndex,
|
||||||
fractionalIndex: nextFractionalIndex,
|
});
|
||||||
},
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("normalizing fractional index", e);
|
console.error("normalizing fractional index", e);
|
||||||
|
normalized.push(element);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
normalized.push(element);
|
||||||
}
|
}
|
||||||
pre++;
|
pre++;
|
||||||
suc++;
|
suc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return allElements;
|
return normalized;
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,8 @@ import { getSelectedElements } from "./selection";
|
|||||||
import { AppState } from "../types";
|
import { AppState } from "../types";
|
||||||
import { Assert, SameType } from "../utility-types";
|
import { Assert, SameType } from "../utility-types";
|
||||||
import { randomInteger } from "../random";
|
import { randomInteger } from "../random";
|
||||||
import { normalizeFractionalIndicies } from "../fractionalIndex";
|
import { fixFractionalIndices } from "../fractionalIndex";
|
||||||
|
import { arrayToMap } from "../utils";
|
||||||
|
|
||||||
type ElementIdKey = InstanceType<typeof LinearElementEditor>["elementId"];
|
type ElementIdKey = InstanceType<typeof LinearElementEditor>["elementId"];
|
||||||
type ElementKey = ExcalidrawElement | ElementIdKey;
|
type ElementKey = ExcalidrawElement | ElementIdKey;
|
||||||
@ -230,9 +231,14 @@ class Scene {
|
|||||||
|
|
||||||
replaceAllElements(
|
replaceAllElements(
|
||||||
nextElements: readonly ExcalidrawElement[],
|
nextElements: readonly ExcalidrawElement[],
|
||||||
mapElementIds = true,
|
mapOfIndicesToFix?: Map<string, ExcalidrawElement>,
|
||||||
) {
|
) {
|
||||||
const _nextElements = normalizeFractionalIndicies(nextElements);
|
let _nextElements;
|
||||||
|
if (mapOfIndicesToFix) {
|
||||||
|
_nextElements = fixFractionalIndices(nextElements, mapOfIndicesToFix);
|
||||||
|
} else {
|
||||||
|
_nextElements = nextElements;
|
||||||
|
}
|
||||||
|
|
||||||
this.elements = _nextElements;
|
this.elements = _nextElements;
|
||||||
const nextFrameLikes: ExcalidrawFrameLikeElement[] = [];
|
const nextFrameLikes: ExcalidrawFrameLikeElement[] = [];
|
||||||
@ -306,7 +312,7 @@ class Scene {
|
|||||||
element,
|
element,
|
||||||
...this.elements.slice(index),
|
...this.elements.slice(index),
|
||||||
];
|
];
|
||||||
this.replaceAllElements(nextElements);
|
this.replaceAllElements(nextElements, arrayToMap([element]));
|
||||||
}
|
}
|
||||||
|
|
||||||
insertElementsAtIndex(elements: ExcalidrawElement[], index: number) {
|
insertElementsAtIndex(elements: ExcalidrawElement[], index: number) {
|
||||||
@ -321,14 +327,17 @@ class Scene {
|
|||||||
...this.elements.slice(index),
|
...this.elements.slice(index),
|
||||||
];
|
];
|
||||||
|
|
||||||
this.replaceAllElements(nextElements);
|
this.replaceAllElements(nextElements, arrayToMap(elements));
|
||||||
}
|
}
|
||||||
|
|
||||||
addNewElement = (element: ExcalidrawElement) => {
|
addNewElement = (element: ExcalidrawElement) => {
|
||||||
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(
|
||||||
|
[...this.elements, element],
|
||||||
|
arrayToMap([element]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -235,9 +235,9 @@ const getTargetElementsMap = <T extends ExcalidrawElement>(
|
|||||||
) => {
|
) => {
|
||||||
return indices.reduce((acc, index) => {
|
return indices.reduce((acc, index) => {
|
||||||
const element = elements[index];
|
const element = elements[index];
|
||||||
acc[element.id] = element;
|
acc.set(element.id, element);
|
||||||
return acc;
|
return acc;
|
||||||
}, {} as Record<string, ExcalidrawElement>);
|
}, new Map<string, ExcalidrawElement>());
|
||||||
};
|
};
|
||||||
|
|
||||||
const shiftElementsByOne = (
|
const shiftElementsByOne = (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user