diff --git a/src/pages/index.astro b/src/pages/index.astro index 4c42905..25d2cbd 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -65,4 +65,12 @@ const [intro, ...portfolioSections] = sections; const togglerInstance = new Toggler(NAV_TOGGLE_ID, NAV_ID); togglerInstance.init(); + + // Even with smooth scrolling, this is necessary to mitigate some of + // the issues that arise from `lvh` sections + scroll tracking. + function handleHashChange() { + navTrackerInstance.safeUpdate(portfolioInstance.mostVisibleIndex); + } + + window.addEventListener('hashchange', handleHashChange, false); diff --git a/src/scripts/Portfolio.ts b/src/scripts/Portfolio.ts index e123e97..151f14c 100644 --- a/src/scripts/Portfolio.ts +++ b/src/scripts/Portfolio.ts @@ -34,7 +34,7 @@ export class Portfolio { #scrollHeight = 0; #sectionHeight = 0; - #isTicking = false; + #rafTicking = false; // TODO: There is a bug in Firefox Mobile that causes the "URL bar" to // re-appear everytime the url is updated (ex: via replaceState). I am @@ -106,6 +106,7 @@ export class Portfolio { } teardown() { + window.removeEventListener('hashchange', this.#runAllUpdates); this.scroller.removeEventListener('scroll', this.#handleScroll); window.removeEventListener('resize', this.#handleResize); @@ -113,6 +114,9 @@ export class Portfolio { } #registerEventListeners() { + // Required alongside `handleScroll` for anchor tags. + window.addEventListener('hashchange', this.#runAllUpdates, false); + // `passive` may not actually make sense for `scroll` events. this.scroller.addEventListener('scroll', this.#handleScroll, { passive: true, @@ -172,18 +176,18 @@ export class Portfolio { ); } - #rafCallback = () => { + #runAllUpdates = () => { this.#updateIndex(); this.#updatePortfolioColor(); - this.#isTicking = false; + this.#rafTicking = false; }; #handleScroll = () => { - if (this.#isTicking) return; + if (this.#rafTicking) return; - this.#rafId = requestAnimationFrame(this.#rafCallback); - this.#isTicking = true; + this.#rafId = requestAnimationFrame(this.#runAllUpdates); + this.#rafTicking = true; this.#onScroll?.({ currentIndex: this.currentIndex, diff --git a/src/styles/global.css b/src/styles/global.css index c870c19..b10afdf 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -87,26 +87,23 @@ body { cursor: url('../assets/svg/cursors/CursorAuto.svg'), auto; } -/* --- Smooth scroll + snapping --- */ +/* --- Scroll snapping --- */ html { /* - It is possible that Safari may require this to be - added to the as well. + Scroll snapping creates many problems on iOS when used in combination + with `100vh`, so we are enabling this only for larger devices. */ - scroll-snap-type: y mandatory; - - /* - Ideally, we use `proximity` everywhere... - but iOS scrolling just feels janky when `proximity` is used. - */ - @media (--min-tablet) { + @media (--min-desktop) { scroll-snap-type: y proximity; } } .section { - scroll-snap-align: start; + /* See note above about iOS issues */ + @media (--min-desktop) { + scroll-snap-align: start; + } } /* --- Components --- */