Compare commits

...

1 commit

Author SHA1 Message Date
q3k 8c52de0616 look: fix scrolling to sections
Some checks failed
/ deploy (push) Failing after 2s
This fixes:

1. Sections overlapping with navbar when linked to. The fix is dirty,
   it's just a margin.
2. 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.
3. 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.
2025-04-13 19:03:03 +02:00
3 changed files with 29 additions and 13 deletions

View file

@ -51,7 +51,7 @@ function NewSection({
after?: ReactElement;
}) {
return (<section id={id} className="bg-background">
<div className="container mx-auto px-4 gap-6 flex flex-col">
<div className="container mx-auto px-4 gap-6 flex flex-col mt-20">
{children}
{after}
</div>

View file

@ -155,3 +155,8 @@
.z-max {
z-index: 10000;
}
/* Allow to scroll past the last section, needed for fragment-directed navigation. */
section#contact {
min-height: 100vh;
}

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');