Let the queue page pin the frame animation
Waiting for the shuffle bag to land on the animation you are working on makes testing one of them tedious. The queue page now carries an Animation row next to Background: Auto keeps the per-track cycle, any other button pins the player to that animation until the mode changes again. The animation names live in config.js alongside their labels, so the server can validate them and the queue page can label its buttons; motion.js keys its registry by the same names. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tg15tLAuT6NrCE1ZxKVgDB
This commit is contained in:
+36
-14
@@ -11,6 +11,7 @@ import {
|
||||
BOUNCE_SPEED,
|
||||
CORNER_INTERVAL_SECONDS,
|
||||
CORNER_MARGIN,
|
||||
AUTO_ANIMATION,
|
||||
} from '/config.js';
|
||||
|
||||
const ASPECT = 9 / 16;
|
||||
@@ -261,33 +262,54 @@ export function startCorners(context) {
|
||||
|
||||
// --- registry -----------------------------------------------------------
|
||||
|
||||
export const ANIMATIONS = [
|
||||
{ name: 'bounce', start: startBounce },
|
||||
{ name: 'corners', start: startCorners },
|
||||
];
|
||||
// Keyed by the names in config.js, which is what travels over the socket.
|
||||
export const ANIMATIONS = {
|
||||
bounce: startBounce,
|
||||
corners: startCorners,
|
||||
};
|
||||
|
||||
const NAMES = Object.keys(ANIMATIONS);
|
||||
|
||||
/**
|
||||
* Run one animation at a time, swapping to a freshly picked one on next().
|
||||
* Returns the handle the player drives from its track changes.
|
||||
* Run one animation at a time. In auto mode next() swaps to a freshly picked
|
||||
* one on every track change; pinned to a name (from the queue page, for
|
||||
* testing) it stays put until the mode changes again.
|
||||
*/
|
||||
export function startAnimationCycle(context) {
|
||||
const picker = createPicker(ANIMATIONS.length);
|
||||
export function startAnimationCycle(context, mode = AUTO_ANIMATION) {
|
||||
const picker = createPicker(NAMES.length);
|
||||
let stop = null;
|
||||
let current = null;
|
||||
|
||||
function next() {
|
||||
function run(name) {
|
||||
stop?.();
|
||||
current = ANIMATIONS[picker.next()];
|
||||
stop = current.start(context);
|
||||
return current.name;
|
||||
current = name;
|
||||
stop = ANIMATIONS[name](context);
|
||||
return current;
|
||||
}
|
||||
|
||||
next();
|
||||
function next() {
|
||||
// Pinned: the track changed, but the operator asked for this one.
|
||||
if (mode !== AUTO_ANIMATION) return current;
|
||||
return run(NAMES[picker.next()]);
|
||||
}
|
||||
|
||||
function setMode(value) {
|
||||
mode = ANIMATIONS[value] ? value : AUTO_ANIMATION;
|
||||
// Always restarts, so switching back to auto takes effect immediately
|
||||
// rather than waiting out the current track.
|
||||
return mode === AUTO_ANIMATION ? run(NAMES[picker.next()]) : run(mode);
|
||||
}
|
||||
|
||||
setMode(mode);
|
||||
|
||||
return {
|
||||
next,
|
||||
setMode,
|
||||
get mode() {
|
||||
return mode;
|
||||
},
|
||||
get name() {
|
||||
return current?.name ?? null;
|
||||
return current;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user