My startup
TacticFrame
A football tactics board for drawing and explaining player movement. It runs in the browser without an account.
10Languages for the interface and articles
- Period
- 2026.09 ~ Present
- Organization
- Firstage
- Role
- Planning, design, development, and operations (solo)
- Links
- Key features
- Arrange formations and movement into scenes, then play them back or export a video.
- Work and results
- Tactics saved and video exported in the browser
- 10 tactics guides and 7 match analyses
- Interface and articles in 10 languages
- Early version released in September 2026
- Tech stack
- Next.js
- Konva
- IndexedDB
- Cloudflare Workers
- TypeScript
- Cloudflare D1
Context
I built a tactics board for explaining football team movement through drawings and video. You place players on the pitch, draw their paths, and join scenes for playback. It runs in the browser without an account.
I handle planning, design, development, and operations as part of Firstage. Alongside the editor, the site offers ten tactics guides and seven match analyses.
Decisions and implementation
- The editable project is not sent to a server. It lives in the browser’s IndexedDB, and a save appends a revision and moves the current-revision pointer in one transaction. A saved project that cannot be read, or has an unknown version, is left untouched and opens in a protected state.
- Player positions are normalized coordinates from 0 to 1 across the pitch, so a scene looks the same at any screen size. Moving players, reordering scenes, and changing scene length have keyboard alternatives, and playback follows the reduced-motion setting.
- Video export stays in the browser. A frozen copy of the project is drawn on a separate Konva canvas and recorded with MediaRecorder, capped at two minutes and 64 MiB. If the tab is hidden or the encoder fails, the partial file is discarded and the user can retry with the same copy.
- Match data is stored in Cloudflare D1 as immutable revisions, and only a validated revision can be activated. The public pointer moves separately, public pages read only the revision it names, and a failed D1 read does not fall back to another source.
- I build each release from a clean checkout so work in progress cannot slip in, and I record the previous Worker version as the rollback target before deploying. Afterward I check the live site at 1440px wide, at 390px portrait, and in mobile landscape.
Current state
I started TacticFrame in September 2026, published an early version at tacticframe.com that month, and still run it alone. The interface and articles come in ten languages, translated and edited with AI, and native-speaker review is not finished. Link sharing is not built, and the project is not affiliated with any club, league, or player.