Update the music tabs for zoom, loop strip, edges and paste

Patterns and Songs follow the last three commits of the editor.

- Patterns: the loop strip over the ruler, the wheel zoom, Audition,
  sizing a note by its left end, the cursor on the nearest line,
  panning before bar 1 and past the rows, Shift, paste under the
  pointer and Fit zooming the rows.
- Songs: one track for a new song, tracks from the head menu, the
  item menu, a click on empty space, +12 dB, edge hover, loop seams,
  one bar at least, pulling items out left, snapping to rounds,
  paste under the pointer and the zoom limits.
- Home: one line on the music tabs.
- Development: 1828 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-06 19:14:50 +02:00
1 parent 528dc7fd5d
commit 6e5c5391b5
4 files changed
+71 -41

No files matched your search

+1 -1
@@ -18,7 +18,7 @@ php tests/php/accounts.test.php # the API's accoun
# has and the web server's container has not (SKIP there)
php tests/php/snapshots.test.php # the snapshot store (#231), the same way
php tests/php/releases.test.php # the release store (#266), the same way
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1817 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1828 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result
+1 -1
@@ -23,7 +23,7 @@ Live: <https://nockal.com/game-maker/> · Widget playground: <https://nockal.com
| [Fonts](Fonts) | Uploading a typeface, what a text wears, what the editor falls back to |
| [Sounds](Sounds) | Uploading a sound, what the asset says, `Play sound` and `Stop sound`, sound FX (gain, pitch, EQ, mix, delay) and how long a voice rings on, what a pause and a stop do to a voice |
| [Instruments](Instruments) | The instrument asset: Notes, Sample, Parameters, Sound FX, Envelope and Output, triggers, zones and layers, the keys of the Instrument tab, `Play note` |
| [Patterns](Patterns) | The pattern asset and its piano roll: drawing, moving and lengthening notes, the grid, the ruler with start and loop, velocities, playing it in a loop |
| [Patterns](Patterns) | The pattern asset and its piano roll: drawing, moving and sizing notes, the grid, the ruler with start and loop, velocities, playing it in a loop |
| [Songs](Songs) | The song asset: tracks with volume, pan, mute and solo, pattern and sound items laid out, moved, cut and split, playing it in a loop |
| [Animations](Animations) | Animation assets, the Animation tab, how they run |
| [Curves](Curves) | Easings drawn by hand, the Curve tab, using one on a key or a `Lerp` |
+32 -19
@@ -29,23 +29,28 @@ grey, a note a drum kit has named shows its name, every C its note name. A key s
pointer holds it. Along the top is the **ruler** with the bars numbered from 1 and the beats as
short ticks, the loop as a band along its top edge and where playing starts as a small triangle at
its foot. Between them are the **notes**, each a bar in its key's row, the brighter the harder it is
struck; picked notes are light with a white edge. Below them is the **velocity lane**: a stem at
the start of every note, as high as its velocity.
struck; picked notes are light with a white edge. An end of a note under the pointer lights up and
the pointer turns into a resize arrow, as on an item of the [Song tab](Songs#the-song-tab): that end
can be dragged. Below them is the **velocity lane**: a stem at the start of every note, as high as
its velocity.
The header has **Play** (it turns into **Stop**), the **Grid**, **Fit** and on the right the number
of notes and the instrument. **Fit** shows the whole pattern across and its notes (or, with none,
what the instrument plays) down the middle.
The header has **Play** (it turns into **Stop**), the **Grid**, **Audition**, **Fit** and on the
right the number of notes and the instrument. **Audition** is off when the tab opens; switched on, a
note sounds for a moment when it is drawn, grabbed or moved to another key. The keys down the left
sound either way. **Fit** shows the whole pattern across and its notes (or, with none, what the
instrument plays) down the middle, the rows zoomed so they fill the height (up to 64 px a row).
### Drawing and editing
| Do this | And this happens |
|---|---|
| Click into the grid | A note at the grid line before the pointer, as long as the last note drawn or lengthened (a grid step at first), with the last velocity set (0.8 at first). It is picked and sounds for a moment. |
| Drag a note by its body | It moves along the grid and to the key under the pointer, the other picked notes with it. It sounds again on every new key. |
| Click into the grid | A note at the grid line before the pointer, as long as the last note drawn or lengthened (a grid step at first), with the last velocity set (0.8 at first). It is picked and, with **Audition** on, sounds for a moment. |
| Drag a note by its body | It moves along the grid and to the key under the pointer, the other picked notes with it. With **Audition** on it sounds when grabbed and again on every new key. |
| Drag a note by its right end | It takes the length to the grid line nearest the pointer, the other picked notes lengthen by as much. |
| Hold `Alt` while drawing, moving or lengthening | Off the grid, on the tick. A note is at least one tick long. |
| Drag a note by its left end | Its start goes to the grid line nearest the pointer and its end stays put; the other picked notes' starts move by as much. Never before tick 0. |
| Hold `Alt` or `Shift` while drawing, moving or sizing | Off the grid, on the tick. A note is at least one tick long. |
| Drag on empty grid | A band; the notes it touches are picked. With `Shift` they are added to the pick. |
| `Shift`-click a note | Adds it to the pick or takes it out. |
| `Shift`-click a note | Adds it to the pick or takes it out. Dragged on with `Shift`, it is added and moved or sized off the grid instead. |
| Right-click a note | Deletes it; dragging on with the right button deletes every note it passes. |
| Drag a stem in the velocity lane | Sets that note's velocity; if the note is picked, the other picked notes move by as much. |
@@ -55,7 +60,7 @@ Every drag is one undo step, and so is every key below that changes notes.
|---|---|
| `Space` | Play or stop. |
| `Delete`, `Backspace` | Delete the picked notes. With none picked the key does nothing, so a second press never asks about the pattern itself. |
| `Ctrl+C`, `Ctrl+V` | Copy the picked notes; paste them so the earliest lands where playing starts. The copy works for every pattern of the project. |
| `Ctrl+C`, `Ctrl+V` | Copy the picked notes; paste them under the pointer: the earliest on the grid line before it, the highest on its row, as far as the keyboard goes. With the pointer off the grid (or left of bar 1) the earliest lands where playing starts, on the keys they came from. The copy works for every pattern of the project. |
| `Ctrl+D` | A copy of the picked notes right behind them, moved by whole grid steps, picked in their place. |
| `Ctrl+A` | Pick every note. |
| `↑` / `↓` | The picked notes a semitone up or down, with `Shift` an octave. |
@@ -67,19 +72,27 @@ editor, the way they do in the other tabs.
### The ruler
- A **click** sets where playing starts (on the grid line before it, with `Alt` on the tick). A
paste lands there. While the pattern plays, it jumps there.
- A **drag** spans the loop, on the grid. Near an end of the loop a drag moves that end.
The ruler has two parts: a dark **loop strip** along its top, which shows the loop as a blue band,
and below it the bars and beats, which hold where playing starts.
- A **click or drag on the bars** moves where playing starts, and nothing else (on the grid line
nearest the pointer, with `Alt` or `Shift` on the tick). A paste with the pointer off the grid
lands there. While the pattern plays, it
jumps there when the button is let go.
- A **drag on the loop strip** spans the loop, on the grid. Near an end of the loop a drag moves
that end. A click there without a drag changes nothing.
- A **right-click** offers *Loop bar N* and *Loop the whole pattern*. With no loop set the whole
pattern is the loop, and a shorter pattern cuts a loop at its end.
### Zoom and scroll
The wheel scrolls up and down, with `Shift` across (a trackpad scrolls both ways). The wheel on
the ruler, or with `Alt` anywhere but the keys, zooms the time about the pointer; with `Alt` on the
keys it zooms the rows. A middle-drag pans both ways. `Ctrl`+wheel is left to the browser, which
zooms the page with it. Only what is on screen is drawn, so a pattern of some hundred notes stays
quick.
The wheel zooms and does nothing else: over the grid, the ruler or the velocity lane it zooms the
time about the pointer, over the keys it zooms the rows (6 to 64 px). `Alt` and `Shift` do not change it. A
middle-drag pans both ways. Bar 1 need not stay at the left edge: a pan takes it up to half the
grid in. The time before it is drawn dark, only to look at; a click there draws no note. Down the
grid the same: the highest note can come up to half the height down from the top, the lowest up to
half the height up from the bottom, the room past them dark and with nothing to draw. `Ctrl`+wheel is left to the browser, which zooms the page with it. Only
what is on screen is drawn, so a pattern of some hundred notes stays quick.
## Playing
@@ -131,6 +144,6 @@ once it was gone by itself after its bar.
## Not yet
No notes of other patterns in the background (ghost notes), no lanes for
No notes of other patterns in the background (ghost notes, #339), no lanes for
pitch bend or an instrument's parameters (automation, #337), no swing. The computer keyboard does
not play notes in this tab as it does in the Instrument tab, and there is no step input.
+37 -20
@@ -3,7 +3,7 @@ one time axis. It is the third piece of the music tools of #330, after the instr
pattern (#333). Several songs and tracks can use the same pattern: an edit to it is heard everywhere
it lies.
Songs are listed under **Songs** in the asset panel. A new song has four empty tracks, 120 BPM in
Songs are listed under **Songs** in the asset panel. A new song has one empty track, 120 BPM in
4/4, and items snap to the bar.
## What a song says
@@ -22,7 +22,7 @@ automation (#337).
### Tracks
A track has a name, a **volume** from -60 to +6 dB, a **pan** from -1 (left) to 1 (right), **mute**
A track has a name, a **volume** from -60 to +12 dB, a **pan** from -1 (left) to 1 (right), **mute**
and **solo**. While any track is soloed, only the soloed ones are heard. Each track is heard on a bus
of its own: a change of volume, pan, mute or solo reaches what is sounding on it at once, not only
the next note. A song keeps at least one track. There are no effects on a track yet, that needs the
@@ -38,40 +38,50 @@ takes both kinds, mixed.
| **Pattern** | Plays the pattern's notes. Longer than the pattern, it repeats it; it plays the whole pattern, the loop set on its ruler is for editing. **Transpose** moves every note by semitones (-48 to 48). **Instrument** plays it with another instrument; empty, the pattern's own. |
| **Sound** | Plays the sound as a clip, at its own speed whatever the tempo. Longer than the sound, it repeats it. A **Sound FX** sends it through an effect. |
Every item has a **volume** from -60 to 0 dB on top of its track's. An item whose pattern or sound
Every item has a **volume** on top of its track's: a sound item from -60 to +12 dB, a pattern item
from -60 to 0 dB, since a note is never louder than its velocity makes it. An item whose pattern or sound
has been deleted stays, drawn red as *missing*, and plays nothing.
An item cut back from its left end keeps what it plays where it was: it starts that far into its
pattern (in ticks) or its sound (in seconds). A split does the same with the right-hand part.
pattern (in ticks) or its sound (in seconds). A split does the same with the right-hand part. Pulled
out by its left end past the start of what it plays, an item repeats that to the left as it does to
the right: it starts that far before the end of a round.
## The Song tab
Down the left are the **heads** of the tracks: the name, **M** (mute, orange when on) and **S**
(solo, yellow when on), below them the volume (the line marks 0 dB) and the pan (the line marks the
middle). Under the last track, **+ Track** adds one. Along the top is the **ruler**, as in the
middle). A track is added from the right-click menu of a head, above or below it. Along the top is the **ruler**, as in the
Pattern tab. Between them are the **lanes** with the items: a pattern blue with its notes drawn
small, every round it plays; a sound green with its waveform, from where it starts in it. A picked
item has a white edge; a picked track a lit head and lane.
small, every round it plays; a sound green with its waveform, from where it starts in it, every
round drawn alike (each column shows the loudest part of what it covers). An item
longer than what it plays has a white line with a small notch where it starts over, one for every
round. An end of an item under the pointer lights up and the pointer turns into a resize arrow: that
end can be dragged. A picked item has a white edge; a picked track a lit head and lane. Zoomed down
to less than 46 px, a head shows only its name, **M** and **S**.
The header has **Play** (it turns into **Stop**), the **Grid**, **Fit** and on the right the number
of tracks and items. **Fit** shows the whole song across.
What is picked goes to the inspector: an item shows its pattern or sound, its volume and the rows of
its kind, a track its name, volume, pan, mute and solo. Both have a button to delete them.
its kind, a track its name, volume, pan, mute and solo. A click on nothing in the lanes picks the
song itself, with its tempo, meter and grid. Items and tracks are deleted with `Delete` or from their
right-click menu, not from the inspector.
### Laying out and editing
| Do this | And this happens |
|---|---|
| Drag a pattern or a sound from the Assets panel onto a lane | A frame shows where it lands; let go and it lies there, on the grid line before the pointer, as long as the pattern or as the sound at the song's tempo, picked. |
| Drag a pattern or a sound from the Assets panel onto a lane | A frame shows where it lands; let go and it lies there, on the grid line before the pointer, as long as the pattern or as the sound at the song's tempo, picked. Left of bar 1 nothing lands. |
| Drag an item by its body | It moves along the grid and to the track under the pointer, the other picked items with it. |
| Drag an item by its right end | It takes the length to the grid line nearest the pointer, the other picked items lengthen by as much. |
| Drag an item by its left end | It is cut back (or pulled out again) at the front; what it plays stays where it was. It can be pulled out no further than the start of what it plays. |
| Hold `Alt` while moving or sizing | Off the grid, on the tick. |
| Drag an item by its right end | It takes the length to the grid line or the end of a round nearest the pointer, the other picked items lengthen by as much. An end of a round between two ticks is cut to the tick before, so nothing of the next round sounds. |
| Drag an item by its left end | It is cut back or pulled out at the front, to the grid line or the start of a round nearest the pointer; what it plays stays where it was. Pulled out past the start of what it plays, it repeats it. A sound not loaded yet stops at its start. |
| Hold `Alt` or `Shift` while moving or sizing | Off the grid and off the rounds, on the tick. |
| Drag on empty lanes | A band; the items it touches are picked. With `Shift` they are added. |
| Click an empty lane | Picks its track. |
| `Shift`-click an item | Adds it to the pick or takes it out. |
| Right-click an item | Deletes it; dragging on with the right button deletes every item it passes. |
| Click on nothing in the lanes | Picks the song itself. |
| Click a head | Picks its track. |
| `Shift`-click an item | Adds it to the pick or takes it out. Dragged on with `Shift`, it is added and moved or sized off the grid instead. |
| Right-click an item | Opens its menu: *Delete* deletes it, or every picked item where it is one of them. |
| Double-click a pattern item | Opens the pattern in the Pattern tab. |
| Click **M** or **S** in a head | Mutes or solos the track. |
| Drag along a head's volume or pan | Sets it; while the song plays it is heard as it moves. |
@@ -83,7 +93,7 @@ Every drag is one undo step, and so is every key below that changes the song.
|---|---|
| `Space` | Play or stop. |
| `Delete`, `Backspace` | Delete the picked items; with none picked, the picked track and what lies on it. Never the song itself. |
| `Ctrl+C`, `Ctrl+V` | Copy the picked items; paste them where playing starts, on the tracks they came from. The copy works for every song of the project. |
| `Ctrl+C`, `Ctrl+V` | Copy the picked items; paste them under the pointer: the earliest on the grid line before it, the topmost on the track under it, the others as far below as there are tracks. With the pointer off the lanes (or left of bar 1) they land where playing starts, on the tracks they came from. The copy works for every song of the project. |
| `Ctrl+D` | A copy of the picked items right behind them, moved by whole grid steps, picked in their place. |
| `Ctrl+E` | Split the picked items where playing starts; the right-hand parts are picked. |
| `Ctrl+A` | Pick every item. |
@@ -91,10 +101,17 @@ Every drag is one undo step, and so is every key below that changes the song.
| `←` / `→` | The picked items a grid step earlier or later, with `Shift` a bar. |
| `Esc` | Pick nothing. |
The ruler, zoom and scrolling work as in the [Pattern tab](Patterns#the-ruler): a click sets where
playing starts, a drag the loop, a right-click offers *Loop bar N* and *Loop the whole song*; the
wheel scrolls, with `Shift` across, on the ruler or with `Alt` it zooms the time. With no loop set
the whole song is the loop: up to the bar after its last item, and at least four bars.
The ruler works as in the [Pattern tab](Patterns#the-ruler): a click or drag on the bars moves
where playing starts, a drag on the loop strip along its top sets the loop, a right-click offers
*Loop bar N* and *Loop the whole song*. With no loop set the whole song is the loop: up to the bar
after its last item, and at least one bar. An empty song is a single bar long, so **Fit** shows that
one bar across; the wheel takes the view out to lay items further on.
The wheel zooms and does nothing else: over the lanes or the ruler the time about the pointer, over
the heads the height of the tracks (28 to 320 px), about the track under the pointer. A middle-drag
pans both ways, and as in the Pattern tab it can take bar 1 up to half the lanes in, the time before
it drawn dark and only to look at. Down the lanes it can take the first track up to half the height
down and the last up to half the height up; nothing lies above or below them. **Fit** shows the whole song across and keeps the height of the tracks.
## Playing