The frame parks in the middle and the colour changes instead: a gradient creeps round the colour wheel behind the poster, and the frame's glow travels with it. Every other animation moves the frame, so the still one reads as a rest between them rather than as a dead spot. The wash layer blends with mix-blend-mode: color, which keeps the poster's luminance and replaces only its hue. soft-light was the first try and barely shifted the colour at all against a poster already knocked back to 45% brightness. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tg15tLAuT6NrCE1ZxKVgDB
81 lines
3.2 KiB
JavaScript
81 lines
3.2 KiB
JavaScript
// Central knobs for the party player.
|
|
|
|
export const PORT = Number(process.env.PORT) || 3000;
|
|
|
|
// Seconds of overlap between the outgoing and incoming video.
|
|
// Audio and video crossfade over this whole window.
|
|
export const OVERLAP_SECONDS = 5;
|
|
|
|
// How fast the player switches when the user jumps around manually.
|
|
export const HARD_CUT_SECONDS = 0.4;
|
|
|
|
// The video frame takes up this fraction of the screen. Keep this below 0.5:
|
|
// the corners animation puts a frame-sized image in all four corners, which
|
|
// only stays overlap-free while two frames fit side by side.
|
|
export const FRAME_SCALE = 0.35;
|
|
|
|
// Pixels per second the frame drifts across the screen.
|
|
export const BOUNCE_SPEED = 120;
|
|
|
|
// The corners animation: seconds between screenshots.
|
|
export const CORNER_INTERVAL_SECONDS = 4;
|
|
|
|
// Gap between the frame and the screen edge, as a fraction of the short side.
|
|
export const CORNER_MARGIN = 0.025;
|
|
|
|
// The drag animation gets its own, roomier base size: it is the only thing on
|
|
// screen while it runs, so it does not have to leave space for a second frame.
|
|
export const DRAG_FRAME_SCALE = 0.6;
|
|
|
|
// The drag animation resizes the frame to somewhere between these multiples of
|
|
// its base size. Above 1 the frame grows past DRAG_FRAME_SCALE, which is
|
|
// fine — nothing else is on screen while this animation runs.
|
|
export const DRAG_MIN_SCALE = 0.55;
|
|
export const DRAG_MAX_SCALE = 1.6;
|
|
|
|
// The trail animation: how fast the frame glides, and how sharply it may turn.
|
|
// The turn cap is what bends the path into an arc — without it the frame would
|
|
// snap onto each new heading and the tail would read as a dotted line.
|
|
export const TRAIL_SPEED = 150;
|
|
export const TRAIL_TURN_RATE = 0.7;
|
|
|
|
// Gap between two dropped stills, in frame widths, and how many the tail holds.
|
|
export const TRAIL_SPACING = 0.6;
|
|
export const TRAIL_LENGTH = 8;
|
|
|
|
// A still's life, from the moment it lands to fully faded.
|
|
export const TRAIL_FADE_SECONDS = 8;
|
|
|
|
// The colour wash: seconds for one full trip round the colour wheel. Slow
|
|
// enough that the screen never looks like it is flashing — the colour should
|
|
// only be obviously different once you look away and back.
|
|
export const WASH_CYCLE_SECONDS = 90;
|
|
|
|
// How far apart the two ends of the wash gradient sit on the wheel, in degrees,
|
|
// and how strongly the wash tints the poster underneath it.
|
|
export const WASH_SPREAD = 70;
|
|
export const WASH_STRENGTH = 0.55;
|
|
|
|
// The frame animations, keyed by the id sent over the socket. The names must
|
|
// match the registry in public/player/motion.js, which supplies the code.
|
|
export const ANIMATIONS = {
|
|
bounce: { label: 'Bounce' },
|
|
corners: { label: 'Corners' },
|
|
drag: { label: 'Drag & resize' },
|
|
trail: { label: 'Comet trail' },
|
|
wash: { label: 'Colour wash' },
|
|
};
|
|
|
|
// Cycle a fresh random animation on every track change. Anything else pins the
|
|
// player to that one animation, which is what the queue page's buttons are for.
|
|
export const AUTO_ANIMATION = 'auto';
|
|
export const DEFAULT_ANIMATION = AUTO_ANIMATION;
|
|
|
|
// Selectable fullscreen backgrounds, keyed by the id sent over the socket.
|
|
export const BACKGROUNDS = {
|
|
pink: { label: 'Pink', src: '/assets/PLAKAT_A2_pink_426x600mm.png' },
|
|
plain: { label: 'Classic', src: '/assets/PLAKAT_A2_426x600mm.png' },
|
|
};
|
|
|
|
export const DEFAULT_BACKGROUND = 'pink';
|