feat: better handle camera positioning
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Edge, NodeInstance } from "@nodarium/types";
|
import type { Edge, NodeInstance } from "@nodarium/types";
|
||||||
import { onMount } from "svelte";
|
|
||||||
import { createKeyMap } from "../../helpers/createKeyMap";
|
import { createKeyMap } from "../../helpers/createKeyMap";
|
||||||
import AddMenu from "../components/AddMenu.svelte";
|
import AddMenu from "../components/AddMenu.svelte";
|
||||||
import Background from "../background/Background.svelte";
|
import Background from "../background/Background.svelte";
|
||||||
@@ -93,15 +92,6 @@
|
|||||||
graphState.activeSocket = null;
|
graphState.activeSocket = null;
|
||||||
graphState.addMenuPosition = null;
|
graphState.addMenuPosition = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
if (localStorage.getItem("cameraPosition")) {
|
|
||||||
const cPosition = JSON.parse(localStorage.getItem("cameraPosition")!);
|
|
||||||
if (Array.isArray(cPosition)) {
|
|
||||||
graphState.setCameraTransform(cPosition[0], cPosition[1], cPosition[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window
|
<svelte:window
|
||||||
|
|||||||
@@ -455,7 +455,8 @@ export class MouseEventManager {
|
|||||||
this.state.cameraDown[1] -
|
this.state.cameraDown[1] -
|
||||||
(my - this.state.mouseDown[1]) / this.state.cameraPosition[2];
|
(my - this.state.mouseDown[1]) / this.state.cameraPosition[2];
|
||||||
|
|
||||||
this.state.setCameraTransform(newX, newY);
|
this.state.cameraPosition[0] = newX;
|
||||||
|
this.state.cameraPosition[1] = newY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -486,15 +487,13 @@ export class MouseEventManager {
|
|||||||
const zoomRatio = newZoom / this.state.cameraPosition[2];
|
const zoomRatio = newZoom / this.state.cameraPosition[2];
|
||||||
|
|
||||||
// Update camera position and zoom level
|
// Update camera position and zoom level
|
||||||
this.state.setCameraTransform(
|
this.state.cameraPosition[0] = this.state.mousePosition[0] -
|
||||||
this.state.mousePosition[0] -
|
|
||||||
(this.state.mousePosition[0] - this.state.cameraPosition[0]) /
|
(this.state.mousePosition[0] - this.state.cameraPosition[0]) /
|
||||||
zoomRatio,
|
zoomRatio;
|
||||||
this.state.mousePosition[1] -
|
this.state.cameraPosition[1] = this.state.mousePosition[1] -
|
||||||
(this.state.mousePosition[1] - this.state.cameraPosition[1]) /
|
(this.state.mousePosition[1] - this.state.cameraPosition[1]) /
|
||||||
zoomRatio,
|
zoomRatio,
|
||||||
newZoom,
|
this.state.cameraPosition[2] = newZoom;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,24 @@ export function setGraphManager(manager: GraphManager) {
|
|||||||
|
|
||||||
export class GraphState {
|
export class GraphState {
|
||||||
|
|
||||||
constructor(private graph: GraphManager) { }
|
constructor(private graph: GraphManager) {
|
||||||
|
$effect.root(() => {
|
||||||
|
$effect(() => {
|
||||||
|
localStorage.setItem("cameraPosition", `[${this.cameraPosition[0]},${this.cameraPosition[1]},${this.cameraPosition[2]}]`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
const storedPosition = localStorage.getItem("cameraPosition")
|
||||||
|
if (storedPosition) {
|
||||||
|
try {
|
||||||
|
const d = JSON.parse(storedPosition);
|
||||||
|
this.cameraPosition[0] = d[0];
|
||||||
|
this.cameraPosition[1] = d[1];
|
||||||
|
this.cameraPosition[2] = d[2];
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Failed to parsed stored camera position", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
width = $state(100);
|
width = $state(100);
|
||||||
height = $state(100);
|
height = $state(100);
|
||||||
@@ -80,28 +97,7 @@ export class GraphState {
|
|||||||
|
|
||||||
isBodyFocused = () => document?.activeElement?.nodeName !== "INPUT";
|
isBodyFocused = () => document?.activeElement?.nodeName !== "INPUT";
|
||||||
|
|
||||||
setCameraTransform(
|
|
||||||
x = this.cameraPosition[0],
|
|
||||||
y = this.cameraPosition[1],
|
|
||||||
z = this.cameraPosition[2],
|
|
||||||
) {
|
|
||||||
if (this.camera) {
|
|
||||||
this.camera.position.x = x;
|
|
||||||
this.camera.position.z = y;
|
|
||||||
this.camera.zoom = z;
|
|
||||||
}
|
|
||||||
this.cameraPosition = [x, y, z];
|
|
||||||
localStorage.setItem("cameraPosition", JSON.stringify(this.cameraPosition));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
updateNodePosition(node: NodeInstance) {
|
updateNodePosition(node: NodeInstance) {
|
||||||
if (node.state.ref && node.state.mesh) {
|
|
||||||
if (node.state["x"] !== undefined && node.state["y"] !== undefined) {
|
|
||||||
node.state.ref.style.setProperty("--nx", `${node.state.x * 10}px`);
|
|
||||||
node.state.ref.style.setProperty("--ny", `${node.state.y * 10}px`);
|
|
||||||
node.state.mesh.position.x = node.state.x + 10;
|
|
||||||
node.state.mesh.position.z = node.state.y + this.getNodeHeight(node.type) / 2;
|
|
||||||
if (
|
if (
|
||||||
node.state.x === node.position[0] &&
|
node.state.x === node.position[0] &&
|
||||||
node.state.y === node.position[1]
|
node.state.y === node.position[1]
|
||||||
@@ -109,13 +105,16 @@ export class GraphState {
|
|||||||
delete node.state.x;
|
delete node.state.x;
|
||||||
delete node.state.y;
|
delete node.state.y;
|
||||||
}
|
}
|
||||||
this.graph.edges = [...this.graph.edges];
|
|
||||||
|
if (node.state["x"] !== undefined && node.state["y"] !== undefined) {
|
||||||
|
if (node.state.ref) {
|
||||||
|
node.state.ref.style.setProperty("--nx", `${node.state.x * 10}px`);
|
||||||
|
node.state.ref.style.setProperty("--ny", `${node.state.y * 10}px`);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (node.state.ref) {
|
||||||
node.state.ref.style.setProperty("--nx", `${node.position[0] * 10}px`);
|
node.state.ref.style.setProperty("--nx", `${node.position[0] * 10}px`);
|
||||||
node.state.ref.style.setProperty("--ny", `${node.position[1] * 10}px`);
|
node.state.ref.style.setProperty("--ny", `${node.position[1] * 10}px`);
|
||||||
node.state.mesh.position.x = node.position[0] + 10;
|
|
||||||
node.state.mesh.position.z =
|
|
||||||
node.position[1] + this.getNodeHeight(node.type) / 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,11 +88,9 @@ export function setupKeymaps(keymap: Keymap, graph: GraphManager, graphState: Gr
|
|||||||
const ease = (t: number) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t);
|
const ease = (t: number) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t);
|
||||||
|
|
||||||
animate(500, (a: number) => {
|
animate(500, (a: number) => {
|
||||||
graphState.setCameraTransform(
|
graphState.cameraPosition[0] = lerp(camX, average[0], ease(a));
|
||||||
lerp(camX, average[0], ease(a)),
|
graphState.cameraPosition[1] = lerp(camY, average[1], ease(a));
|
||||||
lerp(camY, average[1], ease(a)),
|
graphState.cameraPosition[2] = lerp(camZ, 2, ease(a))
|
||||||
lerp(camZ, 2, ease(a)),
|
|
||||||
);
|
|
||||||
if (graphState.mouseDown) return false;
|
if (graphState.mouseDown) return false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user