fix(hero): prevent nav thrashing with hysteresis

Add hysteresis to IntersectionObserver to prevent rapid toggling
between transparent and opaque nav bar states when scrolling near
the threshold. Now uses different thresholds for hiding (< 10%) vs
showing (> 30%), creating a 20% buffer zone.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-10-20 14:09:42 -05:00
parent 92d50673e5
commit 71b1b933b5
1 changed files with 18 additions and 4 deletions

View File

@ -24,17 +24,31 @@ export function HeroAbacus() {
},
}
// Detect when hero scrolls out of view
// Detect when hero scrolls out of view with hysteresis to prevent thrashing
useEffect(() => {
if (!heroRef.current) return
let currentlyVisible = true // Start as visible (hero starts at top)
const observer = new IntersectionObserver(
([entry]) => {
// Hero is visible if more than 20% is in viewport
setIsHeroVisible(entry.intersectionRatio > 0.2)
// Use hysteresis: different thresholds for showing vs hiding
// When scrolling down (becoming invisible): hide when < 10% visible
// When scrolling up (becoming visible): show when > 30% visible
const ratio = entry.intersectionRatio
if (currentlyVisible && ratio < 0.1) {
// Was visible, now scrolled far enough to hide nav branding
currentlyVisible = false
setIsHeroVisible(false)
} else if (!currentlyVisible && ratio > 0.3) {
// Was hidden, now scrolled far enough to show nav branding
currentlyVisible = true
setIsHeroVisible(true)
}
},
{
threshold: [0, 0.2, 0.5, 1],
threshold: [0, 0.1, 0.3, 0.5, 1],
}
)