@@ -10,33 +10,40 @@ type OrbDef = {
1010
1111export default function OrbsLayer ( ) {
1212 const [ scrollY , setScrollY ] = useState ( 0 ) ;
13+ const scrollYRef = React . useRef ( 0 ) ;
1314
1415 useEffect ( ( ) => {
1516 let raf = 0 as number | 0 ;
16- const onScroll = ( ) => {
17- if ( ! raf ) {
18- raf = requestAnimationFrame ( ( ) => {
19- setScrollY ( window . scrollY || 0 ) ;
20- raf = 0 as number | 0 ;
21- } ) as unknown as number ;
17+ const readScroll = ( ) => ( window . scrollY || 0 ) ;
18+ const update = ( ) => {
19+ raf = 0 as number | 0 ;
20+ const y = readScroll ( ) ;
21+ if ( y !== scrollYRef . current ) {
22+ scrollYRef . current = y ;
23+ setScrollY ( y ) ;
2224 }
2325 } ;
24- onScroll ( ) ;
26+ const onScroll = ( ) => {
27+ if ( ! raf ) raf = requestAnimationFrame ( update ) as unknown as number ;
28+ } ;
29+ // Initialize once
30+ scrollYRef . current = readScroll ( ) ;
31+ setScrollY ( scrollYRef . current ) ;
2532 window . addEventListener ( "scroll" , onScroll , { passive : true } ) ;
33+ window . addEventListener ( "resize" , onScroll , { passive : true } ) ;
2634 return ( ) => {
2735 if ( raf ) cancelAnimationFrame ( raf ) ;
2836 window . removeEventListener ( "scroll" , onScroll ) ;
37+ window . removeEventListener ( "resize" , onScroll ) ;
2938 } ;
3039 } , [ ] ) ;
3140
3241 const parallaxY = useMemo ( ( ) => {
33- // Slight parallax: move a bit slower than content
3442 return - ( scrollY * 0.06 ) ;
3543 } , [ scrollY ] ) ;
3644
37- // Generate a smooth HSL color based on scroll position and orb index
3845 const colorFor = ( index : number ) : string => {
39- const hue = ( scrollY * 0.12 + index * 28 ) % 360 ; // scroll-driven hue with per-orb phase offset
46+ const hue = ( scrollY * 0.12 + index * 28 ) % 360 ;
4047 const saturation = 70 ;
4148 const lightness = 62 ;
4249 return `hsl(${ hue } deg ${ saturation } % ${ lightness } %)` ;
0 commit comments