Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ src/screen-name/model/ ← application state
src/screen-name/view/ ← all UI components
```

**Model** (`src/screen-name/model/SimModel.ts`) holds every piece of reactive state as Axon `Property` objects (playback position, duration, overlay visibility, frame rate, model-view transform, tracks). `Track.ts` defines the track model (points, label, color). If you need a new piece of shared state, add it to `SimModel.ts`.
**Model** (`src/screen-name/model/`) holds all application state and pure computation logic. Key files:

| File | Responsibility |
|------|----------------|
| `SimModel.ts` | All reactive state as Axon `Property` objects (playback position, duration, overlay visibility, frame rate, model-view transform, tracks) |
| `Track.ts` | Track model — digitized points, label, color |
| `KinematicsComputer.ts` | Pure functions for computing velocity and acceleration from digitized points via finite differences |
| `ModelViewTransformFactory.ts` | Pure factory that builds the `Transform3` from coordinate-system pose and calibration data |

If you need a new piece of shared state, add it to `SimModel.ts`.

**View** (`src/screen-name/view/`) contains all SceneryStack nodes. Key files:

Expand All @@ -31,6 +40,10 @@ src/screen-name/view/ ← all UI components
| `KinematicsGraphNode.ts` | Configurable kinematics graph; wraps `ConfigurableGraph` with track and unit wiring |
| `TrackListPanel.ts` | Add/remove tracks for manual digitizing |
| `ControlPanel.ts` | Left-side toggle panel |
| `MeasurementToolsPanel.ts` | Checkboxes for measuring tape and angle tool overlays (shown when measurement tools preference is enabled) |
| `MeasuringTapeNode.ts` | Two-endpoint draggable tape overlay; displays real-world distance via model-view transform |
| `AngleToolNode.ts` | Three-handle draggable angle overlay; draws an arc and label at the vertex in degrees |
| `InfoDialogNode.ts` | Modal help dialog explaining digitizing steps; toggled by the info button |
| `WebcamPanel.ts` | Webcam recording dialog |
| `KeyboardShortcutsNode.ts` | Keyboard shortcuts |

Expand All @@ -40,15 +53,21 @@ src/screen-name/view/ ← all UI components
|------|----------------|
| `ConfigurableGraph.ts` | Top-level graph node; owns axis selectors, chart layout, and zoom/reset buttons |
| `GraphDataManager.ts` | Accumulates data points, owns auto-scaling and tick spacing |
| `GraphInteractionHandler.ts` | All pointer/touch/keyboard gestures — pan, pinch-zoom, axis drag, resize, header drag |
| `GraphInteractionHandler.ts` | Orchestrates all gesture handlers; owns shared chart config and exposes zoom/pan API |
| `PanGestureHandler.ts` | Mouse/touch drag on the chart area to pan both axes simultaneously |
| `ZoomGestureHandler.ts` | Mouse-wheel and pinch-to-zoom; preserves pointer/pinch center; double-click to reset |
| `AxisGestureHandler.ts` | Single-axis pan and zoom triggered by gestures on the axis labels |
| `ResizeGestureHandler.ts` | Corner drag handles that resize the graph panel |
| `HeaderDragHandler.ts` | Drag on the header bar to reposition the floating graph panel |
| `GraphControlsPanel.ts` | Axis property selector dropdowns (what to plot on each axis) |
| `PlottableProperty.ts` | `PlottableProperty` type — interface any quantity must satisfy to appear in the selector |
| `kinematics-plottable-properties.ts` | Canonical registry of all plottable quantities (position, velocity, acceleration, speed, time) |

> **Note:** `GraphInteractionHandler.ts` is the largest file in the codebase (~930 lines). When modifying gesture logic, read the existing `zoom()` / `pan()` / `rescaleAxes()` helpers before adding new code — many edge cases (pinch center preservation, manual-zoom locking, axis-specific gestures) are already handled.
> **Note:** Gesture logic is split across focused handler classes (`PanGestureHandler`, `ZoomGestureHandler`, `AxisGestureHandler`, `ResizeGestureHandler`, `HeaderDragHandler`). Read the relevant handler before adding new gesture code — many edge cases (pinch center preservation, manual-zoom locking, axis-specific gestures) are already handled.

The other source directories are less frequently modified:

- `src/preferences/` — User preferences (color profile, etc.)
- `src/preferences/` — User preferences: color profile, auto-tracking visibility, graph quantity visibility (`showVelocityInGraphProperty`, `showAccelerationInGraphProperty`), and measurement tools visibility (`enableMeasurementToolsProperty`)
- `src/tracking/` — OpenCV template-matching pipeline (touch only for tracking algorithm changes)
- `src/i18n/` — Localization strings (English and French)
- `src/` root files (`main.ts`, `init.ts`, `TrackLabColors.ts`, `TrackLabConstants.ts`, etc.) — bootstrapping and global config
Expand All @@ -67,7 +86,7 @@ npm run fix # fix lint + format issues together
## Architecture notes

- **Reactive state**: all model values are Axon `Property` / `BooleanProperty` / `DerivedProperty`. Views observe properties and update automatically — avoid manual imperative sync.
- **Model-view transform**: `SimScreenView` computes a `modelViewTransformProperty` from the coordinate system pose and calibration data. Use it to convert between real-world units and video-pixel coordinates.
- **Model-view transform**: `ModelViewTransformFactory.ts` builds the `Transform3` from the coordinate system pose and calibration data. `SimScreenView` wraps this in a `modelViewTransformProperty`. Use it to convert between real-world units and video-pixel coordinates.
- **Frame rate**: `SimModel.frameRateProperty` (default 30 fps) drives `frameDurationProperty`. The user can change frame rate via `PlaybackControlsNode`; frame stepping and time display use this value.
- **SceneryStack layout**: use `HBox` / `VBox` for rows and columns. Prefer `align: 'center'` and explicit `spacing` values. Do not set absolute pixel positions unless absolutely necessary.

Expand Down
65 changes: 40 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ A browser-based video analysis tool for tracking and measuring motion in physics
- **Calibration tool** — Define a known reference distance to convert pixel measurements to real-world units (mm, cm, m, km, in, ft)
- **Auto-tracking** — Select any object and track it across frames using OpenCV template matching
- **Manual digitizing** — Add multiple tracks (A, B, C…) and place points frame-by-frame with a crosshair cursor and magnifier
- **Measurement tools** — Draggable measuring tape (real-world distance) and three-handle angle tool, enabled via preferences
- **Kinematics graph** — Configurable X-Y plot of any two kinematic quantities (position, velocity, acceleration, speed) for any track
- **Data table** — Spreadsheet view of all track data with CSV export
- **Webcam recording** — Capture live video directly in the browser and use it as the analysis source
- **Help dialog** — In-app guide explaining the digitizing workflow, accessible via the info button
- **Configurable frame rate** — Set video frame rate (15–60 fps) for accurate time calculations
- **Bilingual UI** — English and French interface support
- **Color profiles** — Default and projector modes for classroom presentation
Expand Down Expand Up @@ -118,6 +120,7 @@ src/
├── splash.ts # Splash screen
├── brand.ts # Branding metadata
├── assert.ts # Assertion utilities
├── TrackLabButton.ts # Factory for consistently styled push buttons
├── TrackLabColors.ts # Centralized color properties (default + projector)
├── TrackLabConstants.ts # Layout and validation constants
├── TrackLabNamespace.ts # SceneryStack namespace registration
Expand All @@ -127,34 +130,46 @@ src/
│ ├── strings_en.json # English strings
│ └── strings_fr.json # French strings
├── preferences/
│ ├── TrackLabPreferencesModel.ts # User preferences (color profile, etc.)
│ ├── TrackLabPreferencesModel.ts # User preferences (auto-tracking, graph quantities, measurement tools)
│ └── TrackLabPreferencesNode.ts # Preferences UI
├── screen-name/
│ ├── SimScreen.ts # Screen wiring (model + view)
│ ├── model/
│ │ ├── SimModel.ts # Application state (Axon Properties)
│ │ └── Track.ts # Track model (points, label, color)
│ └── view/
│ ├── SimScreenView.ts # Root view, layout, MVT computation
│ ├── VideoPlayerNode.ts # Video element, hosts overlays
│ ├── VideoSourceControlNode.ts # Video dropdown + Record button
│ ├── PlaybackControlsNode.ts # Play, scrubber, frame step, frame rate
│ ├── CoordinateSystemNode.ts # Draggable/rotatable axes overlay
│ ├── CalibrationToolNode.ts # Reference distance tool
│ ├── ControlPanel.ts # Left-side toggle panel
│ ├── AutoTrackerNode.ts # Auto-tracking overlay and trail
│ ├── DigitizingOverlayNode.ts # Manual digitizing crosshair + magnifier
│ ├── DataTableNode.ts # Spreadsheet of track data, CSV export
│ ├── KinematicsGraphNode.ts # Configurable kinematics graph (wraps graph/)
│ ├── TrackListPanel.ts # Add/remove tracks for digitizing
│ ├── WebcamPanel.ts # Webcam recording dialog
│ └── KeyboardShortcutsNode.ts
├── graph/
│ ├── ConfigurableGraph.ts # Top-level graph node; axis selectors, chart layout, zoom/reset
│ ├── GraphDataManager.ts # Data points, auto-scaling, tick spacing
│ ├── GraphInteractionHandler.ts # Pan, pinch-zoom, axis drag, resize, header drag gestures
│ ├── GraphControlsPanel.ts # Axis property selector dropdowns
│ └── PlottableProperty.ts # Interface for quantities that appear in the axis selector
│ │ ├── SimModel.ts # Application state (Axon Properties)
│ │ ├── Track.ts # Track model (points, label, color)
│ │ ├── KinematicsComputer.ts # Velocity and acceleration via finite differences
│ │ └── ModelViewTransformFactory.ts # Builds Transform3 from coord-system + calibration
│ ├── view/
│ │ ├── SimScreenView.ts # Root view, layout, MVT computation
│ │ ├── VideoPlayerNode.ts # Video element, hosts overlays
│ │ ├── VideoSourceControlNode.ts # Video dropdown + Record button
│ │ ├── PlaybackControlsNode.ts # Play, scrubber, frame step, frame rate
│ │ ├── CoordinateSystemNode.ts # Draggable/rotatable axes overlay
│ │ ├── CalibrationToolNode.ts # Reference distance tool
│ │ ├── ControlPanel.ts # Left-side toggle panel
│ │ ├── AutoTrackerNode.ts # Auto-tracking overlay and trail
│ │ ├── DigitizingOverlayNode.ts # Manual digitizing crosshair + magnifier
│ │ ├── DataTableNode.ts # Spreadsheet of track data, CSV export
│ │ ├── KinematicsGraphNode.ts # Configurable kinematics graph (wraps graph/)
│ │ ├── TrackListPanel.ts # Add/remove tracks for digitizing
│ │ ├── MeasurementToolsPanel.ts # Checkboxes for measuring tape and angle tool
│ │ ├── MeasuringTapeNode.ts # Draggable tape overlay with real-world distance label
│ │ ├── AngleToolNode.ts # Three-handle angle overlay with degree label
│ │ ├── InfoDialogNode.ts # Modal help dialog for digitizing workflow
│ │ ├── WebcamPanel.ts # Webcam recording dialog
│ │ └── KeyboardShortcutsNode.ts
│ └── graph/
│ ├── ConfigurableGraph.ts # Top-level graph node; axis selectors, chart layout, zoom/reset
│ ├── GraphDataManager.ts # Data points, auto-scaling, tick spacing
│ ├── GraphInteractionHandler.ts # Orchestrates gesture handlers; shared chart config
│ ├── PanGestureHandler.ts # Chart-area drag to pan both axes
│ ├── ZoomGestureHandler.ts # Mouse-wheel and pinch zoom; double-click to reset
│ ├── AxisGestureHandler.ts # Single-axis pan and zoom on axis labels
│ ├── ResizeGestureHandler.ts # Corner drag handles for graph panel resize
│ ├── HeaderDragHandler.ts # Header drag to reposition floating graph panel
│ ├── GraphControlsPanel.ts # Axis property selector dropdowns
│ ├── PlottableProperty.ts # Interface for quantities in the axis selector
│ └── kinematics-plottable-properties.ts # Registry of all plottable quantities
└── tracking/
└── OpenCVTracker.ts # OpenCV template matching (TM_CCOEFF_NORMED)
```
Expand All @@ -165,7 +180,7 @@ State is modeled as reactive [Axon Properties](https://github.com/phetsims/axon)

### Model-view transform

`SimScreenView` derives a `modelViewTransformProperty` from the coordinate system's position/rotation and the calibration tool's endpoints and distance. This transform maps real-world coordinates (e.g., meters) to video pixel coordinates and back.
`ModelViewTransformFactory` builds a `Transform3` from the coordinate system's position/rotation and the calibration tool's endpoints and distance. `SimScreenView` wraps this in a reactive `modelViewTransformProperty`. The transform maps real-world coordinates (e.g., meters) to video pixel coordinates and back.

### Tracking pipeline

Expand Down