lofivor/docs/plans/2025-12-16-zoom-pan-design.md
2025-12-16 14:35:24 -05:00

54 lines
1.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Zoom/Pan Camera Design
A viewport camera for zooming into and panning around the simulation without affecting entity behavior.
## Core Behavior
### Zoom
- Scroll wheel zooms toward mouse cursor position
- Range: 1x (default floor) to 10x (ceiling)
- Instant response, no animation
- Esc or Space resets to 1x and clears pan offset
### Pan
- Any mouse button (left/middle/right) + drag pans the viewport
- Only available when zoom > 1x
- Bounded to simulation area - cannot pan into empty space
### UI
- Display current zoom level in existing panel under render info (e.g., `zoom: 2.3x`)
## Implementation Approach
### State
New camera state in `sandbox_main.zig`:
```zig
var zoom: f32 = 1.0;
var pan: @Vector(2, f32) = .{ 0, 0 };
```
### Shader Changes
Modify `entity.vert` to accept `zoom` and `pan` uniforms:
- Apply pan offset before converting to NDC
- Scale by zoom factor
- Scale quad size by zoom so entities appear larger
### Input Handling
- `getMouseWheelMove()` adjusts zoom (clamped 1.010.0)
- Zoom-toward-cursor: adjust pan to keep point under cursor stationary
- Mouse drag (any button) adjusts pan with bounds checking
- Esc/Space resets zoom to 1.0 and pan to (0, 0)
### Zoom-Toward-Cursor Math
When zooming from `oldZoom` to `newZoom` with cursor at `mousePos`:
```
worldMousePos = (mousePos / oldZoom) + pan
newPan = worldMousePos - (mousePos / newZoom)
```
### Pan Bounds
Constrain pan so viewport stays within simulation area:
```
maxPan = simulationSize - (screenSize / zoom)
pan = clamp(pan, 0, maxPan)
```