Compare commits

..

2 Commits

Author SHA1 Message Date
Max Richter
a1ea56093c fix: correctly handle node wrapper resizing
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 1m57s
2025-12-01 19:48:40 +01:00
Max Richter
1850e21810 fix: make clipboard work 2025-12-01 19:30:44 +01:00
3 changed files with 28 additions and 28 deletions

View File

@@ -397,17 +397,17 @@ export class GraphManager extends EventEmitter<{
}
createNodeId() {
const max = Math.max(0, ...this.nodes.keys());
return max + 1;
return Math.max(0, ...this.nodes.keys()) + 1;
}
createGraph(nodes: Node[], edges: [number, number, number, string][]) {
// map old ids to new ids
const idMap = new Map<number, number>();
let startId = this.createNodeId()
nodes = nodes.map((node) => {
const id = this.createNodeId();
const id = startId++;
idMap.set(node.id, id);
const type = this.registry.getNode(node.type);
if (!type) {

View File

@@ -26,15 +26,16 @@ export class GraphState {
constructor(private graph: GraphManager) { }
cameraPosition: [number, number, number] = $state([0, 0, 4]);
wrapper = $state<HTMLDivElement>(null!);
width = $state(100);
height = $state(100);
wrapper = $state<HTMLDivElement>(null!);
rect: DOMRect = $derived(
this.wrapper ? this.wrapper.getBoundingClientRect() : new DOMRect(0, 0, 0, 0),
(this.wrapper && this.width && this.height) ? this.wrapper.getBoundingClientRect() : new DOMRect(0, 0, 0, 0),
);
width = $derived(this.rect?.width ?? 100);
height = $derived(this.rect?.height ?? 100);
camera = $state<OrthographicCamera>(null!);
cameraPosition: [number, number, number] = $state([0, 0, 4]);
clipboard: null | {
nodes: Node[];
@@ -192,43 +193,42 @@ export class GraphState {
copyNodes() {
if (this.activeNodeId === -1 && !this.selectedNodes?.size)
return;
let _nodes = [
let nodes = [
this.activeNodeId,
...(this.selectedNodes?.values() || []),
]
.map((id) => this.graph.getNode(id))
.filter(Boolean) as Node[];
.filter(b => !!b);
const _edges = this.graph.getEdgesBetweenNodes(_nodes);
_nodes = $state.snapshot(
_nodes.map((_node) => ({
..._node,
tmp: {
downX: this.mousePosition[0] - _node.position[0],
downY: this.mousePosition[1] - _node.position[1],
},
})),
);
const edges = this.graph.getEdgesBetweenNodes(nodes);
nodes = nodes.map((node) => ({
...node,
position: [
this.mousePosition[0] - node.position[0],
this.mousePosition[1] - node.position[1],
],
tmp: undefined,
}));
this.clipboard = {
nodes: _nodes,
edges: _edges,
nodes: nodes,
edges: edges,
};
}
pasteNodes() {
if (!this.clipboard) return;
const _nodes = this.clipboard.nodes
const nodes = this.clipboard.nodes
.map((node) => {
node.tmp = node.tmp || {};
node.position[0] = this.mousePosition[0] - (node?.tmp?.downX || 0);
node.position[1] = this.mousePosition[1] - (node?.tmp?.downY || 0);
node.position[0] = this.mousePosition[0] - node.position[0];
node.position[1] = this.mousePosition[1] - node.position[1];
return node;
})
.filter(Boolean) as Node[];
const newNodes = this.graph.createGraph(_nodes, this.clipboard.edges);
const newNodes = this.graph.createGraph(nodes, this.clipboard.edges);
this.selectedNodes.clear();
for (const node of newNodes) {
this.selectedNodes.add(node.id);

View File

@@ -37,14 +37,14 @@ export function setupKeymaps(keymap: Keymap, graph: GraphManager, graphState: Gr
key: "c",
ctrl: true,
description: "Copy active nodes",
callback: graphState.copyNodes,
callback: () => graphState.copyNodes(),
});
keymap.addShortcut({
key: "v",
ctrl: true,
description: "Paste nodes",
callback: graphState.pasteNodes,
callback: () => graphState.pasteNodes(),
});
keymap.addShortcut({