Unify timeline placement and gesture geometry
This commit is contained in:
parent
4e5e02c856
commit
0cb9d0ebf6
16 changed files with 702 additions and 121 deletions
66
docs/one-grid-plan.md
Normal file
66
docs/one-grid-plan.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# The editing grid is the symbol's own frames
|
||||
|
||||
## What was wrong
|
||||
|
||||
Every number a person authors — a span, a `:time :at`, a key, a cut — is in the
|
||||
frame space of the symbol it lives in (`docs/time.md`, and that part is right).
|
||||
The timeline, though, drew its ruler in OUTPUT frames: `clip/output-frames`, the
|
||||
transport's length. In a 12fps project holding 30fps symbols those two spaces sit
|
||||
at a ratio of 2.5, so:
|
||||
|
||||
* a clip at symbol frame 31 was drawn at ruler frame 12.4 — **no clip edge landed
|
||||
on a frame mark**, because almost none of them can;
|
||||
* a gesture measured in ruler frames had to be multiplied into the symbol's
|
||||
frames and rounded (`nest/dragged`), so dragging one ruler frame moved the clip
|
||||
2 or 3 symbol frames — **0.8 or 1.2 ruler frames, never the 1 the pointer
|
||||
said**. That is the jumpiness;
|
||||
* the preview drew the gesture's own number of ruler frames while the commit
|
||||
wrote the rounded one, so **the ghost sat somewhere the settled clip did not**;
|
||||
* before the rounding was added, the fraction went into the document and every
|
||||
later edge edit on that clip was refused for ever (`span/*` refuses a
|
||||
fractional edge, as it should).
|
||||
|
||||
One cause, four symptoms. None of them is an edge case to patch.
|
||||
|
||||
## The model
|
||||
|
||||
1. **A symbol's own frames are the only coordinate anything authored lives in.**
|
||||
Unchanged.
|
||||
2. **The editor edits in the open symbol's frames.** The ruler, the marks, the
|
||||
playhead's position on it, every pointer→frame answer, every drop frame and
|
||||
every drag delta are the open symbol's frames. No multiplication anywhere in
|
||||
the gesture path, so no rounding and nothing fractional to refuse.
|
||||
3. **The output grid is playback's alone** — the clock, the audio mix, export,
|
||||
and the frame the stage draws. Exactly two pure functions cross between them
|
||||
and nothing else does:
|
||||
* `clip/shown-frame clip sid f` — which of `sid`'s frames output frame `f`
|
||||
shows (`cadence/frame`: the latest at or before it).
|
||||
* `clip/first-output-frame clip sid n` — the output frame that first shows
|
||||
symbol frame `n`; the inverse, for seeking from the ruler.
|
||||
4. `nest/inside`, `nest/placement`, `nest/spans` and the gestures take the
|
||||
subject symbol's OWN frame. They used to take an output frame and multiply it
|
||||
secretly, which is what made every caller's units a guess. A caller holding
|
||||
the playhead converts with `clip/shown-frame`, at its own edge, visibly.
|
||||
|
||||
## The gestures
|
||||
|
||||
5. **One pointer→frame function** for the whole timeline, `frame-under`. A drag's
|
||||
delta is the difference of two of its answers, never a pixel ratio rounded
|
||||
separately — so the preview and the commit are the same number by
|
||||
construction.
|
||||
6. **The junction between two clips is one handle with one meaning**: roll. It
|
||||
moves the end of the left clip and the start of the right one together, which
|
||||
is `span/roll`, which is already nothing but `resize-out` then `resize-in`.
|
||||
The three 4px-wide zones it used to pick between — trim-left, roll,
|
||||
trim-right, inside twelve pixels — were the "it just picks one" the handle
|
||||
was accused of. An edge that is not shared still has its own in/out handles.
|
||||
|
||||
## Audio goes with the picture it belongs to
|
||||
|
||||
A take's sound lived inside the take symbol, so placing the take brought it and
|
||||
placing the FACE the take is made of brought nothing. A symbol now says what it
|
||||
sounds like — `:audio`, a sound source — and placing one places a linked audio
|
||||
node beside the clip. Detection sets it on the face it extracts, which is the
|
||||
automatic link; `::ui/link-audio` sets or clears it by hand, which is the manual
|
||||
one. `:linked-to` on the audio node already existed and already follows a moved
|
||||
picture.
|
||||
Loading…
Add table
Add a link
Reference in a new issue