Clickable previews: every still links to its exact app frame
New shared component src/ui/preview.js (appFrameUrl + previewLink): song + seed + frame + venue/venueSel deep-links. App honors ?frame= (warm seek on bank-song load) and ?venueSel= via shared pinVenueShell helper (src/venues/pin.js), which filmstrip and venue-gallery now also use. Filmstrip figures and venue-gallery cards wrap canvases; gallery cells stay unlinked (isolated scene probes, not reproducible in-app).
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
// Pin one venue shell onto a look.
|
||||
//
|
||||
// The same shell-swap in three places: the filmstrip's `venueSel`, the venue
|
||||
// gallery's venue picker, and the app's `?venueSel=`. Only the shell is
|
||||
// forced — module/name/archetype. The VenueSpec population stays the census
|
||||
// one (counts overlap between archetypes), so this is what makes a pinned
|
||||
// preview the exact image the app reproduces, rather than a nearby one.
|
||||
|
||||
import { venues } from './registry.js';
|
||||
|
||||
/**
|
||||
* Force `look.venue` to render as the named venue.
|
||||
*
|
||||
* @param {object} look LookSpec from generateLook (mutated in place)
|
||||
* @param {string} name venue name, e.g. 'Ride'
|
||||
* @param {object} [opts]
|
||||
* @param {number} [opts.seed] seed for a from-scratch spec (default 1)
|
||||
* @param {boolean} [opts.buildIfMissing] build a neutral spec when the
|
||||
* census produced no venue at all (the venue gallery does; the filmstrip
|
||||
* keeps the no-venue video instead)
|
||||
* @returns {boolean} true when a venue is pinned afterwards
|
||||
*/
|
||||
export function pinVenueShell(look, name, { seed = 1, buildIfMissing = false } = {}) {
|
||||
if (!name || !look) return false;
|
||||
const picked = venues.find((v) => v.name === name);
|
||||
if (!picked) throw new Error(`unknown venue "${name}"`);
|
||||
if (!look.venue) {
|
||||
if (!buildIfMissing) return false;
|
||||
look.venue = {
|
||||
archetype: picked.archetype, name: picked.name, seed,
|
||||
shell: { kind: picked.archetype }, projection: { kind: 'screen' },
|
||||
population: { kind: 'scatter', count: 5, spread: 0.7, jitter: 0.25 },
|
||||
paletteMap: [0, 1, 2, 3],
|
||||
perSection: (look.sections || []).map(
|
||||
() => ({ light: 0.7, fog: 0.35, popMul: 0.65, reachMul: 0.85 })),
|
||||
venue: true, readsDepth: false, module: picked,
|
||||
};
|
||||
return true;
|
||||
}
|
||||
look.venue.module = picked;
|
||||
look.venue.name = picked.name;
|
||||
look.venue.archetype = picked.archetype;
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user