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

View File

@@ -90,7 +90,7 @@ export function NodeWrapper<NodeType extends Node>({
const inlineDimensions = getNodeInlineStyleDimensions(node);
// TODO: clamping should happen earlier
const clampedPosition = nodeExtent
? clampPosition(internals.positionAbsolute, nodeExtent, node.measured, origin)
? clampPosition(internals.positionAbsolute, nodeExtent, node.measured)
: internals.positionAbsolute;
const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;

View File

@@ -278,15 +278,10 @@ const createStore = ({
triggerEdgeChanges(edgeChanges);
},
setNodeExtent: (nodeExtent) => {
const { nodeLookup, nodeOrigin } = get();
const { nodeLookup } = get();
for (const [, node] of nodeLookup) {
const positionAbsolute = clampPosition(
node.internals.positionAbsolute,
nodeExtent,
node.measured,
node.origin ?? nodeOrigin
);
const positionAbsolute = clampPosition(node.internals.positionAbsolute, nodeExtent, node.measured);
nodeLookup.set(node.id, {
...node,

View File

@@ -19,17 +19,16 @@ export const clamp = (val: number, min = 0, max = 1): number => Math.min(Math.ma
export const clampPosition = (
position: XYPosition = { x: 0, y: 0 },
extent: CoordinateExtent,
dimensions: Partial<Dimensions>,
origin: NodeOrigin
dimensions: Partial<Dimensions>
) => ({
x: clamp(position.x, extent[0][0], extent[1][0] - (dimensions?.width ?? 0) * origin[0]),
y: clamp(position.y, extent[0][1], extent[1][1] - (dimensions?.height ?? 0) * origin[1]),
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)),
});
/**
* Calculates the velocity of panning when the mouse is close to the edge of the canvas
* @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 max - Maximal position on canvas before panning starts
* @returns - A number between 0 and 1 that represents the velocity of panning

View File

@@ -276,24 +276,6 @@ export async function fitView<Params extends FitViewParamsBase<NodeBase>, Option
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.
*
@@ -318,40 +300,37 @@ export function calculateNodePosition<NodeType extends NodeBase>({
const node = nodeLookup.get(nodeId)!;
const parentNode = node.parentId ? nodeLookup.get(node.parentId) : undefined;
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 (!parentNode) {
onError?.('005', errorMessages['error005']());
} else {
const nodeWidth = node.measured.width;
const nodeHeight = node.measured.height;
const parentWidth = parentNode.measured.width;
const parentHeight = parentNode.measured.height;
if (nodeWidth && nodeHeight && parentWidth && parentHeight) {
currentExtent = [
if (parentWidth && parentHeight) {
extent = [
[parentX, parentY],
[parentX + parentWidth - nodeWidth, parentY + parentHeight - nodeHeight],
[parentX + parentWidth, parentY + parentHeight],
];
}
}
} else if (parentNode && isCoordinateExtent(node.extent)) {
currentExtent = [
extent = [
[node.extent[0][0] + parentX, node.extent[0][1] + parentY],
[node.extent[1][0] + parentX, node.extent[1][1] + parentY],
];
}
const positionAbsolute = isCoordinateExtent(currentExtent)
? clampPosition(nextPosition, currentExtent, node.measured, origin)
const positionAbsolute = isCoordinateExtent(extent)
? clampPosition(nextPosition, extent, node.measured)
: nextPosition;
return {
position: {
// TODO: is there a better way to do this?
x: positionAbsolute.x - parentX + node.measured.width! * origin[0],
y: positionAbsolute.y - parentY + node.measured.height! * origin[1],
},