Venues: song sky, ride roadside, room camera, filmstrip venue pin
- Shared sky dome (src/venues/sky.js): gradient backdrop from palette / section light / style texture, wired into chamber/stage/ride with fog matched to the dome mid colour — replaces clear-to-black - Ride roadside: houses, signs, trees, seeded viz billboard, all analytic scroll; popMul fade for crew, arrangement-gated roadside (no mid-section popping); parked idle creep + engine shake; analytic dash clock - Room camera: traverse glide + progress look sweep + per-section dolly, single-side room visits, one re-hang max; venue framing per archetype - Filmstrip venue selector (?venueSel=) with cache key; seed persisted to URL on reroll; gallery query plumbing
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
|
||||
import { Show, FADE_SECONDS } from '../Show.js';
|
||||
import { generateLook } from '../look/LookGenerator.js';
|
||||
import { venues } from '../venues/registry.js';
|
||||
import { song, SONGS } from '../audio/songbank.js';
|
||||
import { hashString } from '../engine/rng.js';
|
||||
import { frameDescriptor, motionDescriptor } from './variety/descriptors.js';
|
||||
@@ -69,12 +70,22 @@ function blockMean(byBlock) {
|
||||
*
|
||||
* @returns {{name, frames: Array, drift: number, direction: number, look}}
|
||||
*/
|
||||
export function renderSong(show, name, { duration, every, venueEnabled = null }) {
|
||||
export function renderSong(show, name, { duration, every, venueEnabled = null, venueSel = null }) {
|
||||
const { track } = song(name, { duration });
|
||||
// Seeded off the song's name, so a strip is stable between rebuilds and two
|
||||
// songs are not accidentally handed the same look.
|
||||
const venueFlag = venueEnabled !== null ? !!venueEnabled : (typeof location !== 'undefined' && new URLSearchParams(location.search).get('venue') === '1');
|
||||
const look = generateLook(track, { seed: hashString(name), venueEnabled: venueFlag });
|
||||
// Pin one venue in every row (same shell-swap as the venue gallery): the
|
||||
// VenueSpec population stays the census one, only the shell is forced.
|
||||
const sel = venueSel || (typeof location !== 'undefined' && new URLSearchParams(location.search).get('venueSel')) || null;
|
||||
if (sel && look.venue) {
|
||||
const picked = venues.find((v) => v.name === sel);
|
||||
if (!picked) throw new Error(`unknown venue "${sel}"`);
|
||||
look.venue.module = picked;
|
||||
look.venue.name = picked.name;
|
||||
look.venue.archetype = picked.archetype;
|
||||
}
|
||||
show.useTrack(track, look);
|
||||
|
||||
const frames = [];
|
||||
@@ -208,6 +219,7 @@ function momentAt(story, index) {
|
||||
*/
|
||||
export async function buildFilmstrip({
|
||||
duration = DEFAULT_DURATION, every = DEFAULT_EVERY, names = null, venueEnabled = null,
|
||||
venueSel = null,
|
||||
onSong = null, onSongStart = null,
|
||||
} = {}) {
|
||||
const list = names && names.length ? names : songNames();
|
||||
@@ -225,7 +237,7 @@ export async function buildFilmstrip({
|
||||
}
|
||||
let row;
|
||||
try {
|
||||
row = renderSong(show, list[i], { duration, every, venueEnabled });
|
||||
row = renderSong(show, list[i], { duration, every, venueEnabled, venueSel });
|
||||
} catch (err) {
|
||||
row = { name: list[i], frames: [], shots: [], drift: 0, direction: 0, error: err.message };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user