Skip to content

Commit 79f7b6e

Browse files
added intersection observer for nav
1 parent ad70ee2 commit 79f7b6e

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

src/components/ui/NavigationBar.tsx

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import { cn } from "@/lib/utils";
2-
import {
3-
AnimatePresence,
4-
motion,
5-
useScroll,
6-
useMotionValueEvent,
7-
} from "motion/react";
2+
import { AnimatePresence, motion } from "motion/react";
83
import { Cross as HamburgerCross } from "hamburger-react";
94
import { useEffect, useState, useRef } from "react";
105

@@ -25,10 +20,48 @@ export const HoverNavigation = ({
2520
className?: string;
2621
}) => {
2722
const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
23+
const [activeIndex, setActiveIndex] = useState<number | null>(null);
2824
const [hamburgerOpen, setHamburgerOpen] = useState(false);
2925
const hamburgerRef = useRef<HTMLDivElement>(null);
3026
const menuRef = useRef<HTMLDivElement>(null);
3127

28+
// Track which section is in view
29+
useEffect(() => {
30+
const sectionIds = items.map((item) => {
31+
const url = new URL(item.link, window.location.origin);
32+
return url.hash.replace("#", "");
33+
});
34+
35+
const observers: IntersectionObserver[] = [];
36+
37+
sectionIds.forEach((id, idx) => {
38+
if (!id) return;
39+
40+
const element = document.getElementById(id);
41+
if (!element) return;
42+
43+
const observer = new IntersectionObserver(
44+
(entries) => {
45+
entries.forEach((entry) => {
46+
if (entry.isIntersecting) {
47+
setActiveIndex(idx);
48+
}
49+
});
50+
},
51+
{
52+
rootMargin: "-20% 0px -50% 0px",
53+
},
54+
);
55+
56+
observer.observe(element);
57+
observers.push(observer);
58+
});
59+
60+
return () => {
61+
observers.forEach((observer) => observer.disconnect());
62+
};
63+
}, [items]);
64+
3265
useEffect(() => {
3366
const handleClickOutside = (event: MouseEvent) => {
3467
if (
@@ -48,6 +81,9 @@ export const HoverNavigation = ({
4881
};
4982
}, [hamburgerOpen]);
5083

84+
// Use hoveredIndex when hovering, otherwise use activeIndex
85+
const displayIndex = hoveredIndex !== null ? hoveredIndex : activeIndex;
86+
5187
return (
5288
<>
5389
<div className="bg-secondary/50 fixed top-5 left-1/2 z-30 box-border hidden -translate-x-1/2 items-center justify-center overflow-auto rounded-[40px] border-2 border-solid border-gray-700 px-5 py-3 backdrop-blur-md md:flex md:w-11/12 lg:w-2/3 xl:w-auto">
@@ -76,7 +112,7 @@ export const HoverNavigation = ({
76112
}
77113
>
78114
<AnimatePresence>
79-
{hoveredIndex === idx && (
115+
{displayIndex === idx && (
80116
<motion.span
81117
className="absolute inset-0 z-10 block h-full w-full rounded-3xl bg-neutral-100"
82118
layoutId="hoverBackground"

src/pages/projects.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Footer from "../components/global/FooterComponent.astro";
1010
description="View what projects RythonDev has made"
1111
thumbnail="/images/profile/contact_photo.webp"
1212
>
13-
<div id="projects" class="pt-20">
13+
<div class="pt-20">
1414
<h1 class="mt-10 text-center text-5xl">Projects</h1>
1515
<!-- other projects -->
1616
<MoreProjects />

0 commit comments

Comments
 (0)