Key a video to its end at 1x and zoom the timeline further out (#407)
To play a clip at its real speed the user had to know its length, work out the last whole frame by hand and then scroll far to the right to set the end key. The timeline now does the sum, and it zooms out far enough to see a long clip in one piece. - The context menu of a Video time row gets "Video at 1x to its end from frame N". It keys the playhead with the row's value there and the last whole frame before the clip ends with the matching time. - The start key turns linear and keys in between are removed. The whole run is one undo step (KeyStraightRunCommand). - The clip is the one the sprite wears at the playhead, also when the texture is keyed in the same animation (rowVideoAt). - The entry is greyed out for relative rows, without a video, while the length is unknown, or when the playhead is already at the end. - The status line names the result, e.g. "frame 572 shows 57.2 s of 57.27 s". - The timeline zooms out to 0.02 px per frame instead of 4 px. The ruler labels follow a 1-2-5 step without an upper limit. Tests: - Unit video-clock + timeline-view: 27 tests green, 8 new - e2e 66 (atx, alone): ALL PASSED, 23 checks, 66l new - Gate (atx): CHECK EXIT 0, 297 files, 4553 tests - Counter-check: the command keeping the keys in between turns exactly the command test red Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c9e8a3f6ac
commit
774207208c
9 files changed
+291
-8
No files matched your search
@@ -353,6 +353,34 @@ export async function video(t) {
|
||||
along.every((p) => !p.paused && !p.muted && Math.abs(p.rate - 1) <= 0.1 && gap(p.time, p.asked) < 0.15),
|
||||
JSON.stringify(along),
|
||||
);
|
||||
|
||||
// 66l. Right-click → "Video at 1× to its end" (#407): from the playhead (frame 5, 0.5 s) the
|
||||
// last whole frame before the clip ends, the key on 9 between them gone; one undo step.
|
||||
const rowKeys = () =>
|
||||
json(
|
||||
`__gm.state.project.assets.find((a) => a.id === '${CUT}').tracks[0].keys.map((k) => [k.frame, k.value])`,
|
||||
);
|
||||
await mutate(`
|
||||
__gm.state.project.assets.find((a) => a.id === '${CUT}').tracks[0].keys =
|
||||
[{ frame: 0, value: 0 }, { frame: 5, value: 0.5 }, { frame: 9, value: 1.7 }];`);
|
||||
const keyed = JSON.stringify(await rowKeys());
|
||||
await t.evaluate('__gm.animation.scrub(5)');
|
||||
const inRow = await json("__gm.animation.cellAt('vd66-row', 2)");
|
||||
await click(inRow.x, inRow.y, 'right');
|
||||
const runItem = await t.find('Video at 1× to its end from frame 5', true);
|
||||
await click(runItem.x, runItem.y);
|
||||
const steps = Math.floor((uploaded.duration - 0.5) * 10 + 1e-6);
|
||||
const ran = await rowKeys();
|
||||
await t.undo();
|
||||
check(
|
||||
'the menu keys the video at 1x from the playhead to the last frame before its end, in one undo step',
|
||||
ran.length === 3 &&
|
||||
JSON.stringify(ran.slice(0, 2)) === '[[0,0],[5,0.5]]' &&
|
||||
ran[2][0] === 5 + steps &&
|
||||
Math.abs(ran[2][1] - (0.5 + steps / 10)) < 1e-6 &&
|
||||
JSON.stringify(await rowKeys()) === keyed,
|
||||
JSON.stringify({ ran, steps, duration: uploaded.duration, undone: await rowKeys() }),
|
||||
);
|
||||
await showTab('scene');
|
||||
|
||||
await mutate(`
|
||||
|
||||
Reference in new issue
Block a user