feat(274): transect composition synced to the lyric
Song274Transect draws Route 274 in its true shape (the "Ground" view of song-274/route/274-transect.html) and plays it along with the song. - data.ts: reads song-274/route/ at load time (lyrics index, roster, route and the optional east/west stubs); nothing is copied into the code. Only sung nodes are shown; districts and 東に続く light nothing. - progress.ts: a "covered so far" paint over the dimmed road. Its head is pinned to each sung object's km as that line starts and glides between pins on a monotone cubic, so it never runs backwards. After 東に続く it runs out along the east stub; the west stub is always painted. - camera.ts: fixed close zoom during each narration part (lines under 20 s apart), following a Gaussian-smoothed head; pull back to frame the covered road plus some road ahead during breaks, and to the full map after the lyric. - nodeAnimation.ts: lightUp / switchOff as reusable functions over a NodeLook, with long lines switching off after MAX_LIT_S. - palette.ts: every colour as a named token (dark default, light alongside), including shrine and railway families. remotion.config.ts sets song-274/ as the public dir so staticFile() reaches the song's audio/ and route/ in place. Verified: eslint + tsc clean; stills checked across parts, breaks and the ending. Render with --muted and add audio with ffmpeg: Remotion's own AAC lands 42.75 ms late. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PLt25nCVMsoroKALYUBu6u
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Every colour the 274 transect video draws, named by what it is for rather than
|
||||
* what it looks like. Change values here, or override `palette` in the Studio's
|
||||
* input props, without touching the drawing code.
|
||||
*
|
||||
* The dark palette is the video's own, grown from the dark palette of
|
||||
* `song-274/route/274-transect.html`; comments name the page's CSS variable each
|
||||
* token corresponds to. The light palette is the page's, extended with the
|
||||
* tokens the video added (shrine, railway).
|
||||
*/
|
||||
export type TransectPalette = {
|
||||
/** Frame background. */
|
||||
background: string;
|
||||
/** The whole road, before the song has covered it. */
|
||||
roadAhead: string;
|
||||
/** The road the song has covered so far. */
|
||||
roadCovered: string;
|
||||
/** Node fill per feature family, as on the page's legend. */
|
||||
bridge: string;
|
||||
tunnel: string;
|
||||
shed: string;
|
||||
watercourse: string;
|
||||
place: string;
|
||||
/** Stations and every 信号場, whatever their roster kind. */
|
||||
railway: string;
|
||||
shrine: string;
|
||||
other: string;
|
||||
};
|
||||
|
||||
export type FeatureFamily =
|
||||
| "bridge"
|
||||
| "tunnel"
|
||||
| "shed"
|
||||
| "watercourse"
|
||||
| "place"
|
||||
| "railway"
|
||||
| "shrine"
|
||||
| "other";
|
||||
|
||||
export const darkPalette: TransectPalette = {
|
||||
background: "#28323d", // --paper
|
||||
roadAhead: "#49565f", // --rule
|
||||
roadCovered: "#9dcde4", // --road
|
||||
bridge: "#79d1c5", // --bridge
|
||||
tunnel: "#b6c5c1", // --tunnel
|
||||
shed: "#eba9eb", // --shed
|
||||
watercourse: "#5FB6D6", // --water
|
||||
place: "#129252", // --place
|
||||
railway: "#129252", // --railway
|
||||
shrine: "#b32c2c", // --shrine
|
||||
other: "#ff9900", // --util
|
||||
};
|
||||
|
||||
export const lightPalette: TransectPalette = {
|
||||
background: "#E7ECEE",
|
||||
roadAhead: "#C0CCD2",
|
||||
roadCovered: "#2E4A5A",
|
||||
bridge: "#116B62",
|
||||
tunnel: "#3A4650",
|
||||
shed: "#7A5AA6",
|
||||
watercourse: "#2F7E9E",
|
||||
place: "#8A6D1F",
|
||||
railway: "#1F6E43",
|
||||
shrine: "#9B2C2C",
|
||||
other: "#5B6B75",
|
||||
};
|
||||
Reference in New Issue
Block a user