From 6fe3469bd64f7908db27e2ba89017b044b8ffb4b Mon Sep 17 00:00:00 2001 From: Shish Date: Mon, 21 Apr 2025 18:53:28 +0100 Subject: [PATCH] svg path render --- backend/web.rs | 9 ++++ src/routes/calc/path.tsx | 114 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/backend/web.rs b/backend/web.rs index f9f4ca5..24d01f8 100644 --- a/backend/web.rs +++ b/backend/web.rs @@ -133,6 +133,9 @@ fn calc_dist(db: &State, start: String, end: String) -> Result "jump".to_string(), @@ -198,6 +204,9 @@ fn calc_path( to: WebStar { id: conn.target, name: db.star_id_to_name[&conn.target].clone(), + x: from_star.x, + y: from_star.y, + z: from_star.z, }, }); last_id = conn.target; diff --git a/src/routes/calc/path.tsx b/src/routes/calc/path.tsx index 71ffdf0..514fa2b 100644 --- a/src/routes/calc/path.tsx +++ b/src/routes/calc/path.tsx @@ -13,12 +13,18 @@ type PathStep = { from: { name: string; id: string; + x: number; + y: number; + z: number; }; conn_type: ConnType; distance: number; to: { name: string; id: string; + x: number; + y: number; + z: number; }; }; @@ -71,6 +77,110 @@ function TextPath(props: { path: PathStep[] }) { ); } +function SvgPath(props: { path: PathStep[] }) { + function jump_color(conn_type: ConnType): string { + switch (conn_type) { + case "npc_gate": + return "green"; + case "smart_gate": + return "blue"; + case "jump": + return "orange"; + } + } + + let path_bounds = { + min_x: Infinity, + min_y: Infinity, + max_x: -Infinity, + max_y: -Infinity, + min_z: Infinity, + max_z: -Infinity, + }; + props.path.forEach((p) => { + path_bounds.min_x = Math.min(path_bounds.min_x, p.from.x, p.to.x); + path_bounds.min_y = Math.min(path_bounds.min_y, p.from.y, p.to.y); + path_bounds.max_x = Math.max(path_bounds.max_x, p.from.x, p.to.x); + path_bounds.max_y = Math.max(path_bounds.max_y, p.from.y, p.to.y); + path_bounds.min_z = Math.min(path_bounds.min_z, p.from.z, p.to.z); + path_bounds.max_z = Math.max(path_bounds.max_z, p.from.z, p.to.z); + }); + const content_width = path_bounds.max_x - path_bounds.min_x; + const content_height = path_bounds.max_z - path_bounds.min_z; + const margin = Math.max(content_width, content_height) * 0.1; + path_bounds = { + min_x: path_bounds.min_x - margin, + max_x: path_bounds.max_x + margin, + min_y: path_bounds.min_y - margin, + max_y: path_bounds.max_y + margin, + min_z: path_bounds.min_z - margin, + max_z: path_bounds.max_z + margin, + }; + + const width = path_bounds.max_x - path_bounds.min_x; + const height = path_bounds.max_z - path_bounds.min_z; + const scale = 1 / Math.max(width, height); + + const path2d: PathStep[] = props.path.map((n) => ({ + from: { + id: n.from.id, + name: n.from.name, + x: (n.from.x - path_bounds.min_x) * scale, + y: 1 - (n.from.z - path_bounds.min_z) * scale, + z: 0, + }, + conn_type: n.conn_type, + distance: n.distance, + to: { + id: n.to.id, + name: n.to.name, + x: (n.to.x - path_bounds.min_x) * scale, + y: 1 - (n.to.z - path_bounds.min_z) * scale, + z: 0, + }, + })); + + return ( + <> + + + {path2d.map((p, i) => { + const x1 = p.from.x * 1024; + const y1 = p.from.y * 1024; + const x2 = p.to.x * 1024; + const y2 = p.to.y * 1024; + return ( + + + + + {i == 0 ? ( + + {p.from.name} + + ) : null} + + {p.to.name} + + + ); + })} + + + ); +} + function PathFinder() { const [start, setStart] = useSessionStorage("start", "E.G1G.6GD"); const [end, setEnd] = useSessionStorage("end", "Nod"); @@ -87,11 +197,12 @@ function PathFinder() { const [path, setPath] = useState(null); const [error, setError] = useState(null); + /* useEffect(() => { setPath(null); setError(null); }, [start, end, jump, optimize]); - +*/ function submit(e: FormEvent) { e.preventDefault(); form_api(e.target as HTMLFormElement, 2, setPath, setError); @@ -181,6 +292,7 @@ function PathFinder() { + {path && } ); }