fixed node extent calculation and simplified calculateNodePosition
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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],
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user