Files
Hermes Agent 78f19cde7d feat: Add comprehensive design documentation for Krates
- Canvas: Infinite zoomable workspace with LOD and navigation
- Spotlight: Fuzzy search with type filters and view shortcuts
- Krate: Window group container with non-overlapping placement
- Detail Window: YAML/Describe/Logs/Shell views with maximize
- Top Bar: Cluster info, user presence, admin toggle
- Admin Drawer: Multi-user presence and spectate functionality
- Minimap: Browse and navigate canvas overview
- Collection Window: List/tree views with filtering and sorting
- Shell/Logs: Real-time terminal and log streaming
- Backend: Go service with K8s API, WebSocket handlers, CRDT sync
- Architecture: Full project structure and tech stack
2026-06-16 08:32:47 -04:00

3.9 KiB
Raw Permalink Blame History

Canvas Feature Specification

Overview

The canvas is the infinite zoomable/pannable workspace where krates live. It serves as the primary interaction surface for exploring Kubernetes clusters.

Core Responsibilities

  • Render an infinite 2D workspace (12000×8000px world)
  • Handle camera navigation (pan/zoom)
  • Manage Level of Detail (LOD) based on zoom level
  • Display a CAD grid overlay
  • Coordinate global interactions (space panning, spotlight trigger)

Technical Requirements

Viewport & World Layer

  • Full viewport (position: fixed; inset: 0)
  • Background color: #0b0e13
  • World layer: 12000×8000px div transformed via translate(camX, camY) scale(zoom)
  • All krates/windows are absolutely positioned children

Grid Overlay (CSS background-image)

  • Fine grid: 34px spacing, rgba(125,145,175,.04)
  • Coarse grid: 170px spacing, rgba(125,145,175,.075)
  • Both X and Y repeating linear gradients

Camera State

interface CanvasState {
  camX: number;       // world-to-screen X offset
  camY: number;       // world-to-screen Y offset
  zoom: number;       // 0.16  2.2; default 0.92
  flying: boolean;    // true during animated camera transitions
  dragging: boolean;  // true during pan drag
  collapsed: boolean; // LOD: true when zoom < 0.4
  spacePanning: boolean; // true while space is held
}

Navigation

Scroll Wheel

  • ** Default **: Pan canvas
  • ** Ctrl/⌘ + scroll **: Zoom canvas (intercepted via wheel event with e.ctrlKey || e.metaKey)

Space + Drag Panning

  • Critical: must work even when shell window has keyboard focus
  • Implementation:
    • document.addEventListener('keydown', handler, { capture: true }) on space
    • Set "panning" flag, prevent default on body
    • Forward mousemove to canvas pan handler
    • Release on keyup for space
    • Do NOT use e.stopPropagation() - allow event propagation

Click/Typed Key Triggers

  • ** Click on empty canvas **: Open spotlight
  • ** Type any key **: Open spotlight with that character pre-seeded

Zoom Levels / LOD

  • ** zoom > 0.5 **: Normal view — krates expanded, all windows visible, draggable
  • ** zoom < 0.4 **: Collapsed view — krates become 230px wide overview cards, no windows rendered
  • ** Hysteresis**: Collapse at 0.4, re-expand at 0.5 (prevents flickering)

Animations

  • CSS transform with transition only for programmatic "fly" animations: .52s cubic-bezier(.22,.8,.28,1)
  • During user scroll/drag: transition: none for immediacy

UI Components

Top Bar

  • Position: absolute; top: 0; left: 0; right: 0; z-index: 10; height ~56px
  • Layout: display: flex; align-items: center; padding: 13px 18px
  • Background: none (transparent)
  • Left side: Logo pill, cluster pill, krate count pill
  • Right side: Synced pill, admin button, roster avatars

Bottom Hint Bar

  • Position: absolute; right: 18px; bottom: 18px
  • Shows keyboard hints (status bar)

Zoom Pill

  • Position: absolute; left: 18px; bottom: 18px
  • Displays current zoom percentage

Minimap

  • Position: absolute; right: 18px; bottom: 64px
  • Size: 180×120px
  • Shows all krates as small rectangles
  • Viewport indicator rectangle showing current view frustum
  • Click anywhere to fly camera to that world position

Interaction Summary

Interaction Behavior
Scroll wheel Pan canvas
Ctrl/⌘ + scroll Zoom canvas
Space + drag Pan canvas (even over windows/shells)
Click empty canvas Open spotlight
Type any key Open spotlight pre-seeded
Minimap click Fly camera to position

Gotchas

  1. Space pan over shells: Must intercept with { capture: true }, prevent default, but don't stop propagation
  2. Ctrl/⌘+scroll: Use { capture: true } on canvas wheel handler to intercept before window scroll containers
  3. Camera transitions: Only animate during programmatic fly, not user gestures
  4. LOD state: Use stable boolean collapsed in state, not derived from zoom on every render