diff --git a/hooks/useScrollDirection.ts b/hooks/useScrollDirection.ts new file mode 100644 index 0000000..c360c5f --- /dev/null +++ b/hooks/useScrollDirection.ts @@ -0,0 +1,46 @@ +'use client'; + +import { useState, useEffect } from 'react'; + +export type ScrollDirection = 'up' | 'down'; + +/** + * A hook to detect the scroll direction. + * It uses requestAnimationFrame for performance, comparing the current scroll position + * with the previous one to determine if the user is scrolling up or down. + * + * @returns {ScrollDirection | null} The current scroll direction ('up' or 'down'), or null on the initial render. + */ +export function useScrollDirection(): ScrollDirection | null { + const [scrollDirection, setScrollDirection] = useState(null); + + useEffect(() => { + let lastScrollY = window.pageYOffset; + let ticking = false; + + const updateScrollDirection = () => { + const scrollY = window.pageYOffset; + + if (Math.abs(scrollY - lastScrollY) < 10) { + ticking = false; + return; + } + setScrollDirection(scrollY > lastScrollY ? 'down' : 'up'); + lastScrollY = scrollY > 0 ? scrollY : 0; + ticking = false; + }; + + const onScroll = () => { + if (!ticking) { + window.requestAnimationFrame(updateScrollDirection); + ticking = true; + } + }; + + window.addEventListener('scroll', onScroll); + + return () => window.removeEventListener('scroll', onScroll); + }, []); + + return scrollDirection; +} \ No newline at end of file diff --git a/src/components/About.tsx b/src/components/About.tsx index 8641491..d9595fd 100644 --- a/src/components/About.tsx +++ b/src/components/About.tsx @@ -6,10 +6,10 @@ export function About() { return (
- +
diff --git a/src/components/ContentDistribution.tsx b/src/components/ContentDistribution.tsx index c45af40..af24c64 100644 --- a/src/components/ContentDistribution.tsx +++ b/src/components/ContentDistribution.tsx @@ -153,24 +153,31 @@ export default function ContentDistribution({ className, bg = '#ffffff' }: Props {/* central cloud */} - {/* rotating layer with badges */} + {/* rotating layer with badges and beams */} + {/* Beams */} + {layout.map((n, i) => { + const rad = (n.a * Math.PI) / 180; + const x = n.r * Math.cos(rad); + const y = n.r * Math.sin(rad); + return ; + })} + + {/* Badges */} {layout.map((n, i) => { const rad = (n.a * Math.PI) / 180; const x = n.r * Math.cos(rad); const y = n.r * Math.sin(rad); return ( - + {n.icon} - {/* beam from center to this node (animated) */} - ); })} diff --git a/src/components/LinuxLink.tsx b/src/components/LinuxLink.tsx index ede0070..1e0f251 100644 --- a/src/components/LinuxLink.tsx +++ b/src/components/LinuxLink.tsx @@ -8,7 +8,7 @@ export function LinuxLink({ }) { return (