Skip to content

Commit

Permalink
✨ [NavTracker] Improve current navigation highlight
Browse files Browse the repository at this point in the history
  • Loading branch information
beefchimi committed Jul 29, 2024
1 parent ad3b2e1 commit 991dad3
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 57 deletions.
63 changes: 12 additions & 51 deletions src/components/Navigation.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ interface ItemDescriptor {
id: string;
name: string;
description: string;
// Not using a `current` prop as we need to calculate the
// current item via a `script` instead of `frontmatter`.
// current?: boolean;
// class:list={['Link', {current: item.current}]}
}
interface Props {
Expand Down Expand Up @@ -166,61 +170,18 @@ const {id, items = []} = Astro.props;
}

/* --- Active Item iteration --- */
/* TODO: Replace these with an `active` class instead. */

html[data-current-index='0'] .Item:nth-child(1) .Link,
html[data-current-index='1'] .Item:nth-child(2) .Link,
html[data-current-index='2'] .Item:nth-child(3) .Link,
html[data-current-index='3'] .Item:nth-child(4) .Link,
html[data-current-index='4'] .Item:nth-child(5) .Link,
html[data-current-index='5'] .Item:nth-child(6) .Link,
html[data-current-index='6'] .Item:nth-child(7) .Link,
html[data-current-index='7'] .Item:nth-child(8) .Link,
html[data-current-index='8'] .Item:nth-child(9) .Link,
html[data-current-index='9'] .Item:nth-child(10) .Link,
html[data-current-index='10'] .Item:nth-child(11) .Link,
html[data-current-index='11'] .Item:nth-child(12) .Link,
html[data-current-index='12'] .Item:nth-child(13) .Link,
html[data-current-index='13'] .Item:nth-child(14) .Link,
html[data-current-index='14'] .Item:nth-child(15) .Link {

.Item[data-current] .Link {
cursor: url('../assets/svg/cursors/CursorHorns.svg'), not-allowed;
color: var(--color-primary);
translate: calc(var(--nav-item-shift-x) * -1) 0;
}

html[data-current-index='0'] .Item:nth-child(1) .Link:active,
html[data-current-index='1'] .Item:nth-child(2) .Link:active,
html[data-current-index='2'] .Item:nth-child(3) .Link:active,
html[data-current-index='3'] .Item:nth-child(4) .Link:active,
html[data-current-index='4'] .Item:nth-child(5) .Link:active,
html[data-current-index='5'] .Item:nth-child(6) .Link:active,
html[data-current-index='6'] .Item:nth-child(7) .Link:active,
html[data-current-index='7'] .Item:nth-child(8) .Link:active,
html[data-current-index='8'] .Item:nth-child(9) .Link:active,
html[data-current-index='9'] .Item:nth-child(10) .Link:active,
html[data-current-index='10'] .Item:nth-child(11) .Link:active,
html[data-current-index='11'] .Item:nth-child(12) .Link:active,
html[data-current-index='12'] .Item:nth-child(13) .Link:active,
html[data-current-index='13'] .Item:nth-child(14) .Link:active,
html[data-current-index='14'] .Item:nth-child(15) .Link:active {
cursor: url('../assets/svg/cursors/CursorHornsClicked.svg'), not-allowed;
}
&:active {
cursor: url('../assets/svg/cursors/CursorHornsClicked.svg'), not-allowed;
}

html[data-current-index='0'] .Item:nth-child(1) .Link::before,
html[data-current-index='1'] .Item:nth-child(2) .Link::before,
html[data-current-index='2'] .Item:nth-child(3) .Link::before,
html[data-current-index='3'] .Item:nth-child(4) .Link::before,
html[data-current-index='4'] .Item:nth-child(5) .Link::before,
html[data-current-index='5'] .Item:nth-child(6) .Link::before,
html[data-current-index='6'] .Item:nth-child(7) .Link::before,
html[data-current-index='7'] .Item:nth-child(8) .Link::before,
html[data-current-index='8'] .Item:nth-child(9) .Link::before,
html[data-current-index='9'] .Item:nth-child(10) .Link::before,
html[data-current-index='10'] .Item:nth-child(11) .Link::before,
html[data-current-index='11'] .Item:nth-child(12) .Link::before,
html[data-current-index='12'] .Item:nth-child(13) .Link::before,
html[data-current-index='13'] .Item:nth-child(14) .Link::before,
html[data-current-index='14'] .Item:nth-child(15) .Link::before {
opacity: 0;
&::before {
opacity: 0;
}
}
</style>
2 changes: 1 addition & 1 deletion src/layouts/Page.astro
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const OG_IMAGE = new URL('/dulmage-social.png', Astro.site).href;
---

<!doctype html>
<html lang="en" data-current-index="0" data-ready="loading">
<html lang="en" data-ready="loading">
<head>
<meta charset="UTF-8" />
<meta
Expand Down
9 changes: 7 additions & 2 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,21 @@ const [intro, ...portfolioSections] = sections;
<script>
import {NAV_ID, NAV_TOGGLE_ID, OVERLAY_ID, PERSONAL_EMAIL} from '@data/app';

import {NavTracker} from '@scripts/NavTracker';
import {Overlay} from '@scripts/Overlay';
import {Portfolio} from '@scripts/Portfolio';
import {SecretEmail} from '@scripts/SecretEmail';
import {Toggler} from '@scripts/Toggler';

const navTrackerInstance = new NavTracker(`#${NAV_ID} li`);
navTrackerInstance.update();

const overlayInstance = new Overlay(OVERLAY_ID);
overlayInstance.init();

// Only pass `{scroller: 'main'}` if we want scroll-snapping.
const portfolioInstance = new Portfolio();
const portfolioInstance = new Portfolio({}, ({mostVisibleIndex}) => {
navTrackerInstance.safeUpdate(mostVisibleIndex);
});
portfolioInstance.init();

const emailInstance = new SecretEmail(PERSONAL_EMAIL);
Expand Down
25 changes: 25 additions & 0 deletions src/scripts/NavTracker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export class NavTracker {
#items: NodeListOf<Element>;
#lastSavedIndex = 0;

constructor(selector = 'nav ul li') {
this.#items = document.querySelectorAll(selector);
}

update(currentIndex = 0) {
this.#items.forEach((element, index) => {
if (index === currentIndex) {
element.setAttribute('data-current', 'true');
} else {
element.removeAttribute('data-current');
}
});
}

safeUpdate(currentIndex = 0) {
if (this.#lastSavedIndex === currentIndex) return;

this.#lastSavedIndex = currentIndex;
this.update(currentIndex);
}
}
27 changes: 24 additions & 3 deletions src/scripts/Portfolio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,19 @@ interface Selectors {
scroller?: string;
}

interface ScrollData {
currentIndex: number;
nextIndex: number;
mostVisibleIndex: number;
indexProgress: number;
}

type CustomScrollFn = (data: ScrollData) => void;

export class Portfolio {
#selector: Required<Selectors>;
#onScroll: CustomScrollFn | undefined;

#sections: NodeListOf<Element>;
#scroller: Element | null;
#channels: RgbChannels;
Expand All @@ -31,12 +42,13 @@ export class Portfolio {
// user-agent sniff in order to work around it.
static SUPPORT_URL_UPDATES = false;

constructor(selectors?: Selectors) {
constructor(selectors?: Selectors, onScroll?: CustomScrollFn) {
this.#selector = {
cssColorProp: selectors?.cssColorProp || CSS_PORTFOLIO_COLOR_PROP,
section: selectors?.section || SECTION_SELECTOR,
scroller: selectors?.scroller || '',
};
this.#onScroll = onScroll;

this.#sections = document.querySelectorAll(this.#selector.section);
this.#scroller = Boolean(this.#selector.scroller)
Expand All @@ -58,6 +70,10 @@ export class Portfolio {
: this.#index + 1;
}

get mostVisibleIndex() {
return this.sectionScrollProgress > 60 ? this.nextIndex : this.currentIndex;
}

get channels() {
return this.#channels;
}
Expand Down Expand Up @@ -136,8 +152,6 @@ export class Portfolio {
if (this.#index === newIndex) return;

this.#index = newIndex;
document.documentElement.dataset.currentIndex = newIndex.toString();

this.#updateUrlHash();
}

Expand Down Expand Up @@ -170,6 +184,13 @@ export class Portfolio {

this.#rafId = requestAnimationFrame(this.#rafCallback);
this.#isTicking = true;

this.#onScroll?.({
currentIndex: this.currentIndex,
nextIndex: this.nextIndex,
mostVisibleIndex: this.mostVisibleIndex,
indexProgress: this.sectionScrollProgress,
});
};

#handleResize = () => {
Expand Down

0 comments on commit 991dad3

Please sign in to comment.