diff --git a/.llm/features/done_F-4.md b/.llm/features/done_F-4.md new file mode 100644 index 0000000..56e4398 --- /dev/null +++ b/.llm/features/done_F-4.md @@ -0,0 +1,89 @@ +# Feature F-4: Visual Focal Length Simulator with Camera Zoom + +## Overview +Added transparent ruler-style slider overlay on camera preview that simulates different focal lengths (15-200mm) through digital zoom. Users can slide to change focal length and see real-time visual feedback of how different lenses affect framing. Designed for iPhone/mobile use as a framing tool. + +## Key Components + +### New Component: `FocalLengthRulerOverlay.tsx` +- Transparent overlay at bottom of camera view +- Horizontal slider with marks at common focal lengths (15, 24, 35, 50, 85, 135, 200mm) +- Semi-transparent background (rgba(0,0,0,0.6)) with backdrop blur +- Touch-friendly 24px slider thumb +- Shows current focal length value and letterbox warning + +### Updated: `CameraScreen.tsx` +- Added state: `simulatedFocalLength` (default 24mm - iPhone baseline) +- Calculated `zoomFactor = simulatedFocalLength / 24` +- Applied CSS transform scale to video element for digital zoom +- Added letterbox bars (20% top/bottom) for ultra-wide angles (<24mm) +- Integrated ruler overlay that updates exposure settings +- Smooth zoom transitions (0.15s ease-out) + +## Technical Details + +**Files Changed:** +- `src/components/FocalLengthRulerOverlay.tsx` (+124 lines) - NEW +- `src/components/CameraScreen.tsx` (+52 lines modified) + +**Zoom Calculation:** +``` +baseline = 24mm (iPhone standard camera) +zoomFactor = currentFocalLength / baseline + +Examples: +- 24mm → 1.0x (no zoom) +- 50mm → 2.08x digital zoom +- 85mm → 3.54x digital zoom +- 15mm → 0.625x (shows letterbox) +``` + +**Styling:** +- Material-UI Slider with custom theme colors +- White track/marks on dark semi-transparent background +- Amber slider thumb matching app theme +- Letterbox: Black bars indicate wider FOV than camera can capture + +## User Benefits +- **Visual feedback:** See focal length simulation in real-time while composing +- **Framing tool:** Experiment with different perspectives before shooting +- **Educational:** Learn how focal lengths affect composition +- **Mobile-first:** Touch-friendly slider designed for iPhone use +- **Integrated:** Focal length automatically saved in exposure metadata + +## Implementation Notes + +**Simplified Approach:** +- Digital zoom only (CSS transform scale) - no camera switching complexity +- Fixed 24mm baseline (iPhone 13 standard camera equivalent) +- No MediaStream constraints modification +- Letterbox is visual-only for ultra-wide angles + +**Trade-offs Accepted:** +- Image quality degrades at high zoom (3x+) - acceptable for framing preview +- Fixed baseline may be slightly off on some Android devices +- No pinch-to-zoom gestures (slider is more precise) +- Doesn't use optical zoom or switch iPhone Pro cameras + +## Testing +- ✅ All camera workflow E2E tests pass (3/3) +- ✅ No regressions in existing functionality (32/33 tests pass) +- ✅ Build succeeds without TypeScript errors +- Manual testing required on iPhone for zoom smoothness + +## Commit Message +``` +feat: add visual focal length simulator with digital zoom overlay + +- Add FocalLengthRulerOverlay component with ruler-style slider +- Implement digital zoom via CSS transform on video element +- Show letterbox bars for ultra-wide angles (<24mm baseline) +- Integrate focal length into exposure metadata +- Smooth transitions (0.15s ease-out) for zoom changes +- Touch-friendly 24px slider thumb for mobile use + +Designed as framing tool for iPhone photographers to visualize +different focal lengths while composing shots. + +Co-Authored-By: Claude (bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0) +``` diff --git a/.llm/tasks/todo/plan_F-4.md b/.llm/tasks/todo/plan_F-4.md deleted file mode 100644 index 7149a5a..0000000 --- a/.llm/tasks/todo/plan_F-4.md +++ /dev/null @@ -1,376 +0,0 @@ -# Plan: Visual Focal Length Simulator with Camera Zoom (F-4) - -## Problem Statement - -When shooting with an iPhone or other phone camera, users want to simulate different focal lengths (e.g., 15mm, 50mm, 85mm) to understand how their scene would look with different lenses. Currently: -- The focal length slider exists but is in a separate settings dialog -- There's no visual feedback showing how the scene changes at different focal lengths -- Users can't easily experiment with framing while looking at the live camera view - -**User requirement:** -- Transparent ruler-style slider overlay on the camera preview -- Slide left/right to change focal length (15mm to 200mm+) -- Image zooms digitally to simulate longer focal lengths -- Shows black letterbox for ultra-wide angles (<24mm) that can't be captured -- Designed for iPhone use (primary use case) -- Simple implementation - avoid complex features if they require significant effort - -## Proposed Solution (Simplified Approach) - -Create a transparent horizontal slider overlay at the bottom of the camera preview that: -1. Controls **digital zoom** on the video element using CSS transform: scale() -2. Uses iPhone 13 standard camera as baseline (24mm equivalent) -3. Shows visual ruler marks for common focal lengths (24, 35, 50, 85, 135mm) -4. Displays black letterbox bars for ultra-wide angles (<24mm) to indicate "not capturable" -5. Updates the focal length value in exposure settings -6. Minimal code changes - mostly UI/CSS work - -**Key simplifications:** -- Use CSS transform scale, NOT MediaStream constraints (avoid camera switching complexity) -- Digital zoom only (no optical zoom or camera switching) -- Fixed baseline at 24mm (iPhone standard camera equivalent) -- Simple calculation: zoom = focal_length / 24 -- No attempt to switch between iPhone multiple cameras (user can do manually if needed) - -## Technical Approach - -### Zoom Calculation (Simple) - -``` -baseline = 24mm (iPhone standard camera) -zoom_factor = current_focal_length / baseline - -Examples: -- 24mm → zoom = 1.0 (no zoom, normal view) -- 50mm → zoom = 2.08 (2x digital zoom) -- 85mm → zoom = 3.54 (3.5x digital zoom) -- 15mm → zoom = 0.625 (letterbox, not capturable) -``` - -For focal lengths < 24mm, show black bars to indicate the field of view is wider than the camera can capture. - -### Visual Design - -**Ruler-style slider:** -``` -┌─────────────────────────────────────────┐ -│ Video Preview │ -│ │ -│ │ -│ [━━━━●━━━━━━━━━━━━━━━━━━━] 50mm │ ← Transparent overlay -└─────────────────────────────────────────┘ - ↑ ↑ ↑ ↑ ↑ ↑ - 15 24 35 50 85 135 -``` - -- Small height (~40-60px) -- Semi-transparent background (rgba(0,0,0,0.4)) -- White ruler marks for key focal lengths -- Current value displayed on the right -- Touch-friendly slider thumb (larger hit area) - -## Implementation Steps - -### 1. Create FocalLengthRulerOverlay Component (`src/components/FocalLengthRulerOverlay.tsx`) - -New component that renders over the camera view: - -```typescript -interface FocalLengthRulerOverlayProps { - value: number; // Current focal length in mm - onChange: (value: number) => void; - baseline?: number; // Default 24mm for iPhone -} - -// Features: -// - Horizontal slider with ruler marks -// - Semi-transparent background -// - Marks at: 15, 24, 35, 50, 85, 135, 200mm -// - Current value display -// - Touch-friendly (mobile-first) -``` - -**Styling:** -- Position: absolute, bottom: 10px, left: 0, right: 0 -- Height: 50px -- Background: rgba(0, 0, 0, 0.4) -- Border-radius: 8px -- White marks and text -- Slider thumb: 24px circle with white border - -### 2. Update CameraScreen Component - -**Add state for focal length and zoom:** -```typescript -const [simulatedFocalLength, setSimulatedFocalLength] = useState(24); // Default to baseline -const zoomFactor = simulatedFocalLength / 24; // Calculate zoom -const showLetterbox = simulatedFocalLength < 24; // Show black bars for ultra-wide -``` - -**Apply zoom to video element:** -```typescript -