Description
Allow users to replay a canvas session as a time-lapse animation, scrub through history, and export the replay as an animated GIF / MP4. This greatly improves collaboration awareness and provides a “how it was made” export.
Current workflow
Users can view current canvas or request history slices, but there's no replay UI or scrubbable time-travel player.
Proposed solution
Add a "Replay" player that requests strokes for a room in a time range (server-side support for ranged stroke queries exists in rooms.get_strokes), plays them in order with adjustable speed, provides scrub bar, and exports animation to GIF/MP4 client-side (or server-side fallback for very large canvases).
Technical requirements
Files to create:
frontend/src/components/Replay/ReplayPlayer.jsx
frontend/src/components/Replay/ReplayControls.jsx
frontend/src/utils/replayExporter.js (GIF/MP4 generation helpers / worker)
Files to modify:
Room.jsx (add "Replay" entry / button)
Canvas.js (add a "playback" mode for rendering strokes sequentially)
Backend enhancements (optional for server-side export or streaming):
backend/routes/replay_export.py
backend/services/video_export_worker.py
Skills needed
- React + canvas animation
- Timing & deterministic replay
- Client-side GIF/MP4 generation (workers) or server-side image/ffmpeg pipelines
Key features to implement
- Scrubbable player UI with speed multiplier (0.25x - 4x)
- Live metadata overlay (who drew each stroke and timestamp)
- Export to animated GIF (client-side) and optional server-side MP4 for long sessions
- Bookmark/share links to specific replay timestamps
Technical challenges
- Memory/performance when loading many strokes
- Deterministic rendering across clients (canvas coordinate normalization)
- Exporting long-duration replays (size vs fidelity tradeoffs)
Getting started
- Add prototype
ReplayPlayer that fetches strokes by time range
- Implement sequencing logic and controls
- Add GIF exporter using a WebWorker (e.g., gif.js)
- Optionally add server-side export
Tests to add
- Unit: replay sequencer orders strokes correctly based on ts
- Integration: export small sequence → GIF contains expected frames
- UI: scrub bar seek to timestamp X shows strokes up to X
Resources
- gif.js, ccapture.js, ffmpeg
Description
Allow users to replay a canvas session as a time-lapse animation, scrub through history, and export the replay as an animated GIF / MP4. This greatly improves collaboration awareness and provides a “how it was made” export.
Current workflow
Users can view current canvas or request history slices, but there's no replay UI or scrubbable time-travel player.
Proposed solution
Add a "Replay" player that requests strokes for a room in a time range (server-side support for ranged stroke queries exists in rooms.get_strokes), plays them in order with adjustable speed, provides scrub bar, and exports animation to GIF/MP4 client-side (or server-side fallback for very large canvases).
Technical requirements
Files to create:
frontend/src/components/Replay/ReplayPlayer.jsxfrontend/src/components/Replay/ReplayControls.jsxfrontend/src/utils/replayExporter.js(GIF/MP4 generation helpers / worker)Files to modify:
Room.jsx(add "Replay" entry / button)Canvas.js(add a "playback" mode for rendering strokes sequentially)Backend enhancements (optional for server-side export or streaming):
backend/routes/replay_export.pybackend/services/video_export_worker.pySkills needed
Key features to implement
Technical challenges
Getting started
ReplayPlayerthat fetches strokes by time rangeTests to add
Resources