look: fix scrolling to sections
Some checks failed
/ deploy (push) Failing after 2s

This fixes:

1. The inability to scroll down to 'contacts' and other lower sections.
   We just expand the second-to-last section to allow the browser to
   scroll.
2. Updating the currently active section - this now uses a global view
   of all visible sections that is updated by the observer diff, thereby
   fixing the logic.
This commit is contained in:
q3k 2025-04-13 19:00:56 +02:00
parent 6da5da5bee
commit 06ff6d32e8
2 changed files with 30 additions and 13 deletions

View file

@ -156,6 +156,12 @@
z-index: 10000;
}
/* Allow to scroll past the last section, needed for fragment-directed navigation. */
section#contact {
min-height: 100vh;
}
/* Fix scrolling to section by fragment, making sure it shows in the right spot and not behind the navbar. */
section {
scroll-margin-top: calc(var(--spacing) * 16 + var(--spacing) * 4);
}
}

View file

@ -6,7 +6,7 @@ export const linksOrder: Array<Sections> = [
"tickets",
"cfp",
"details",
"contact"
"contact",
]
export function useColorSections(parent: React.RefObject<HTMLDivElement | null>) {
@ -27,6 +27,7 @@ export function useColorSections(parent: React.RefObject<HTMLDivElement | null>)
acc[value] = parent.current!.querySelector('[data-sub="' + value + '"]')!;
return acc;
}, {} as Record<Sections, HTMLAnchorElement>);
console.log(subs);
const links = linksOrder.reduce((acc, value) => {
acc[value] = parent.current!.querySelector('[href="#' + value + '"]')!;
return acc;
@ -34,22 +35,32 @@ export function useColorSections(parent: React.RefObject<HTMLDivElement | null>)
console.log(links)
const observer = new IntersectionObserver((entries) => {
// Set of currently intersecting sections by ID.
let intersecting: Set<string> = new Set;
const observer = new IntersectionObserver((entries) => {
// Update intersection set based on diff.
let startedIntersecting: Set<string> = new Set;
let stoppedIntersecting: Set<string> = new Set;
for (const entry of entries) {
const target = entry.target.id as Sections
if (entry.isIntersecting) {
// FIXME: This seems to be VERY broken on firefox.
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1250972
// It basically spikes up CPU usage to some enormous values just to update the hash, like WTF firefox.
// if (history.replaceState) {
// timeout = setTimeout(() => {
// history.replaceState(null, "", `#${target}`)
// }, 150)
// }
startedIntersecting.add(entry.target.id);
} else {
stoppedIntersecting.add(entry.target.id);
}
}
intersecting = intersecting.difference(stoppedIntersecting);
intersecting = intersecting.union(startedIntersecting);
console.log(intersecting);
// Act upon intersection set to find the highest intersecting section -
// that's our 'active' section.
for (const id of linksOrder) {
if (intersecting.has(id)) {
console.log("best: " + id);
subs[previous.current]?.classList.remove('scale-x-100');
links[previous.current]?.classList.remove('text-primary');
previous.current = target;
previous.current = id;
subs[previous.current]?.classList.add('scale-x-100');
links[previous.current]?.classList.add('text-primary');