Skip to content

Commit

Permalink
Initital attempt at drag to connect (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
TSKsmiley committed Feb 27, 2024
2 parents d28739f + 5837751 commit ea46815
Showing 1 changed file with 70 additions and 15 deletions.
85 changes: 70 additions & 15 deletions src/lib/components/Network.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
NONE,
DRAGGING,
PANNING,
CONNECTING,
}
const viewBox = {
Expand Down Expand Up @@ -49,6 +50,7 @@
onMount(() => {
if (!SVGContainer) return;
viewBox.width = SVGContainer.getBoundingClientRect().width;
viewBox.height = SVGContainer.getBoundingClientRect().height;
});
Expand All @@ -66,7 +68,11 @@
if (targetId) {
selectedNode = $network.nodes.find((node) => node.id === targetId) || null;
if (selectedNode) {
if (!selectedNode) return;
if (event.shiftKey) {
interactionState = InteractionState.CONNECTING;
} else {
initialMouse.x = selectedNode.x;
initialMouse.y = selectedNode.y;
interactionState = InteractionState.DRAGGING;
Expand All @@ -80,8 +86,31 @@
}
function handlePointerUp(event: PointerEvent) {
if (!(event.target instanceof Element)) return;
event.preventDefault();
if (interactionState === InteractionState.CONNECTING && selectedNode) {
const element = document.elementFromPoint(event.clientX, event.clientY);
const targetId = element?.tagName === "circle" ? element.id : null;
if (
targetId &&
targetId !== selectedNode.id &&
!$network.connections.some(
(connection) =>
(connection.source === selectedNode?.id && connection.target === targetId) ||
(connection.source === targetId && connection.target === selectedNode?.id),
)
) {
$network.connections = [
...$network.connections,
{ source: selectedNode.id, target: targetId },
];
}
}
interactionState = InteractionState.NONE;
selectedNode = null;
Expand All @@ -103,9 +132,12 @@
$network.nodes = $network.nodes;
} else if (interactionState === InteractionState.PANNING) {
mouse.x = event.clientX;
mouse.y = event.clientY;
viewBox.x -= delta.x;
viewBox.y -= delta.y;
} else if (interactionState === InteractionState.CONNECTING) {
mouse.x = event.clientX;
mouse.y = event.clientY;
}
Expand Down Expand Up @@ -137,6 +169,23 @@
viewBox.height *= zoomFactor;
}
function handleDrop(event: DragEvent) {
event.preventDefault();
const data = parseInt(event.dataTransfer?.getData("text/plain") ?? "0");
if (!isNodeType(data)) return;
if (!SVGContainer) return;
const newNode: Node = {
id: Math.random().toString(36).substring(7),
label: "L",
...scaledMousePosition(event.clientX, event.clientY),
type: data,
};
$network.nodes = [...$network.nodes, newNode];
}
function getCoordinates(connection: Connection) {
const source = $network.nodes.find((node) => node.id === connection.source);
const target = $network.nodes.find((node) => node.id === connection.target);
Expand All @@ -151,22 +200,20 @@
};
}
function handleDrop(event: DragEvent) {
event.preventDefault();
function scaledMousePosition(x: number, y: number) {
if (!SVGContainer) return { x, y };
const data = parseInt(event.dataTransfer?.getData("text/plain") ?? "0");
if (!isNodeType(data)) return;
if (!SVGContainer) return;
return {
x: (x - SVGContainer.getBoundingClientRect().left) * viewBox.scale + viewBox.x,
y: (y - SVGContainer.getBoundingClientRect().top) * viewBox.scale + viewBox.y,
};
}
const newNode: Node = {
id: Math.random().toString(36).substring(7),
label: "L",
x: (event.clientX - SVGContainer.getBoundingClientRect().left) * viewBox.scale + viewBox.x,
y: (event.clientY - SVGContainer.getBoundingClientRect().top) * viewBox.scale + viewBox.y,
type: data,
function transformToLineDestination(origin: { x: number; y: number }) {
return {
x2: origin.x,
y2: origin.y,
};
$network.nodes = [...$network.nodes, newNode];
}
</script>

Expand All @@ -185,6 +232,14 @@
{#each $network.connections as connection}
<line {...getCoordinates(connection)} stroke="black" />
{/each}
{#if interactionState === InteractionState.CONNECTING && selectedNode}
<line
x1={selectedNode.x}
y1={selectedNode.y}
{...transformToLineDestination(scaledMousePosition(mouse.x, mouse.y))}
stroke="black"
/>
{/if}
{#each $network.nodes as node}
<circle id={node.id} cx={node.x} cy={node.y} r="20" fill={nodeColors[node.type]} />
<text x={node.x} y={node.y} text-anchor="middle" alignment-baseline="middle"
Expand Down

0 comments on commit ea46815

Please sign in to comment.