refactor(z-level): implement new stacking logic
This commit is contained in:
+42
-35
@@ -1,48 +1,50 @@
|
||||
import { ElementId, Node, NodeInternals, NodeInternalsItem, XYPosition } from '../types';
|
||||
|
||||
type XYPosAndTreeLevel = XYPosition & { treeLevel: number };
|
||||
type XYZPosition = XYPosition & { z: number };
|
||||
type ParentNodes = Record<ElementId, boolean>;
|
||||
|
||||
function addPositions(a: XYPosAndTreeLevel, b: XYPosAndTreeLevel): XYPosAndTreeLevel {
|
||||
return {
|
||||
x: (a.x ?? 0) + (b.x ?? 0),
|
||||
y: (a.y ?? 0) + (b.y ?? 0),
|
||||
treeLevel: a.treeLevel + (b.treeLevel || 1),
|
||||
};
|
||||
}
|
||||
|
||||
function getAbsolutePosAndTreeLevel(
|
||||
function calculateXYZPosition(
|
||||
node: NodeInternalsItem,
|
||||
nodeInternals: NodeInternals,
|
||||
result: XYPosAndTreeLevel
|
||||
): XYPosAndTreeLevel {
|
||||
const parentNode = node.parentNode ? nodeInternals.get(node.parentNode) : false;
|
||||
|
||||
if (!parentNode) {
|
||||
parentNodes: ParentNodes,
|
||||
result: XYZPosition
|
||||
): XYZPosition {
|
||||
if (!node.parentNode) {
|
||||
return result;
|
||||
}
|
||||
const parentNode = nodeInternals.get(node.parentNode)!;
|
||||
|
||||
return getAbsolutePosAndTreeLevel(
|
||||
parentNode,
|
||||
nodeInternals,
|
||||
addPositions(result, {
|
||||
x: parentNode.position?.x || 0,
|
||||
y: parentNode.position?.y || 0,
|
||||
treeLevel: parentNode.treeLevel || 0,
|
||||
})
|
||||
);
|
||||
// +1 for each recursion level
|
||||
let zAddition = 1;
|
||||
|
||||
// +2 if it's a parent node, so that groups/parents are always on top
|
||||
if (parentNodes[node.parentNode!]) {
|
||||
zAddition = 2;
|
||||
}
|
||||
|
||||
if (parentNode.z) {
|
||||
zAddition += parentNode.z;
|
||||
}
|
||||
|
||||
return calculateXYZPosition(parentNode, nodeInternals, parentNodes, {
|
||||
x: (result.x ?? 0) + (parentNode.position?.x ?? 0),
|
||||
y: (result.y ?? 0) + (parentNode.position?.y ?? 0),
|
||||
z: (result.z ?? 0) + zAddition,
|
||||
});
|
||||
}
|
||||
export function createNodeInternals(nodes: Node[], nodeInternals: NodeInternals): NodeInternals {
|
||||
const nextNodeInternals = new Map<ElementId, NodeInternalsItem>();
|
||||
const parentNodes: Record<ElementId, boolean> = {};
|
||||
const parentNodes: ParentNodes = {};
|
||||
|
||||
nodes.forEach((node) => {
|
||||
const internals: NodeInternalsItem = {
|
||||
...nodeInternals.get(node.id),
|
||||
id: node.id,
|
||||
width: node.width || null,
|
||||
height: node.height || null,
|
||||
position: node.position,
|
||||
positionAbsolute: node.position,
|
||||
treeLevel: node.isDragging || node.isSelected ? 1000 : node.zIndex || 0,
|
||||
z: node.isDragging || node.isSelected ? 1000 : node.zIndex || 0,
|
||||
};
|
||||
if (node.parentNode) {
|
||||
internals.parentNode = node.parentNode;
|
||||
@@ -55,25 +57,30 @@ export function createNodeInternals(nodes: Node[], nodeInternals: NodeInternals)
|
||||
const updatedInternals: NodeInternalsItem = nextNodeInternals.get(node.id)!;
|
||||
|
||||
if (node.parentNode || parentNodes[node.id]) {
|
||||
if (node.parentNode) {
|
||||
const parentNodeInternal = nextNodeInternals.get(node.parentNode);
|
||||
if (parentNodeInternal) {
|
||||
parentNodeInternal.isParentNode = true;
|
||||
let startingZ = updatedInternals.z;
|
||||
|
||||
if (!startingZ) {
|
||||
if (parentNodes[node.id] && node.parentNode) {
|
||||
startingZ = 2;
|
||||
} else if (node.parentNode) {
|
||||
startingZ = 1;
|
||||
}
|
||||
}
|
||||
|
||||
const positionAbsoluteAndTreeLevel = getAbsolutePosAndTreeLevel(node, nextNodeInternals, {
|
||||
const { x, y, z } = calculateXYZPosition(node, nextNodeInternals, parentNodes, {
|
||||
...node.position,
|
||||
treeLevel: updatedInternals.treeLevel || 1,
|
||||
z: startingZ as number,
|
||||
});
|
||||
|
||||
const { treeLevel, x, y } = positionAbsoluteAndTreeLevel;
|
||||
|
||||
updatedInternals.positionAbsolute = {
|
||||
x,
|
||||
y,
|
||||
};
|
||||
updatedInternals.treeLevel = treeLevel;
|
||||
updatedInternals.z = z;
|
||||
|
||||
if (parentNodes[node.id]) {
|
||||
updatedInternals.isParent = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user