4.1 KiB
4.1 KiB
Design Document: Minimap Feature Specification
Overview
The minimap provides a bird's-eye overview of all krates' positions on the canvas. It allows navigation by clicking to fly the camera to any location.
Position & Size
Placement
- Position:
absolute; right: 18px; bottom: 64px(above zoom pill) - Size: 180×120px
- Z-index: Must be above canvas but below spotlight (z-index: 20-30 range)
Background
- Base:
rgba(16,20,28,.97) - Border:
1px solid rgba(140,165,200,.2) - Border-radius:
4px - Padding: None (full content area)
Viewport Indicator
Rectangle
- Shows current camera view frustum
- Position: Relative to minimap content (proportionally mapped)
- Size: Proportional to zoom level
- Color: Accent (e.g.,
#4dd6e8cyan) with 40% opacity - Stroke: Solid line, 1px
Mapping
- World position (wx, wy) → Minimap coordinates
- Formula:
mx = (wx + camX) / zoom scaling factor my = (wy + camY) / zoom scaling factor - Zoom mapping: Larger viewport indicator = lower zoom level
Krate Visualization
Representation
- Each krate = small rectangle (8×6px default)
- Color: Matches krate's namespace color
- Position: Relative to minimap origin
- Scaled down: ~1/60th of world space
Content
- Krate positions only (not internal windows)
- All active krates on canvas
- Update on: krate create, delete, move
Performance Optimization
- Only render visible krates (cull distant ones)
- Batch updates (throttle minimap render)
- Use CSS transform, not re-layout
Interaction
Click Navigation
- Click anywhere → fly camera to world position
- Calculate world coordinates from click position:
worldX = (clickX / minimapWidth) * worldWidth - viewportWidth/2 worldY = (clickY / minimapHeight) * worldHeight - viewportHeight/2 - Animate camera fly:
.52s cubic-bezier(.22,.8,.28,1) - Zoom: Set to
0.92or user's preferred zoom
Hover Effects (Optional)
- Hover krate rectangle → highlight preview on canvas
- Show tooltip: krate name, window count
Canvas Synchronization
Updates Triggered By
- New krate creation
- Krate movement (drag)
- Krate deletion
- Canvas resize (re-calculate scale)
- Camera change (update viewport indicator)
Throttling
- Debounce minimap render: 100ms
- Don't update on every pixel of drag
- Batch: Collect all krate changes, render once
Visual Styling
Krate Rectangles
- Size: 8×6px (small but visible)
- Color: Krate's namespace color
- Fill: Solid
- Border: None (or very subtle: rgba(255,255,255,.1))
Viewport Indicator
- Fill: None
- Stroke:
#4dd6e8(accent), 1px - Opacity: 0.4
- Rounded corners: 2px
Background Patterns (Optional)
- Subtle grid overlay (same as main canvas, fainter)
- Stars or dots for visual interest
- Very low opacity: rgba(255,255,255,.05)
Coordinate Mapping
World to Minimap
minimapScale = minimapWidth / worldWidth (e.g., 180 / 12000 = 0.015)
minimapX = (worldX + camX) * minimapScale
minimapY = (worldY + camY) * minimapScale
Minimap to World (for click)
worldX = (minimapX / minimapScale) - camX
worldY = (minimapY / minimapScale) - camY
Viewport Rect
viewportWidthWorld = viewportWidth / zoom
viewportHeightWorld = viewportHeight / zoom
viewportMinimapX = (camX * minimapScale)
viewportMinimapY = (camY * minimapScale)
viewportMinimapW = (viewportWidthWorld * minimapScale)
viewportMinimapH = (viewportHeightWorld * minimapScale)
Animation
Camera Fly
- Duration:
.52s - Easing:
cubic-bezier(.22,.8,.28,1) - Target: Center minimap-clicked position
- Zoom: Set to
0.92(or user preference)
Smooth Updates
- Smooth viewport indicator movement: CSS transition
- Avoid jitter during drag
- Use
requestAnimationFramefor updates
Gotchas
- Coordinate precision: Use floating-point for accurate mapping
- Zoom handling: Viewport indicator must scale inversely with zoom
- Performance: Minimap should never block main thread
- Culling: Don't render krates far outside view
- Click handling: Ensure click z-index > canvas but < spotlight
- Responsiveness: Recalculate mapping on window resize