@@ -14,28 +14,44 @@ function ScrollIcons() {
1414 const scrollContainer = scrollRef . current ;
1515
1616 if ( ! scrollContainer ) return ;
17- let currentScrollPosition = 0 ;
1817
19- const startScrolling = ( ) => {
20- const move = ( ) => {
18+ const mediaQuery = typeof window !== 'undefined' && 'matchMedia' in window ? window . matchMedia ( '(prefers-reduced-motion: reduce)' ) : null ;
19+ if ( mediaQuery ?. matches ) {
20+ scrollContainer . scrollTo ( 0 , 0 ) ;
21+ return ;
22+ }
23+
24+ let currentScrollPosition = scrollContainer . scrollLeft || 0 ;
25+ let animationFrameId : number | null = null ;
26+ let lastTimestamp = performance . now ( ) ;
27+ const frameDuration = isMobile ? 48 : 30 ; // throttle updates to ~20-30 FPS
28+
29+ const step = ( timestamp : number ) => {
30+ const elapsed = timestamp - lastTimestamp ;
31+
32+ if ( elapsed >= frameDuration ) {
2133 const totalWidth = scrollContainer . scrollWidth ;
2234
23- currentScrollPosition += 1 ; // move 1px per interval
35+ currentScrollPosition += 1 ;
2436 if ( currentScrollPosition >= totalWidth / 2 ) {
25- currentScrollPosition = 0 ; // reset to 0 when it reaches the end
37+ currentScrollPosition = 0 ;
2638 }
2739
2840 scrollContainer . scrollTo ( currentScrollPosition , 0 ) ;
29- } ;
41+ lastTimestamp = timestamp ;
42+ }
3043
31- return setInterval ( move , isMobile ? 48 : 20 ) ; // faster scrolling on desktop
44+ animationFrameId = requestAnimationFrame ( step ) ;
3245 } ;
3346
34- const intervalId = startScrolling ( ) ;
47+ animationFrameId = requestAnimationFrame ( step ) ;
3548
36- // clear interval on unmount
37- return ( ) => clearInterval ( intervalId ) ;
38- } , [ ] ) ;
49+ return ( ) => {
50+ if ( animationFrameId !== null ) {
51+ cancelAnimationFrame ( animationFrameId ) ;
52+ }
53+ } ;
54+ } , [ isMobile ] ) ;
3955 const logos = useMemo (
4056 ( ) => [
4157 ...aboutPageConfig . developers . logos ,
0 commit comments