Compositions: fade items in and out with grips at their corners

- Compositions has a new section Fades and a paragraph on the grips
  in the tab.
- Videos describes the sprite property Video volume.
- Development counts 2073 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-14 09:05:37 +02:00
1 parent 4203ca83ea
commit dbdab1f55e
3 files changed
+29 -4

No files matched your search

+26 -2
@@ -20,7 +20,8 @@ of objects beside scenes and containers (`ObjectHolder` in `src/core/model/Proje
What is stored (`CompositionAsset` in `src/core/model/Asset.ts`): `tracks` (id, name), `items` (id
= the object's id, track, start and length in frames, offset in seconds into its video,
`fitMedia`, and for an audio item `audio`) and `clips` (id, track, animation, start in frames). An
`fitMedia`, for an audio item `audio`, and its fades `fadeIn`, `fadeOut`, `curveIn`, `curveOut`)
and `clips` (id, track, animation, start in frames). An
item whose object is gone stays in the list, so an undo finds it again, and plays as nothing.
### Audio items
@@ -41,6 +42,23 @@ A **sound**, a **clip of a sound**, a **pattern** or a **song** dragged onto a t
- **Animation clips do not belong to an audio item**: there is nothing on it they could move.
- **What is gone plays nothing.** The item stays, drawn red, named *(missing)*.
### Fades
An item with a sound, an audio item or an item whose sprite wears a video, can **fade in** at its
start and **fade out** at its end. Each fade is a number of frames and a curve, the curves of a
[sound's clip](Sounds): *Linear* (the default), *Equal power*, *S-curve*, *Exponential*,
*Logarithmic*. The fades hang on the edges of the item: trimmed or resized, the item takes them
along. A fade is never longer than the item, and the fade out never longer than what the fade in
leaves (`itemFades` in `src/core/model/composition.ts`).
- **An audio item** fades on its own bus. The fades are ramps of that bus' level on the audio clock,
planned by the scheduler with the notes (`SequenceLevel` in `src/core/music/sequence.ts`), so they
land to the sample. Started in the middle of a fade, it takes the ramp up from there.
- **A video item** fades its sprite's **Video volume** (see [Videos](Videos#following-an-animation)):
every frame the composition sets it to the sprite's own value times the fade, and the player
glides to it over a few milliseconds, so the steps of the frames do not click. Video sprites below
the item fade along.
The sequences are made in `src/core/music/compositionAudio.ts`: everything in milliseconds of the
composition, one sequence for each place of the mix the items go to. `CompositionSound`
(`src/runtime/compositionSound.ts`) plays them through the scheduler, in the tab and in a game.
@@ -120,6 +138,11 @@ the clips as narrower bars above them. The header bar has **+ Track**, **Play**
stays where it is in time. It may go past the video's start (the offset turns negative). An
edge snaps to the video's start and end within 6 px. An edge has the first say over a body, so
the hidden end of an item below another can still be taken.
- **The fade handles.** An item with a sound has a small square on its top edge at each end, shown
while the pointer is over the item or it is picked, and always where it has a fade. Dragging one
inwards draws out the fade, back to the edge removes it. The handle comes before the edge, so the
top corner fades and the rest of the edge trims. The fade is drawn as the curve its level
follows from the bottom of the item to the top, the part not heard shaded.
- **Where the video lies.** On an item with a video, a small triangle in a lower corner says the
item cuts into the video on that side: there would be more of it. A line with a triangle, like a
loop in the Song tab, marks where the video starts or ends inside the item; with Loop on the
@@ -170,7 +193,8 @@ the links of their video in the [Master routing](Sounds#master-routing).
stay at the top. **The inspector** of an item shows its object's rows and a block **TIMING**:
*Start*, *Length* and, for a video item, *Offset*, all in seconds, and **Fit to media**. An audio
item shows **SOUND ITEM** (*PATTERN*, *SONG*): what it plays, the same timing rows with *Offset*,
**Volume** in dB and **Bus** (*From asset*, *Master* or a bus). A track
**Volume** in dB and **Bus** (*From asset*, *Master* or a bus). An item with a sound adds *Fade
in* and *Fade out* in seconds and a curve for each to its TIMING. A track
shows its name; a clip its animation and its start, with the length of one pass.
**Fit to media.** A new item's length follows its video: when an override gives its sprite another
+1 -1
@@ -21,7 +21,7 @@ php tests/php/releases.test.php # the release stor
php tests/php/files.test.php # uploaded files in a folder per account (#344), the same way
php tests/php/videos.test.php # the video store, its queue and the worker (#402), with the
# real ffmpeg: the CI image and feuerwerk-video have it
node tools/seed-e2e.mjs && node tools/e2e.mjs # 2072 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 2073 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
+2 -1
@@ -101,13 +101,14 @@ Not yet: nodes to play, pause or jump in a video, or to hear when it ends. That
## Following an animation
A video that plays by itself runs on its own clock, so an [animation](Animations) cannot say which
picture shows when. For a cut, the sprite's **Video clock** row says who keeps the time (#404). Both
picture shows when. For a cut, the sprite's **Video clock** row says who keeps the time (#404). These
rows show only while the Texture is a video or a clip of one.
| Row | |
|---|---|
| **Video clock** | **Free** (the default): the video plays by itself, as above. **Driven**: it shows the picture at its Video time |
| **Video time** | seconds into the clip, shown while the clock is Driven. A number like any other, so an animation keys it |
| **Video volume** | 0 to 1, how loud the video is heard through this sprite, on top of the video's own Volume. Shown while the clock is Driven. The fades of a [composition](Compositions#fades) item set it |
What the keys on Video time do: