feat: floodlit roadside billboard carries the selected-builds case studies
This commit is contained in:
@@ -37,6 +37,8 @@ import { createMaintenanceWindow } from '@/scene/world/maintenance-window';
|
||||
import { createHeadlights } from '@/scene/world/headlights';
|
||||
import { maintenanceProgress } from '@/journey/maintenance-progress';
|
||||
import { createMilestones } from '@/scene/world/milestones';
|
||||
import { billboardNear, createBillboard, textureSize } from '@/scene/world/billboard';
|
||||
import { BILLBOARD_NUDGE } from '@/scene/world/composition';
|
||||
import { isMilestoneSection, sectionLocalProgress } from '@/journey/route-log';
|
||||
import { dawnStep, type DawnStep } from '@/journey/dawn';
|
||||
import { dawnLightUniforms } from '@/scene/world/dawn-light';
|
||||
@@ -174,7 +176,15 @@ export async function createProceduralSceneGeneration(
|
||||
// MILE MARKERS: kilometre posts roll past through Experience and Profile.
|
||||
// Low tier and touch draw them without beam, pulse or flash.
|
||||
const milestones = createMilestones(context.resources, maintenanceTier === 'full');
|
||||
// DRIVE-IN: the Selected builds billboard. Low tier and touch: one steady
|
||||
// flood, no pulse, flicker or hover zoom, 512 px screens.
|
||||
const billboard = createBillboard(context.resources, {
|
||||
mode: maintenanceTier,
|
||||
textureSize: textureSize(context.quality),
|
||||
});
|
||||
let billboardKey = '';
|
||||
scene.add(
|
||||
billboard.mesh,
|
||||
maintenance.group,
|
||||
milestones.mesh,
|
||||
milestones.pool,
|
||||
@@ -366,6 +376,19 @@ export async function createProceduralSceneGeneration(
|
||||
musicPulse,
|
||||
deltaSeconds,
|
||||
);
|
||||
const billboardNudge = billboard.update({
|
||||
section: snapshot.activeSectionId,
|
||||
p: snapshot.activeSectionId === 'selected-builds'
|
||||
? sectionLocalProgress(snapshot, 'selected-builds')
|
||||
: null,
|
||||
direction: snapshot.direction,
|
||||
near: billboardNear(snapshot),
|
||||
pulse: musicPulse,
|
||||
energy: overdrive,
|
||||
focus: document.documentElement.dataset.billboardFocus,
|
||||
narrow: camera.aspect <= 1.18,
|
||||
deltaSeconds,
|
||||
});
|
||||
// END OF SHIFT: parked at the destination, the night ends. One scalar
|
||||
// drives it all; leaving rewinds it as fast as the outro returns.
|
||||
const dawn = easeInOutCubic(outroProgress);
|
||||
@@ -511,7 +534,7 @@ export async function createProceduralSceneGeneration(
|
||||
baseComposition.targetZ,
|
||||
upcoming.targetZ,
|
||||
anticipation,
|
||||
),
|
||||
) + BILLBOARD_NUDGE.targetZ * billboardNudge,
|
||||
fov: THREE.MathUtils.lerp(
|
||||
baseComposition.fov,
|
||||
upcoming.fov,
|
||||
@@ -521,7 +544,7 @@ export async function createProceduralSceneGeneration(
|
||||
baseComposition.shift,
|
||||
upcoming.shift,
|
||||
anticipation,
|
||||
),
|
||||
) + BILLBOARD_NUDGE.shift * billboardNudge,
|
||||
};
|
||||
// The document stays native. Only the rendered lens eases to the chapter's safe zone.
|
||||
const cameraX = wideComposition ? composition.x : 0;
|
||||
@@ -682,6 +705,16 @@ export async function createProceduralSceneGeneration(
|
||||
dawnState = nextDawnState;
|
||||
document.documentElement.dataset.dawn = nextDawnState;
|
||||
}
|
||||
if (TEST_BUILD) {
|
||||
const board = billboard.inspect();
|
||||
const key = `${board.progress.activeProjectId}|${board.shown}|${board.floods.map(Math.round).join()}|${Math.round(board.lit * 10)}|${Math.round(board.rise * 10)}|${Math.round(board.zoom * 10)}|${board.flickers}|${board.shimmers}|${board.textures}`;
|
||||
if (key !== billboardKey) {
|
||||
billboardKey = key;
|
||||
window.dispatchEvent(new CustomEvent('portfolio-billboard-frame', {
|
||||
detail: { now, activeSectionId: snapshot.activeSectionId, direction: snapshot.direction, ...board },
|
||||
}));
|
||||
}
|
||||
}
|
||||
if (TEST_BUILD && snapshot.sign !== null) {
|
||||
const presentation = sign.inspect(camera, width, height);
|
||||
if (presentation !== null) {
|
||||
|
||||
Reference in New Issue
Block a user