@@ -1,8 +1,8 @@
"use client" ;
import React , { Suspense , useEffect , useMemo , useRef } from "react" ;
import { Canvas , useFrame } from "@react-three/fiber" ;
import { RoundedBox , Line , Sparkles , Html , useGLTF , ContactShadows , Environment , Lightformer } from "@react-three/drei" ;
import React , { Suspense , useEffect , useMemo , useRef , useState } from "react" ;
import { Canvas , useFrame , useThree } from "@react-three/fiber" ;
import { RoundedBox , Line , Sparkles , Html , useGLTF , ContactShadows , Environment , Lightformer , Preload } from "@react-three/drei" ;
import { EffectComposer , Bloom } from "@react-three/postprocessing" ;
import { KernelSize } from "postprocessing" ;
import * as THREE from "three" ;
@@ -26,6 +26,53 @@ const BLUE = "#3B82F6"; // 03 optimization
const ORANGE = "#F59E0B" ; // 04 grading
const RED = "#C01227" ; // 05 winner
/* ===========================================================================
Dev metrics HUD — enable by appending ?perf to the URL. Samples the live
WebGL renderer (draw calls, triangles, resident geometries/textures, linked
shader programs) plus a rolling FPS, twice a second, into a fixed overlay.
Zero cost when not enabled (component simply isn't mounted).
=========================================================================== */
function PerfHud() {
const gl = useThree ( ( s ) = > s . gl ) ;
const el = useRef < HTMLDivElement | null > ( null ) ;
// Rolling FPS + one-shot timings: page navigation load, and time from this
// canvas mounting to its first rendered frame (≈ Workflow-3 activation cost).
const acc = useRef ( { t : 0 , frames : 0 , mount : 0 , firstFrame : 0 , nav : 0 } ) ;
useEffect ( ( ) = > {
const a = acc . current ;
a . mount = performance . now ( ) ;
const navEntry = performance . getEntriesByType ( "navigation" ) [ 0 ] as PerformanceNavigationTiming | undefined ;
a . nav = navEntry ? Math . round ( navEntry . loadEventEnd || navEntry . domContentLoadedEventEnd ) : 0 ;
const d = document . createElement ( "div" ) ;
d . style . cssText =
"position:fixed;top:10px;left:10px;z-index:99999;font:11px/1.5 ui-monospace,monospace;" +
"background:rgba(0,0,0,.82);color:#39ff14;padding:8px 11px;border-radius:7px;white-space:pre;pointer-events:none" ;
document . body . appendChild ( d ) ;
el . current = d ;
return ( ) = > { d . remove ( ) ; } ;
} , [ ] ) ;
useFrame ( ( _s , dt ) = > {
const a = acc . current ;
if ( ! a . firstFrame && a . mount ) a . firstFrame = performance . now ( ) - a . mount ;
a . frames ++ ; a . t += dt ;
if ( a . t >= 0.5 && el . current ) {
const r = gl . info . render ;
const m = gl . info . memory ;
el . current . textContent =
` FPS ${ ( a . frames / a . t ) . toFixed ( 0 ) } \ n ` +
` draws ${ r . calls } ${ r . calls < 100 ? " ✓" : " ⚠" } \ n ` +
` triangles ${ r . triangles . toLocaleString ( ) } \ n ` +
` geometries ${ m . geometries } \ n ` +
` textures ${ m . textures } \ n ` +
` programs ${ gl . info . programs ? . length ? ? 0 } \ n ` +
` page load ${ a . nav } ms \ n ` +
` WF3 1st fr ${ Math . round ( a . firstFrame ) } ms ` ;
a . frames = 0 ; a . t = 0 ;
}
} ) ;
return null ;
}
/* ===========================================================================
Camera — fully scroll-driven (reads a ref, never React state). Dollies forward
through the world, riding behind+above the active district and looking slightly
@@ -62,13 +109,19 @@ function CameraRig({ progress, reduced, isMobile }: { progress: React.RefObject<
Shared helpers
--------------------------------------------------------------------------- */
/** Fade a district's drei <Html> chips in/out by camera proximity (ref-driven). */
function useLabelFade ( i : number , progress : React.RefObject < number > ) {
/** Fade a district's drei <Html> chips in/out by camera proximity (ref-driven).
* No-ops entirely when the district is asleep (its labels are unmounted then). */
function useLabelFade ( i : number , progress : React.RefObject < number > , awake : boolean ) {
const labels = useRef < HTMLElement [ ] > ( [ ] ) ;
const register = ( el : HTMLElement | null ) = > {
if ( el && ! labels . current . includes ( el ) ) labels . current . push ( el ) ;
} ;
useEffect ( ( ) = > {
// Labels are conditionally rendered, so their refs churn; drop stale ones each time.
if ( ! awake ) labels . current = [ ] ;
} , [ awake ] ) ;
useFrame ( ( ) = > {
if ( ! awake ) return ;
const idx = ( progress . current ? ? 0 ) * ( N - 1 ) ;
const op = THREE . MathUtils . clamp ( 1 - ( Math . abs ( idx - i ) - 0.4 ) / 0.45 , 0 , 1 ) ;
for ( const el of labels . current ) el . style . opacity = String ( op ) ;
@@ -162,14 +215,14 @@ function buildModel(scene: THREE.Object3D, targetSize: number) {
return { root , wheels } ;
}
function GLBVehicle ( { kind } : { kind : string } ) {
function GLBVehicle ( { kind , awake = true } : { kind : string ; awake? : boolean } ) {
const tune = VEH_TUNE [ kind ] ;
const { scene } = useGLTF ( MODELS [ kind ] ) ;
const { root } = useMemo ( ( ) = > buildModel ( scene , tune . size ) , [ scene , tune ] ) ;
const g = useRef < THREE.Group > ( null ) ;
useFrame ( ( state ) = > {
const grp = g . current ;
if ( ! grp ) return ;
if ( ! grp || ! awake ) return ;
const t = state . clock . elapsedTime ;
switch ( kind ) {
case "bike" : grp . position . y = Math . abs ( Math . sin ( t * 3 ) ) * 0.025 ; grp . rotation . z = Math . sin ( t * 3 ) * 0.012 ; break ;
@@ -195,7 +248,7 @@ const TRUCK_FWD_YAW = 0;
* is smoothed with quaternion slerp (always faces travel, never snaps). Wheels spin in
* proportion to distance travelled; a glow ring marks the active segment under the truck.
*/
function RouteTruck ( { route , reduced , i , progress } : { route : THREE.CatmullRomCurve3 ; reduced : boolean ; i : number ; progress : React.RefObject < number > } ) {
function RouteTruck ( { route , reduced , i , progress , awake = true } : { route : THREE.CatmullRomCurve3 ; reduced : boolean ; i : number ; progress : React.RefObject < number > ; awake? : boolean } ) {
const { scene } = useGLTF ( MODELS . truck ) ;
const built = useMemo ( ( ) = > buildModel ( scene , 0.85 ) , [ scene ] ) ;
const wheels = useRef < THREE.Object3D [ ] > ( [ ] ) ;
@@ -207,7 +260,7 @@ function RouteTruck({ route, reduced, i, progress }: { route: THREE.CatmullRomCu
const prevT = useRef ( 0 ) ;
useFrame ( ( state , dt ) = > {
const grp = g . current ;
if ( ! grp ) return ;
if ( ! grp || ! awake ) return ;
const idx = ( progress . current ? ? 0 ) * ( N - 1 ) ;
const t = THREE . MathUtils . clamp ( idx - ( i - 0.5 ) , 0 , 1 ) ; // 0 → hub … 1 → delivery
const pos = route . getPointAt ( t ) ;
@@ -268,22 +321,24 @@ function OrderPacket({ curve, offset }: { curve: THREE.Curve<THREE.Vector3>; off
}
/** A vehicle parked on its own glowing route node (flat on the floor, no white pad). */
function RiderAvatar ( { rider , register } : { rider : typeof RIDERS [ number ] ; register : ( el : HTMLElement | null ) = > void } ) {
function RiderAvatar ( { rider , register , awake } : { rider : typeof RIDERS [ number ] ; register : ( el : HTMLElement | null ) = > void ; awake : boolean } ) {
return (
< group position = { [ rider . x , 0 , ROW_Z ] } >
< mesh position = { [ 0 , 0.014 , 0 ] } rotation = { [ - Math . PI / 2 , 0 , 0 ] } > < ringGeometry args = { [ 0.52 , 0.64 , 36 ] } / > < meshBasicMaterial color = { GREEN } transparent opacity = { 0.6 } side = { THREE . DoubleSide } toneMapped = { false } / > < / mesh >
< mesh position = { [ 0 , 0.008 , 0 ] } rotation = { [ - Math . PI / 2 , 0 , 0 ] } > < circleGeometry args = { [ 0.52 , 36 ] } / > < meshBasicMaterial color = { GREEN } transparent opacity = { 0.08 } side = { THREE . DoubleSide } toneMapped = { false } / > < / mesh >
< group position = { [ 0 , 0.02 , 0 ] } >
< Suspense fallback = { null } >
< GLBVehicle kind = { rider . kind } / >
< GLBVehicle kind = { rider . kind } awake = { awake } / >
< / Suspense >
< / group >
< Html center distanceFactor = { 9 } position = { [ 0 , 1.5 , 0 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-chip" ref = { register } >
< span className = "dm-st3d-chip__ico" > { rider . icon } < / span >
< span className = "dm-st3d-chip__txt " > < b > Rider { rider . id } < / b > { rider . veh } < / span >
< / div >
< / Html >
{ awake && (
< Html center distanceFactor = { 9 } position = { [ 0 , 1.5 , 0 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-chip" ref = { register } >
< span className = "dm-st3d-chip__ico " > { rider . icon } < / span >
< span className = "dm-st3d-chip__txt" > < b > Rider { rider . id } < / b > { rider . veh } < / span >
< / div >
< / Html >
) }
< / group >
) ;
}
@@ -291,11 +346,12 @@ function RiderAvatar({ rider, register }: { rider: typeof RIDERS[number]; regist
const ORDERS_SRC : [ number , number , number ] = [ 3.3 , 0.45 , - 0.7 ] ;
const HUB_CORE : [ number , number , number ] = [ 0 , 0.55 , - 1.4 ] ;
const IntakeHub = React . memo ( function IntakeHub ( { i , progress , reduced } : { i : number ; progress : React.RefObject < number > ; reduced : boolean } ) {
const register = useLabelFade ( i , progress ) ;
const IntakeHub = React . memo ( function IntakeHub ( { i , progress , reduced , awake } : { i : number ; progress : React.RefObject < number > ; reduced : boolean ; awake : boolean } ) {
const register = useLabelFade ( i , progress , awake );
const counter = useRef < HTMLSpanElement > ( null ) ;
const halo = useRef < THREE.Mesh > ( null ) ;
useFrame ( ( state , dt ) = > {
if ( ! awake ) return ;
if ( counter . current ) {
if ( reduced ) counter . current . textContent = "59" ;
else {
@@ -308,14 +364,11 @@ const IntakeHub = React.memo(function IntakeHub({ i, progress, reduced }: { i: n
const intake = useMemo ( ( ) = > lineGeom ( ORDERS_SRC , HUB_CORE ) , [ ] ) ;
const routes = useMemo ( ( ) = > RIDERS . map ( ( r ) = > lineGeom ( HUB_CORE , [ r . x , 0.12 , ROW_Z ] ) ) , [ ] ) ;
return (
< group position = { districtPosition ( i ) } >
< group position = { districtPosition ( i ) } visible = { awake } >
{ /* orders.csv source node → intake route → hub (order packets flowing in) */ }
< GlowNode position = { ORDERS_SRC } color = { GREEN } size = { 0.12 } / >
< Line points = { intake . getPoints ( 2 ) } color = { GREEN } lineWidth = { 1.8 } transparent opacity = { 0.5 } toneMapped = { false } / >
{ ! reduced && [ 0 , 0.5 ] . map ( ( o ) = > < OrderPacket key = { o } curve = { intake } offset = { o } / > ) }
< Html center distanceFactor = { 9 } position = { [ ORDERS_SRC [ 0 ] , ORDERS_SRC [ 1 ] + 0.5 , ORDERS_SRC [ 2 ] ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : GREEN } } ref = { register } > 📄 orders . csv < / div >
< / Html >
{ awake && ! reduced && [ 0 , 0.5 ] . map ( ( o ) = > < OrderPacket key = { o } curve = { intake } offset = { o } / > ) }
{ /* AI Assignment Hub — a grounded dispatch hub (rim ring + hex dais + glowing core + halo) */ }
< group position = { [ 0 , 0 , - 1.4 ] } >
@@ -324,25 +377,33 @@ const IntakeHub = React.memo(function IntakeHub({ i, progress, reduced }: { i: n
< mesh position = { [ 0 , 0.55 , 0 ] } > < icosahedronGeometry args = { [ 0.32 , 1 ] } / > < meshStandardMaterial color = { GREEN } emissive = { GREEN } emissiveIntensity = { 1.2 } toneMapped = { false } flatShading / > < / mesh >
< mesh ref = { halo } position = { [ 0 , 0.55 , 0 ] } rotation = { [ Math . PI / 2.4 , 0 , 0 ] } > < torusGeometry args = { [ 0.5 , 0.025 , 10 , 40 ] } / > < meshStandardMaterial color = { GREEN } emissive = { GREEN } emissiveIntensity = { 1 } toneMapped = { false } / > < / mesh >
< / group >
< Html center distanceFactor = { 9 } position = { [ 0 , 1.8 , - 1.4 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-count" ref = { register } > < span ref = { counter } > 0 < / span > Orders < / div >
< / Html >
< Html center distanceFactor = { 9 } position = { [ 0 , 1.32 , - 1.4 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : GREEN } } ref = { register } > 🤖 AI Assignment Hub < / div >
< / Html >
{ /* assignment routes hub → each vehicle node */ }
{ routes . map ( ( c , j ) = > (
< group key = { j } >
< Line points = { c . getPoints ( 2 ) } color = { GREEN } lineWidth = { 1.6 } transparent opacity = { 0.45 } toneMapped = { false } / >
{ ! reduced && < Packet curve = { c } color = { GREEN } speed = { 0.55 } offset = { j * 0.22 } / > }
{ awake && ! reduced && < Packet curve = { c } color = { GREEN } speed = { 0.55 } offset = { j * 0.22 } / > }
< / group >
) ) }
{ /* soft contact shadow grounding the fleet (baked once for performance) */ }
< ContactShadows position = { [ 0 , 0.02 , ROW_Z ] } scale = { [ 7.5 , 2.6 ] } resolution = { 512 } blur = { 2.6 } far = { 1.2 } opacity = { 0.4 } frames = { 1 } color = "#1e293b" / >
{ RIDERS . map ( ( r ) = > < RiderAvatar key = { r . id } rider = { r } register = { register } / > ) }
{ RIDERS . map ( ( r ) = > < RiderAvatar key = { r . id } rider = { r } register = { register } awake = { awake } / > ) }
{ awake && (
< >
< Html center distanceFactor = { 9 } position = { [ ORDERS_SRC [ 0 ] , ORDERS_SRC [ 1 ] + 0.5 , ORDERS_SRC [ 2 ] ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : GREEN } } ref = { register } > 📄 orders . csv < / div >
< / Html >
< Html center distanceFactor = { 9 } position = { [ 0 , 1.8 , - 1.4 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-count" ref = { register } > < span ref = { counter } > 0 < / span > Orders < / div >
< / Html >
< Html center distanceFactor = { 9 } position = { [ 0 , 1.32 , - 1.4 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : GREEN } } ref = { register } > 🤖 AI Assignment Hub < / div >
< / Html >
< / >
) }
< / group >
) ;
} ) ;
@@ -361,12 +422,12 @@ const STRATS = [
] ;
const CORE : [ number , number , number ] = [ 0 , 1.45 , - 2.7 ] ;
const StrategyNetwork = React . memo ( function StrategyNetwork ( { i , progress , reduced } : { i : number ; progress : React.RefObject < number > ; reduced : boolean } ) {
const register = useLabelFade ( i , progress ) ;
const StrategyNetwork = React . memo ( function StrategyNetwork ( { i , progress , reduced , awake } : { i : number ; progress : React.RefObject < number > ; reduced : boolean ; awake : boolean } ) {
const register = useLabelFade ( i , progress , awake );
const ring = useRef < THREE.Mesh > ( null ) ;
const coreMesh = useRef < THREE.Mesh > ( null ) ;
useFrame ( ( state , dt ) = > {
if ( reduced ) return ;
if ( reduced || ! awake ) return ;
if ( ring . current ) ring . current . rotation . z += dt * 0.6 ;
if ( coreMesh . current ) coreMesh . current . rotation . y += dt * 0.4 ;
} ) ;
@@ -381,7 +442,7 @@ const StrategyNetwork = React.memo(function StrategyNetwork({ i, progress, reduc
[ ] ,
) ;
return (
< group position = { districtPosition ( i ) } >
< group position = { districtPosition ( i ) } visible = { awake } >
{ /* dark tech dais + glowing rim (reads as a control platform, not a white slab) */ }
< mesh position = { [ 0 , 0.06 , - 0.6 ] } > < cylinderGeometry args = { [ 5.4 , 5.6 , 0.12 , 56 ] } / > < meshStandardMaterial color = "#161b30" metalness = { 0.5 } roughness = { 0.42 } emissive = { PURPLE } emissiveIntensity = { 0.07 } / > < / mesh >
< mesh position = { [ 0 , 0.13 , - 0.6 ] } rotation = { [ - Math . PI / 2 , 0 , 0 ] } > < ringGeometry args = { [ 5.2 , 5.42 , 64 ] } / > < meshBasicMaterial color = { PURPLE } transparent opacity = { 0.4 } side = { THREE . DoubleSide } toneMapped = { false } / > < / mesh >
@@ -389,22 +450,26 @@ const StrategyNetwork = React.memo(function StrategyNetwork({ i, progress, reduc
< mesh position = { [ 0 , 0.65 , - 2.7 ] } > < cylinderGeometry args = { [ 0.4 , 0.62 , 1.2 , 24 ] } / > < meshStandardMaterial color = "#2a3350" metalness = { 0.5 } roughness = { 0.4 } / > < / mesh >
< mesh ref = { coreMesh } position = { CORE } > < icosahedronGeometry args = { [ 0.6 , 1 ] } / > < meshStandardMaterial color = { PURPLE } emissive = { PURPLE } emissiveIntensity = { 1.3 } toneMapped = { false } flatShading / > < / mesh >
< mesh ref = { ring } position = { CORE } rotation = { [ Math . PI / 2.4 , 0 , 0 ] } > < torusGeometry args = { [ 0.98 , 0.03 , 10 , 44 ] } / > < meshStandardMaterial color = { PURPLE } emissive = { PURPLE } emissiveIntensity = { 1.1 } toneMapped = { false } / > < / mesh >
< Html center distanceFactor = { 9 } position = { [ 0 , 2.5 , - 2.7 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : PURPLE } } ref = { register } > 🤖 AI Engine < / div >
< / Html >
{ awake && (
< Html center distanceFactor = { 9 } position = { [ 0 , 2.5 , - 2.7 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : PURPLE } } ref = { register } > 🤖 AI Engine < / div >
< / Html >
) }
{ lanes . map ( ( l , j ) = > {
const col = l . unified ? PURPLE : "#a99bd6" ;
return (
< group key = { l . name } >
< Line points = { l . curve . getPoints ( 2 ) } color = { col } lineWidth = { l . unified ? 2.4 : 1.6 } transparent opacity = { l . unified ? 0.7 : 0.5 } toneMapped = { false } / >
{ ! reduced && < Packet curve = { l . curve } color = { col } speed = { 0.5 } offset = { j * 0.16 } size = { l . unified ? 0.075 : 0.06 } / > }
{ awake && ! reduced && < Packet curve = { l . curve } color = { col } speed = { 0.5 } offset = { j * 0.16 } size = { l . unified ? 0.075 : 0.06 } / > }
{ /* flat glowing route node (consistent with the dispatch network) */ }
< mesh position = { [ l . end [ 0 ] , 0.135 , l . end [ 2 ] ] } rotation = { [ - Math . PI / 2 , 0 , 0 ] } > < ringGeometry args = { [ 0.34 , 0.44 , 28 ] } / > < meshBasicMaterial color = { col } transparent opacity = { l . unified ? 0.6 : 0.4 } side = { THREE . DoubleSide } toneMapped = { false } / > < / mesh >
< GlowNode position = { l . end } color = { col } size = { l . unified ? 0.15 : 0.11 } / >
< Html center distanceFactor = { 9 } position = { [ l . end [ 0 ] , l . end [ 1 ] + 0.62 , l . end [ 2 ] ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = { ` dm-st3d-tag ${ l . unified ? "is-u" : "is-muted" } ` } style = { { [ "--tc" as string ] : l . unified ? PURPLE : "#94a3b8" } } ref = { register } > { l . name } < / div >
< / Html >
{ awake && (
< Html center distanceFactor = { 9 } position = { [ l . end [ 0 ] , l . end [ 1 ] + 0.62 , l . end [ 2 ] ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = { ` dm-st3d-tag ${ l . unified ? "is-u" : "is-muted" } ` } style = { { [ "--tc" as string ] : l . unified ? PURPLE : "#94a3b8" } } ref = { register } > { l . name } < / div >
< / Html >
) }
< / group >
) ;
} ) }
@@ -467,8 +532,8 @@ function DeliveryBadge({ pos, i, progress }: { pos: [number, number, number]; i:
) ;
}
const CityRouteMap = React . memo ( function CityRouteMap ( { i , progress , reduced } : { i : number ; progress : React.RefObject < number > ; reduced : boolean } ) {
const register = useLabelFade ( i , progress ) ;
const CityRouteMap = React . memo ( function CityRouteMap ( { i , progress , reduced , awake } : { i : number ; progress : React.RefObject < number > ; reduced : boolean ; awake : boolean } ) {
const register = useLabelFade ( i , progress , awake );
// OPEN delivery path (Dispatch Hub → … → Delivery). Static "road"; only the truck moves.
const route = useMemo ( ( ) = > {
const pts = [ DEPOT3 , . . . DEST ] . map ( ( [ x , z ] ) = > new THREE . Vector3 ( x , 0.12 , z ) ) ;
@@ -477,11 +542,11 @@ const CityRouteMap = React.memo(function CityRouteMap({ i, progress, reduced }:
const routePts = useMemo ( ( ) = > route . getPoints ( 100 ) , [ route ] ) ;
const delivery = DEST [ DEST . length - 1 ] ;
return (
< group position = { districtPosition ( i ) } >
< group position = { districtPosition ( i ) } visible = { awake } >
{ /* STATIC delivery route (the road) — no flowing lines; the truck is the only mover */ }
< Line points = { routePts } color = { BLUE } lineWidth = { 2.6 } transparent opacity = { 0.8 } toneMapped = { false } / >
< Suspense fallback = { null } >
< RouteTruck route = { route } reduced = { reduced } i = { i } progress = { progress } / >
< RouteTruck route = { route } reduced = { reduced } i = { i } progress = { progress } awake = { awake } / >
< / Suspense >
{ /* dispatch hub (static) */ }
@@ -490,41 +555,46 @@ const CityRouteMap = React.memo(function CityRouteMap({ i, progress, reduced }:
< mesh position = { [ 0 , 0.13 , 0 ] } > < cylinderGeometry args = { [ 0.5 , 0.58 , 0.26 , 6 ] } / > < meshStandardMaterial color = "#0f2036" emissive = { BLUE } emissiveIntensity = { 0.15 } metalness = { 0.4 } roughness = { 0.45 } / > < / mesh >
< GlowNode position = { [ 0 , 0.52 , 0 ] } color = { BLUE } size = { 0.14 } / >
< / group >
< Html center distanceFactor = { 9 } position = { [ DEPOT3 [ 0 ] , 1.05 , DEPOT3 [ 1 ] ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : BLUE } } ref = { register } > 🏢 Dispatch Hub < / div >
< / Html >
{ /* route nodes + delivery destination */ }
{ /* route nodes + delivery destination (static geometry; labels gated below) */ }
{ DEST . map ( ( [ x , z ] , j ) = > {
const label = DEST_LABELS [ j ] ;
const isDelivery = j === DEST . length - 1 ;
return (
< group key = { j } position = { [ x , 0 , z ] } >
< mesh position = { [ 0 , 0.02 , 0 ] } rotation = { [ - Math . PI / 2 , 0 , 0 ] } > < ringGeometry args = { [ 0.16 , 0.23 , 20 ] } / > < meshBasicMaterial color = { BLUE } transparent opacity = { 0.55 } side = { THREE . DoubleSide } toneMapped = { false } / > < / mesh >
< mesh position = { [ 0 , 0.3 , 0 ] } > < cylinderGeometry args = { [ 0.03 , 0.03 , 0.6 , 8 ] } / > < meshStandardMaterial color = { BLUE } emissive = { BLUE } emissiveIntensity = { 0.4 } / > < / mesh >
< GlowNode position = { [ 0 , 0.66 , 0 ] } color = { BLUE } size = { isDelivery ? 0.16 : 0.12 } / >
{ label && (
< Html center distanceFactor = { 9 } position = { [ 0 , 1.06 , 0 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : BLUE } } ref = { register } > { label } < / div >
< / Html >
) }
< / group >
) ;
} ) }
{ /* delivery arrival pulse + completion badge (only when the truck arr ives ) */ }
< DeliveryPulse pos = { [ delivery [ 0 ] , 0.02 , delivery [ 1 ] ] } i = { i } progress = { progress } / >
< DeliveryBadge pos = { [ delivery [ 0 ] , 1.42 , delivery [ 1 ] ] } i = { i } progress = { progress } / >
{ /* delivery arrival pulse (only mounted/animated while this district is act ive) */ }
{ awake && <DeliveryPulse pos = { [ delivery [ 0 ] , 0.02 , delivery [ 1 ] ] } i = { i } progress = { progress } / > }
{ /* validation overlays + optimization result */ }
{ VALIDATIONS . map ( ( v ) = > (
< Html key = { v . t } center distanceFactor = { 9 } position = { v . p } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : BLUE } } ref = { register } > ✓ { v . t } < / div >
< / Html >
) ) }
< Html center distanceFactor = { 9 } position = { [ 0 , 3.2 , - 0.4 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-score" style = { { [ "--tc" as string ] : BLUE } } ref = { register } > 🗺 ️ Route optimized · < b > − 18 % < / b > distance < / div >
< / Html >
{ awake && (
< >
< Html center distanceFactor = { 9 } position = { [ DEPOT3 [ 0 ] , 1.05 , DEPOT3 [ 1 ] ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : BLUE } } ref = { register } > 🏢 Dispatch Hub < / div >
< / Html >
{ DEST . map ( ( [ x , z ] , j ) = > {
const label = DEST_LABELS [ j ] ;
return label ? (
< Html key = { j } center distanceFactor = { 9 } position = { [ x , 1.06 , z ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : BLUE } } ref = { register } > { label } < / div >
< / Html >
) : null ;
} ) }
< DeliveryBadge pos = { [ delivery [ 0 ] , 1.42 , delivery [ 1 ] ] } i = { i } progress = { progress } / >
{ VALIDATIONS . map ( ( v ) = > (
< Html key = { v . t } center distanceFactor = { 9 } position = { v . p } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-tag" style = { { [ "--tc" as string ] : BLUE } } ref = { register } > ✓ { v . t } < / div >
< / Html >
) ) }
< Html center distanceFactor = { 9 } position = { [ 0 , 3.2 , - 0.4 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-score" style = { { [ "--tc" as string ] : BLUE } } ref = { register } > 🗺 ️ Route optimized · < b > − 18 % < / b > distance < / div >
< / Html >
< / >
) }
< / group >
) ;
} ) ;
@@ -540,8 +610,8 @@ const KPIS = [
{ n : "Battery" , v : 100 , a : 0.66 } ,
] ;
const CommandCenter = React . memo ( function CommandCenter ( { i , progress } : { i : number ; progress : React.RefObject < number > } ) {
const register = useLabelFade ( i , progress ) ;
const CommandCenter = React . memo ( function CommandCenter ( { i , progress , awake } : { i : number ; progress : React.RefObject < number > ; awake : boolean } ) {
const register = useLabelFade ( i , progress , awake );
const screens = useMemo (
( ) = >
KPIS . map ( ( k ) = > {
@@ -552,7 +622,7 @@ const CommandCenter = React.memo(function CommandCenter({ i, progress }: { i: nu
[ ] ,
) ;
return (
< group position = { districtPosition ( i ) } >
< group position = { districtPosition ( i ) } visible = { awake } >
< mesh position = { [ 0 , 0.45 , 1.4 ] } rotation = { [ - 0.12 , 0 , 0 ] } > < boxGeometry args = { [ 5.6 , 0.18 , 1.5 ] } / > < meshStandardMaterial color = "#dfe4f1" metalness = { 0.4 } roughness = { 0.4 } / > < / mesh >
< mesh position = { [ 0 , 0.12 , 0.9 ] } > < boxGeometry args = { [ 5.2 , 0.24 , 0.6 ] } / > < meshStandardMaterial color = "#cdd5e6" metalness = { 0.3 } roughness = { 0.5 } / > < / mesh >
@@ -561,19 +631,23 @@ const CommandCenter = React.memo(function CommandCenter({ i, progress }: { i: nu
< RoundedBox args = { [ 1.7 , 1.15 , 0.06 ] } radius = { 0.06 } smoothness = { 2 } >
< meshStandardMaterial color = "#ffffff" emissive = { ORANGE } emissiveIntensity = { 0.18 } metalness = { 0.1 } roughness = { 0.4 } transparent opacity = { 0.92 } / >
< / RoundedBox >
< Html center distanceFactor = { 8 } position = { [ 0 , 0 , 0.05 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-kpi" style = { { [ "--tc" as string ] : ORANGE } } ref = { register } >
< span className = "dm-st3d-kpi__n" > { s . n } < / span >
< span className = "dm-st3d-kpi__v " > { s . v } < i > % < / i > < / span >
< span className = "dm-st3d-kpi__bar " > < i style = { { width : ` $ {s . v }% ` } } / > < / span >
< / div >
< / Html >
{ awake && (
< Html center distanceFactor = { 8 } position = { [ 0 , 0 , 0.05 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-kpi" style = { { [ "--tc" as string ] : ORANGE } } ref = { register } >
< span className = "dm-st3d-kpi__n " > { s . n } < / span >
< span className = "dm-st3d-kpi__v " > { s . v }< i > % < / i > < / span >
< span className = "dm-st3d-kpi__bar" > < i style = { { width : ` ${ s . v } % ` } } / > < / span >
< / div >
< / Html >
) }
< / group >
) ) }
< Html center distanceFactor = { 9 } position = { [ 0 , 3.1 , - 0.4 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-score" style = { { [ "--tc" as string ] : ORANGE } } ref = { register } > Perform anc e Grade < b > A < / b > · 4.5 / 5 < / div >
< / Html >
{ awake && (
< Html center distanceFactor = { 9 } position = { [ 0 , 3.1 , - 0.4 ] } zIndexR ang e= { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-score" style = { { [ "--tc" as string ] : ORANGE } } ref = { register } > Performance Grade < b > A < / b > · 4.5 / 5 < / div >
< / Html >
) }
< / group >
) ;
} ) ;
@@ -589,7 +663,7 @@ const PODIUM = [
{ n : "Proximity" , v : 64 , x : 2.4 , win : false } ,
] ;
function Pillar ( { p , register } : { p : typeof PODIUM [ number ] ; register : ( el : HTMLElement | null ) = > void } ) {
function Pillar ( { p , register , awake } : { p : typeof PODIUM [ number ] ; register : ( el : HTMLElement | null ) = > void ; awake : boolean } ) {
const h = 0.6 + ( p . v / 100 ) * 2.2 ;
const col = p . win ? RED : "#94a3b8" ;
return (
@@ -598,30 +672,32 @@ function Pillar({ p, register }: { p: typeof PODIUM[number]; register: (el: HTML
< boxGeometry args = { [ 1.0 , h , 1.0 ] } / >
< meshStandardMaterial color = { col } emissive = { col } emissiveIntensity = { p . win ? 0.7 : 0.15 } metalness = { 0.2 } roughness = { 0.4 } transparent opacity = { p . win ? 0.96 : 0.7 } toneMapped = { false } / >
< / mesh >
< Html center distanceFactor = { 9 } position = { [ 0 , h + 0.45 , 0 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = { ` dm-st3d-tag ${ p . win ? "is-win" : "is-muted" } ` } style = { { [ "--tc" as string ] : col } } ref = { register } > < b > { p . v } % < / b > & nbsp ; { p . n } < / div >
< / Html >
{ awake && (
< Html center distanceFactor = { 9 } position = { [ 0 , h + 0.45 , 0 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = { ` dm-st3d-tag ${ p . win ? "is-win" : "is-muted" } ` } style = { { [ "--tc" as string ] : col } } ref = { register } > < b > { p . v } % < / b > & nbsp ; { p . n } < / div >
< / Html >
) }
< / group >
) ;
}
const WinnerPodium = React . memo ( function WinnerPodium ( { i , progress , reduced , isMobile } : { i : number ; progress : React.RefObject < number > ; reduced : boolean ; isMobile : boolean } ) {
const register = useLabelFade ( i , progress ) ;
const WinnerPodium = React . memo ( function WinnerPodium ( { i , progress , reduced , isMobile , awake } : { i : number ; progress : React.RefObject < number > ; reduced : boolean ; isMobile : boolean ; awake : boolean } ) {
const register = useLabelFade ( i , progress , awake );
const trophy = useRef < THREE.Group > ( null ) ;
useFrame ( ( state ) = > {
if ( trophy . current && ! reduced ) {
if ( trophy . current && ! reduced && awake ) {
const winH = 0.6 + ( 88 / 100 ) * 2.2 ;
trophy . current . position . y = winH + 0.95 + Math . sin ( state . clock . elapsedTime * 1.4 ) * 0.08 ;
trophy . current . rotation . y += 0.01 ;
}
} ) ;
return (
< group position = { districtPosition ( i ) } >
< group position = { districtPosition ( i ) } visible = { awake } >
< mesh position = { [ 0 , 0.05 , - 0.6 ] } > < cylinderGeometry args = { [ 4.3 , 4.5 , 0.12 , 48 ] } / > < meshStandardMaterial color = "#1d1622" metalness = { 0.5 } roughness = { 0.42 } emissive = { RED } emissiveIntensity = { 0.06 } / > < / mesh >
< mesh position = { [ 0 , 0.12 , - 0.6 ] } rotation = { [ - Math . PI / 2 , 0 , 0 ] } > < ringGeometry args = { [ 4.1 , 4.32 , 56 ] } / > < meshBasicMaterial color = { RED } transparent opacity = { 0.35 } side = { THREE . DoubleSide } toneMapped = { false } / > < / mesh >
< mesh position = { [ - 2.4 , 0.14 , - 0.6 ] } > < cylinderGeometry args = { [ 0.85 , 0.9 , 0.14 , 28 ] } / > < meshStandardMaterial color = { RED } emissive = { RED } emissiveIntensity = { 0.9 } toneMapped = { false } / > < / mesh >
{ PODIUM . map ( ( p ) = > < Pillar key = { p . n } p = { p } register = { register } / > ) }
{ PODIUM . map ( ( p ) = > < Pillar key = { p . n } p = { p } register = { register } awake = { awake } / > ) }
< mesh position = { [ - 2.4 , 3.0 , - 0.6 ] } > < coneGeometry args = { [ 1.0 , 2.6 , 28 , 1 , true ] } / > < meshBasicMaterial color = { RED } transparent opacity = { 0.07 } side = { THREE . DoubleSide } toneMapped = { false } / > < / mesh >
< group ref = { trophy } position = { [ - 2.4 , 3.5 , - 0.6 ] } >
@@ -630,16 +706,18 @@ const WinnerPodium = React.memo(function WinnerPodium({ i, progress, reduced, is
< mesh position = { [ 0 , - 0.22 , 0 ] } > < cylinderGeometry args = { [ 0.18 , 0.22 , 0.1 , 16 ] } / > < meshStandardMaterial color = "#FFD45A" emissive = "#FFB020" emissiveIntensity = { 1 } toneMapped = { false } / > < / mesh >
< / group >
{ ! reduced && < Sparkles count = { isMobile ? 16 : 28 } scale = { [ 5 , 4 , 4 ] } position = { [ - 2.4 , 2.6 , - 0.6 ] } size = { 3.2 } speed = { 0.5 } opacity = { 0.9 } color = "#ff9aa9" / > }
{ awake && ! reduced && < Sparkles count = { isMobile ? 16 : 28 } scale = { [ 5 , 4 , 4 ] } position = { [ - 2.4 , 2.6 , - 0.6 ] } size = { 3.2 } speed = { 0.5 } opacity = { 0.9 } color = "#ff9aa9" / > }
< Html center distanceFactor = { 9 } position = { [ 0.7 , 3.0 , - 0.6 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-winner3d" ref = { register } >
< span className = "dm-st3d-winner3d__top" > 🏆 Best Strategy < / span >
< span className = "dm-st3d-winner3d__name " > EV Aware < / span >
< span className = "dm-st3d-winner3d__row " > < b > 88 % < / b > Performance Sco re< / span >
< span className = "dm-st3d-winner3d__row" > < b > 52 / 59 < / b > Orders Fulfilled < / span >
< / div >
< / Html >
{ awake && (
< Html center distanceFactor = { 9 } position = { [ 0.7 , 3.0 , - 0.6 ] } zIndexRange = { [ 20 , 0 ] } pointerEvents = "none" >
< div className = "dm-st3d-winner3d" ref = { register } >
< span className = "dm-st3d-winner3d__top " > 🏆 Best Strategy < / span >
< span className = "dm-st3d-winner3d__name " > EV Awa re< / span >
< span className = "dm-st3d-winner3d__row" > < b > 88 % < / b > Performance Score < / span >
< span className = "dm-st3d-winner3d__row" > < b > 52 / 59 < / b > Orders Fulfilled < / span >
< / div >
< / Html >
) }
< / group >
) ;
} ) ;
@@ -704,8 +782,21 @@ function Floor() {
) ;
}
function Scene ( { progress , reduced , isMobile , stage } : { progress : React.RefObject < number > ; reduced : boolean ; isMobile : boolean ; stage : number } ) {
const near = ( i : number ) = > Math . abs ( i - stage ) <= 1 ; // only mount active ± 1 district
function Scene ( { progress , reduced , isMobile , stage , active , perf } : { progress : React.RefObject < number > ; reduced : boolean ; isMobile : boolean ; stage : number ; active : boolean ; perf : boolean } ) {
// Districts stay MOUNTED for the whole scroll (GLB cloned once, shaders compiled
// once → no remount hitch, no blank frames). `near` only toggles per-district
// visibility + per-frame work + <Html> mounting, so off-screen districts render
// nothing and run zero per-frame CPU/DOM cost (only the active ±1 stays awake).
const near = ( i : number ) = > Math . abs ( i - stage ) <= 1 ;
// Defer the expensive post-processing + ambient particles until the section is
// actually active for the first time, then latch them on. This keeps Bloom's
// render targets and the Sparkles buffers from being allocated during initial
// page load / while WF3 is still below the fold — without re-allocating them
// (and hitching) every time the user scrolls past and back.
const [ everActive , setEverActive ] = useState ( false ) ;
useEffect ( ( ) = > { if ( active ) setEverActive ( true ) ; } , [ active ] ) ;
const heavyFx = everActive && ! reduced && ! isMobile ;
return (
< >
< color attach = "background" args = { [ BG ] } / >
@@ -727,26 +818,33 @@ function Scene({ progress, reduced, isMobile, stage }: { progress: React.RefObje
< Floor / >
< DataRoad / >
{ near ( 0 ) && <IntakeHub i = { 0 } progress = { progress } reduced = { reduced } / >}
{ near ( 1 ) && <StrategyNetwork i = { 1 } progress = { progress } reduced = { reduced } / >}
{ near ( 2 ) && <CityRouteMap i = { 2 } progress = { progress } reduced = { reduced } / >}
{ near ( 3 ) && <CommandCenter i = { 3 } progress = { progress } / >}
{ near ( 4 ) && <WinnerPodium i = { 4 } progress = { progress } reduced = { reduced } isMobile = { isMobile } / >}
< IntakeHub i = { 0 } progress = { progress } reduced = { reduced } awake = { near ( 0 ) } / >
< StrategyNetwork i = { 1 } progress = { progress } reduced = { reduced } awake = { near ( 1 ) } / >
< CityRouteMap i = { 2 } progress = { progress } reduced = { reduced } awake = { near ( 2 ) } / >
< CommandCenter i = { 3 } progress = { progress } awake = { near ( 3 ) } / >
< WinnerPodium i = { 4 } progress = { progress } reduced = { reduced } isMobile = { isMobile } awake = { near ( 4 ) } / >
{ ! reduced && ! isMobile && (
{ heavyFx && (
< Sparkles count = { 30 } scale = { [ 18 , 7 , N * 13 ] } position = { [ 0 , 3 , ( - ( N - 1 ) * 13 ) / 2 ] } size = { 2 } speed = { 0.22 } opacity = { 0.35 } color = "#9aa6c4" / >
) }
{ ! reduced && ! isMobile && (
{ heavyFx && (
< EffectComposer multisampling = { 0 } >
< Bloom mipmapBlur intensity = { 0.7 } luminanceThreshold = { 0.74 } luminanceSmoothing = { 0.06 } radius = { 0.68 } kernelSize = { KernelSize . SMALL } / >
< / EffectComposer >
) }
{ /* Compile every material/texture upfront (districts are all mounted) so the
first time a district becomes visible there's no shader-compile stall. */ }
< Preload all / >
{ perf && < PerfHud / > }
< / >
) ;
}
export default function StrategyCanvas ( { progress , reduced = false , isMobile = false , active = true , stage = 0 } : Props ) {
// Opt-in dev metrics overlay: append ?perf to the URL.
const perf = typeof window !== "undefined" && new URLSearchParams ( window . location . search ) . has ( "perf" ) ;
return (
< Canvas
dpr = { [ 1 , isMobile ? 1 : 1.25 ] }
@@ -754,7 +852,7 @@ export default function StrategyCanvas({ progress, reduced = false, isMobile = f
gl = { { antialias : false , powerPreference : "high-performance" , alpha : false } }
frameloop = { active ? "always" : "never" }
>
< Scene progress = { progress } reduced = { reduced } isMobile = { isMobile } stage = { stage } / >
< Scene progress = { progress } reduced = { reduced } isMobile = { isMobile } stage = { stage } active = { active } perf = { perf } / >
< / Canvas >
) ;
}