OpenCut-app / OpenCut-app/OpenCut
Rewrite input: field notes from shipping mobile touch editing on the classic editor
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 89.8k
- Forks
- 8.9k
- PR merge metrics
- No merged PRs in 30d
Description
Context: we ship a production video product (FrameOS) whose editor is the classic OpenCut web editor, adopted wholesale under MIT — thank you for building it. Over a series of releases we took it from desktop-only to genuinely usable on phones, in production. Since the rewrite targets "desktop, mobile, and browser from one codebase", here are the design decisions that actually mattered, and the ones that surprised us. Sharing as input for the architecture phase (per the README's "open an issue" invitation; related: #811).
The touch grammar that worked (mostly borrowed from CapCut)
-
Tie timeline scroll to playhead time on phones. A horizontal swipe scrubs (the playhead seeks to viewport-center time), and seeking auto-centers the scroll. This one change made the timeline feel native on touch. We kept the geometry untouched (no blank lead-in), so all container-based x↔time math kept working.
-
Disambiguate scroll vs. drag with a hold. A quick swipe on an element body scrolls/scrubs; a ~260 ms hold promotes the same touch to a drag. Trim handles and the playhead drag immediately — they're small, deliberate targets, so there's no ambiguity to resolve. This split (hold-to-drag for bodies, immediate for handles) eliminated nearly all mis-drags.
-
Open at a fixed zoom on phones (we use 100 px/s), never fit-to-clip. Fit-to-clip makes short clips unscrubbable and long clips microscopic; a fixed scale gives muscle memory.
-
Phone chrome: preview stacked over timeline, asset/property panels as bottom/side sheets, and a CapCut-style bottom tool strip. We shipped floating buttons over the preview first and replaced them — the strip won decisively.
What we deliberately did NOT do (and what we'd do in a rewrite)
We did not migrate the five mouse-era drag controllers to pointer events. Instead we added a small "touch bridge": surfaces opt in via a data attribute, and single-finger touches on them are replayed as synthetic mouse events (plus tap-as-click). Everything unmarked keeps native scrolling.
That was the right call for retrofitting — contained risk, desktop path untouched. For a from-scratch input layer, use pointer events from day one, but keep the opt-in surface model: the genuinely hard design question was never the event API, it was "which surfaces capture gestures, and which keep native scroll". Making that an explicit per-surface declaration (rather than emergent from handler wiring) is what kept behavior predictable as surfaces were added.
Gotchas worth designing around early
- Viewport units: editor roots need
dvh-style dynamic viewport height on phones, or browser chrome eats the timeline. - Nested horizontal scrollables (a scrollable toolbar above scrollable tracks) confuse users and any UI automation — worth avoiding in the layout contract.
- OS edge gestures (back-swipe, control center) collide with timeline gestures near screen edges; leave dead zones or accept mispredictions.
Happy to go deeper on any of this (measurements, the exact promotion thresholds, what users mis-touched most). Excited for the rewrite.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the README's architecture-phase invitation and related issue #811; this issue names no implementation files, tests, or entry point. Treat the post as design input rather than a bounded coding task, and first identify the rewrite architecture and its agreed scope. Done is not defined here and would require a maintainer decision on the proposed input model and mobile interaction behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, mobile-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100