677677 z-index : 0 ;
678678 pointer-events : none;
679679}
680+ .hero-overlay {
681+ position : absolute;
682+ top : 0 ;
683+ left : 0 ;
684+ width : 100% ;
685+ height : 100% ;
686+ background : rgba (0 , 0 , 0 , 0.20 );
687+ z-index : 0 ;
688+ pointer-events : none;
689+ }
680690</ style >
681691< script type ="importmap ">
682692{
683693 "imports" : {
684694 "three" : "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js" ,
685- "three/addons/" : "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"
695+ "three/addons/" : "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/" ,
696+ "three/examples/jsm/" : "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"
686697 }
687698}
688699</ script >
709720
710721< header class ="hero ">
711722 < canvas id ="vendor-graph "> </ canvas >
723+ < div class ="hero-overlay "> </ div >
712724 < div class ="container ">
713725 < h1 class ="hero-title ">
714726 < span class ="lava-text "> < span class ="lava-letter " style ="--i:0 " data-letter ="N "> N</ span > < span class ="lava-letter " style ="--i:1 " data-letter ="t "> t</ span > < span class ="lava-letter " style ="--i:2 " data-letter ="h "> h</ span > < span class ="lava-letter " style ="--i:3 " data-letter =" "> </ span > < span class ="lava-letter " style ="--i:4 " data-letter ="P "> P</ span > < span class ="lava-letter " style ="--i:5 " data-letter ="a "> a</ span > < span class ="lava-letter " style ="--i:6 " data-letter ="r "> r</ span > < span class ="lava-letter " style ="--i:7 " data-letter ="t "> t</ span > < span class ="lava-letter " style ="--i:8 " data-letter ="y "> y</ span > </ span > < br >
@@ -918,6 +930,9 @@ <h2 class="section-title">Ready to Find Your Nth Party?</h2>
918930
919931< script type ="module ">
920932import * as THREE from 'three' ;
933+ import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js' ;
934+ import { RenderPass } from 'three/addons/postprocessing/RenderPass.js' ;
935+ import { BokehPass } from 'three/addons/postprocessing/BokehPass.js' ;
921936
922937// ── CONFIG ──
923938const NODE_COUNT = 120 ;
@@ -1180,11 +1195,22 @@ <h2 class="section-title">Ready to Find Your Nth Party?</h2>
11801195}
11811196
11821197// ── RESIZE ──
1198+ // ── POST-PROCESSING (Depth of Field) ──
1199+ const composer = new EffectComposer ( renderer ) ;
1200+ composer . addPass ( new RenderPass ( scene , camera ) ) ;
1201+ const bokehPass = new BokehPass ( scene , camera , {
1202+ focus : 4.0 ,
1203+ aperture : 0.008 ,
1204+ maxblur : 0.012 ,
1205+ } ) ;
1206+ composer . addPass ( bokehPass ) ;
1207+
11831208function resize ( ) {
11841209 const rect = hero . getBoundingClientRect ( ) ;
11851210 const w = rect . width ;
11861211 const h = rect . height ;
11871212 renderer . setSize ( w , h ) ;
1213+ composer . setSize ( w , h ) ;
11881214 camera . aspect = w / h ;
11891215 camera . updateProjectionMatrix ( ) ;
11901216}
@@ -1202,13 +1228,20 @@ <h2 class="section-title">Ready to Find Your Nth Party?</h2>
12021228 const delta = Math . min ( clock . getDelta ( ) , 0.05 ) ;
12031229
12041230 if ( ! prefersReducedMotion ) {
1205- // Slow camera orbit
1206- const orbitSpeed = 0.06 ;
1207- const angle = elapsed * orbitSpeed ;
1208- camera . position . x = Math . sin ( angle ) * 5.5 ;
1209- camera . position . z = Math . cos ( angle ) * 5.5 ;
1210- camera . position . y = 2.0 + Math . sin ( elapsed * 0.15 ) * 0.5 ;
1211- camera . lookAt ( 0 , 0 , 0 ) ;
1231+ // Slow drifting pan through the network
1232+ const t1 = elapsed * 0.04 ;
1233+ const t2 = elapsed * 0.03 ;
1234+ const t3 = elapsed * 0.025 ;
1235+ camera . position . x = Math . sin ( t1 ) * 4.5 + Math . cos ( t2 * 1.3 ) * 1.5 ;
1236+ camera . position . z = Math . cos ( t1 ) * 4.5 + Math . sin ( t3 * 0.9 ) * 1.5 ;
1237+ camera . position . y = 1.8 + Math . sin ( t2 ) * 1.0 + Math . cos ( t3 * 0.7 ) * 0.5 ;
1238+ // Look at a slowly drifting target (not fixed on center)
1239+ const lookX = Math . sin ( t3 * 1.1 ) * 1.2 ;
1240+ const lookY = Math . sin ( t2 * 0.8 ) * 0.4 ;
1241+ const lookZ = Math . cos ( t3 * 0.6 ) * 1.2 ;
1242+ camera . lookAt ( lookX , lookY , lookZ ) ;
1243+ // Update DOF focus to distance between camera and look target
1244+ bokehPass . uniforms [ 'focus' ] . value = camera . position . distanceTo ( new THREE . Vector3 ( lookX , lookY , lookZ ) ) ;
12121245
12131246 // Pulse primary glow
12141247 const glowScale = 0.35 + 0.08 * Math . sin ( elapsed * 1.5 ) ;
@@ -1253,7 +1286,7 @@ <h2 class="section-title">Ready to Find Your Nth Party?</h2>
12531286 }
12541287 }
12551288
1256- renderer . render ( scene , camera ) ;
1289+ composer . render ( ) ;
12571290}
12581291animate ( ) ;
12591292</ script >
0 commit comments