fixed node extent calculation and simplified calculateNodePosition

This commit is contained in:
peterkogo
2024-08-20 12:42:57 +02:00
parent d9563505d8
commit 4a30f3a0fd
4 changed files with 15 additions and 42 deletions
@@ -90,7 +90,7 @@ export function NodeWrapper<NodeType extends Node>({
const inlineDimensions = getNodeInlineStyleDimensions(node); const inlineDimensions = getNodeInlineStyleDimensions(node);
// TODO: clamping should happen earlier // TODO: clamping should happen earlier
const clampedPosition = nodeExtent const clampedPosition = nodeExtent
? clampPosition(internals.positionAbsolute, nodeExtent, node.measured, origin) ? clampPosition(internals.positionAbsolute, nodeExtent, node.measured)
: internals.positionAbsolute; : internals.positionAbsolute;
const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave; const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;
+2 -7
View File
@@ -278,15 +278,10 @@ const createStore = ({
triggerEdgeChanges(edgeChanges); triggerEdgeChanges(edgeChanges);
}, },
setNodeExtent: (nodeExtent) => { setNodeExtent: (nodeExtent) => {
const { nodeLookup, nodeOrigin } = get(); const { nodeLookup } = get();
for (const [, node] of nodeLookup) { for (const [, node] of nodeLookup) {
const positionAbsolute = clampPosition( const positionAbsolute = clampPosition(node.internals.positionAbsolute, nodeExtent, node.measured);
node.internals.positionAbsolute,
nodeExtent,
node.measured,
node.origin ?? nodeOrigin
);
nodeLookup.set(node.id, { nodeLookup.set(node.id, {
...node, ...node,
+4 -5
View File
@@ -19,17 +19,16 @@ export const clamp = (val: number, min = 0, max = 1): number => Math.min(Math.ma
export const clampPosition = ( export const clampPosition = (
position: XYPosition = { x: 0, y: 0 }, position: XYPosition = { x: 0, y: 0 },
extent: CoordinateExtent, extent: CoordinateExtent,
dimensions: Partial<Dimensions>, dimensions: Partial<Dimensions>
origin: NodeOrigin
) => ({ ) => ({
x: clamp(position.x, extent[0][0], extent[1][0] - (dimensions?.width ?? 0) * origin[0]), x: clamp(position.x, extent[0][0], extent[1][0] - (dimensions?.width ?? 0)),
y: clamp(position.y, extent[0][1], extent[1][1] - (dimensions?.height ?? 0) * origin[1]), y: clamp(position.y, extent[0][1], extent[1][1] - (dimensions?.height ?? 0)),
}); });
/** /**
* Calculates the velocity of panning when the mouse is close to the edge of the canvas * Calculates the velocity of panning when the mouse is close to the edge of the canvas
* @internal * @internal
* @param value - One dimensional poition of the mouse (x or y) * @param value - One dimensional poition of the mouse supi(x or y)
* @param min - Minimal position on canvas before panning starts * @param min - Minimal position on canvas before panning starts
* @param max - Maximal position on canvas before panning starts * @param max - Maximal position on canvas before panning starts
* @returns - A number between 0 and 1 that represents the velocity of panning * @returns - A number between 0 and 1 that represents the velocity of panning
+8 -29
View File
@@ -276,24 +276,6 @@ export async function fitView<Params extends FitViewParamsBase<NodeBase>, Option
return Promise.resolve(true); return Promise.resolve(true);
} }
/**
* This function clamps the passed extend by the node's width and height.
* This is needed to prevent the node from being dragged outside of its extent.
*
* @param node
* @param extent
* @returns
*/
function clampNodeExtent<NodeType extends NodeBase>(
node: NodeType,
extent?: CoordinateExtent | 'parent'
): CoordinateExtent | 'parent' | undefined {
if (!extent || extent === 'parent') {
return extent;
}
return [extent[0], [extent[1][0] - (node.measured?.width ?? 0), extent[1][1] - (node.measured?.height ?? 0)]];
}
/** /**
* This function calculates the next position of a node, taking into account the node's extent, parent node, and origin. * This function calculates the next position of a node, taking into account the node's extent, parent node, and origin.
* *
@@ -318,40 +300,37 @@ export function calculateNodePosition<NodeType extends NodeBase>({
const node = nodeLookup.get(nodeId)!; const node = nodeLookup.get(nodeId)!;
const parentNode = node.parentId ? nodeLookup.get(node.parentId) : undefined; const parentNode = node.parentId ? nodeLookup.get(node.parentId) : undefined;
const { x: parentX, y: parentY } = parentNode ? parentNode.internals.positionAbsolute : { x: 0, y: 0 }; const { x: parentX, y: parentY } = parentNode ? parentNode.internals.positionAbsolute : { x: 0, y: 0 };
const origin = node.origin ?? nodeOrigin;
let currentExtent = clampNodeExtent(node, node.extent || nodeExtent); const origin = node.origin ?? nodeOrigin;
let extent = nodeExtent;
if (node.extent === 'parent' && !node.expandParent) { if (node.extent === 'parent' && !node.expandParent) {
if (!parentNode) { if (!parentNode) {
onError?.('005', errorMessages['error005']()); onError?.('005', errorMessages['error005']());
} else { } else {
const nodeWidth = node.measured.width;
const nodeHeight = node.measured.height;
const parentWidth = parentNode.measured.width; const parentWidth = parentNode.measured.width;
const parentHeight = parentNode.measured.height; const parentHeight = parentNode.measured.height;
if (nodeWidth && nodeHeight && parentWidth && parentHeight) { if (parentWidth && parentHeight) {
currentExtent = [ extent = [
[parentX, parentY], [parentX, parentY],
[parentX + parentWidth - nodeWidth, parentY + parentHeight - nodeHeight], [parentX + parentWidth, parentY + parentHeight],
]; ];
} }
} }
} else if (parentNode && isCoordinateExtent(node.extent)) { } else if (parentNode && isCoordinateExtent(node.extent)) {
currentExtent = [ extent = [
[node.extent[0][0] + parentX, node.extent[0][1] + parentY], [node.extent[0][0] + parentX, node.extent[0][1] + parentY],
[node.extent[1][0] + parentX, node.extent[1][1] + parentY], [node.extent[1][0] + parentX, node.extent[1][1] + parentY],
]; ];
} }
const positionAbsolute = isCoordinateExtent(currentExtent) const positionAbsolute = isCoordinateExtent(extent)
? clampPosition(nextPosition, currentExtent, node.measured, origin) ? clampPosition(nextPosition, extent, node.measured)
: nextPosition; : nextPosition;
return { return {
position: { position: {
// TODO: is there a better way to do this?
x: positionAbsolute.x - parentX + node.measured.width! * origin[0], x: positionAbsolute.x - parentX + node.measured.width! * origin[0],
y: positionAbsolute.y - parentY + node.measured.height! * origin[1], y: positionAbsolute.y - parentY + node.measured.height! * origin[1],
}, },