fix(edges): use derived store for edge handling

This commit is contained in:
moklick
2023-02-01 15:25:14 +01:00
parent 2af833aee1
commit 71bd05b7e7
10 changed files with 243 additions and 215 deletions
@@ -0,0 +1,28 @@
<script lang="ts">
import Edge from '$lib/components/edges/BaseEdge.svelte';
import { useStore } from '$lib/store';
const { edgesWithDataStore, widthStore, heightStore } = useStore();
</script>
<svg
width={$widthStore}
height={$heightStore}
class="react-flow__edges react-flow__container"
>
{#each $edgesWithDataStore as edge}
<Edge {...edge} />
{/each}
</svg>
<style>
.react-flow__edges {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
pointer-events: none;
overflow: visible;
}
@@ -0,0 +1,105 @@
import {
type NodeHandleBounds,
type Rect,
type Node,
type HandleElement,
type XYPosition,
Position,
internalsSymbol
} from '@reactflow/core';
export function getNodeData(node?: Node): [Rect, NodeHandleBounds | null, boolean] {
const handleBounds = node?.[internalsSymbol]?.handleBounds || null;
const isValid =
handleBounds &&
node?.width &&
node?.height &&
typeof node?.positionAbsolute?.x !== 'undefined' &&
typeof node?.positionAbsolute?.y !== 'undefined';
return [
{
x: node?.positionAbsolute?.x || 0,
y: node?.positionAbsolute?.y || 0,
width: node?.width || 0,
height: node?.height || 0
},
handleBounds,
!!isValid
];
}
export function getHandlePosition(
position: Position,
nodeRect: Rect,
handle: HandleElement | null = null
): XYPosition {
const x = (handle?.x || 0) + nodeRect.x;
const y = (handle?.y || 0) + nodeRect.y;
const width = handle?.width || nodeRect.width;
const height = handle?.height || nodeRect.height;
switch (position) {
case Position.Top:
return {
x: x + width / 2,
y
};
case Position.Right:
return {
x: x + width,
y: y + height / 2
};
case Position.Bottom:
return {
x: x + width / 2,
y: y + height
};
case Position.Left:
return {
x,
y: y + height / 2
};
}
}
export function getHandle(bounds: HandleElement[], handleId?: string | null): HandleElement | null {
if (!bounds) {
return null;
}
if (handleId) {
return bounds.find((d) => d.id === handleId)!;
} else if (bounds.length === 1) {
return bounds[0];
}
return null;
}
export type EdgePosition = {
sourceX: number;
sourceY: number;
targetX: number;
targetY: number;
};
export function getEdgePositions(
sourceNodeRect: Rect,
sourceHandle: HandleElement,
sourcePosition: Position,
targetNodeRect: Rect,
targetHandle: HandleElement,
targetPosition: Position
): EdgePosition {
const sourceHandlePos = getHandlePosition(sourcePosition, sourceNodeRect, sourceHandle);
const targetHandlePos = getHandlePosition(targetPosition, targetNodeRect, targetHandle);
return {
sourceX: sourceHandlePos.x,
sourceY: sourceHandlePos.y,
targetX: targetHandlePos.x,
targetY: targetHandlePos.y
};
}