feat(v2): Phase 1 — map-first layout matching v1
Rebuilds the v1 map-centric experience in React: Layout: - 400px sidebar on left, interactive map on right (flex, 100vh) - Exact same proportions and dark theme as v1 Sidebar (top→bottom): - Header with active player count + Dashboard toggle button - Server status dot (Coldeve online/offline with pulse) - Aggregate counters: Rares (gold), Server KPH (blue glow), Kills (red) - 6 sort buttons (Name, KPH, S.Kills, S.Rares, T.Kills, KPR) - Player name filter - Scrollable player list with per-row: - Name + coordinates - HP/Stamina/Mana vital bars (red/orange/blue gradients) - Session kills, total kills, KPH - Session rares, total rares, VTank meta state pill - Online time, deaths, prismatic tapers - Color-coded left border per player Map: - dereth.png with CSS transform pan (drag) + zoom (wheel, 1.1x factor, max 20x) - Player dots (6px circles, color-matched to sidebar) - Hover tooltip (name, coords, kph, kills) - World coordinate display at cursor position - Fit-to-window on first load View toggle: Map View ↔ Dashboard with localStorage persistence. All v1 CSS ported under ml-* prefix, scoped via map-layout.css. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3791c01bf3
commit
2c4b8d3afb
16 changed files with 995 additions and 151 deletions
31
frontend/src/utils/coordinates.ts
Normal file
31
frontend/src/utils/coordinates.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Matches v1 script.js MAP_BOUNDS (UtilityBelt's coordinate system)
|
||||
export const MAP_BOUNDS = {
|
||||
west: -102.1,
|
||||
east: 102.1,
|
||||
north: 102.1,
|
||||
south: -102.1,
|
||||
};
|
||||
|
||||
export function worldToPx(ew: number, ns: number, imgW: number, imgH: number) {
|
||||
const x = ((ew - MAP_BOUNDS.west) / (MAP_BOUNDS.east - MAP_BOUNDS.west)) * imgW;
|
||||
const y = ((MAP_BOUNDS.north - ns) / (MAP_BOUNDS.north - MAP_BOUNDS.south)) * imgH;
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
export function pxToWorld(
|
||||
screenX: number, screenY: number,
|
||||
scale: number, offX: number, offY: number,
|
||||
imgW: number, imgH: number,
|
||||
) {
|
||||
const mapX = (screenX - offX) / scale;
|
||||
const mapY = (screenY - offY) / scale;
|
||||
const ew = MAP_BOUNDS.west + (mapX / imgW) * (MAP_BOUNDS.east - MAP_BOUNDS.west);
|
||||
const ns = MAP_BOUNDS.north - (mapY / imgH) * (MAP_BOUNDS.north - MAP_BOUNDS.south);
|
||||
return { ew, ns };
|
||||
}
|
||||
|
||||
export function formatCoord(ns: number, ew: number): string {
|
||||
const nsDir = ns >= 0 ? 'N' : 'S';
|
||||
const ewDir = ew >= 0 ? 'E' : 'W';
|
||||
return `${Math.abs(ns).toFixed(1)}${nsDir}, ${Math.abs(ew).toFixed(1)}${ewDir}`;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue