-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
104 lines (91 loc) · 3.58 KB
/
Copy pathscript.js
File metadata and controls
104 lines (91 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
const header = document.querySelector("[data-header]");
const navToggle = document.querySelector(".nav-toggle");
const nav = document.querySelector(".site-nav");
const navLinks = document.querySelectorAll(".site-nav a");
const year = document.querySelector("[data-year]");
const stageButtons = [...document.querySelectorAll("[data-stage]")];
const labStage = document.querySelector("[data-lab-stage]");
const labInsight = document.querySelector("[data-lab-insight]");
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const updateHeader = () => {
header?.classList.toggle("is-scrolled", window.scrollY > 16);
};
const closeNav = () => {
navToggle?.setAttribute("aria-expanded", "false");
nav?.classList.remove("is-open");
document.body.classList.remove("nav-open");
};
navToggle?.addEventListener("click", () => {
const willOpen = navToggle.getAttribute("aria-expanded") !== "true";
navToggle.setAttribute("aria-expanded", String(willOpen));
nav?.classList.toggle("is-open", willOpen);
document.body.classList.toggle("nav-open", willOpen);
});
navLinks.forEach((link) => link.addEventListener("click", closeNav));
window.addEventListener("scroll", updateHeader, { passive: true });
window.addEventListener("resize", () => {
if (window.innerWidth > 900) closeNav();
});
updateHeader();
if (year) year.textContent = String(new Date().getFullYear());
let activeStage = 0;
let stageTimer;
const selectStage = (index) => {
const button = stageButtons[index];
if (!button || !labStage || !labInsight) return;
activeStage = index;
stageButtons.forEach((stage, stageIndex) => {
const isActive = stageIndex === index;
stage.classList.toggle("is-active", isActive);
stage.setAttribute("aria-pressed", String(isActive));
});
labStage.textContent = `FIELD NOTE / ${button.dataset.stage}`;
labInsight.classList.remove("is-changing");
void labInsight.offsetWidth;
labInsight.textContent = button.dataset.insight;
labInsight.classList.add("is-changing");
};
const stopStageRotation = () => window.clearInterval(stageTimer);
stageButtons.forEach((button, index) => {
button.addEventListener("click", () => {
stopStageRotation();
selectStage(index);
});
button.addEventListener("focus", stopStageRotation);
});
if (stageButtons.length && !prefersReducedMotion) {
stageTimer = window.setInterval(() => selectStage((activeStage + 1) % stageButtons.length), 3600);
}
const revealItems = document.querySelectorAll("[data-reveal]");
if (prefersReducedMotion || !("IntersectionObserver" in window)) {
revealItems.forEach((item) => item.classList.add("is-visible"));
} else {
document.documentElement.classList.add("reveal-ready");
const revealObserver = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.classList.add("is-visible");
observer.unobserve(entry.target);
});
},
{ threshold: 0.12, rootMargin: "0px 0px -40px" },
);
revealItems.forEach((item) => {
if (item.getBoundingClientRect().top < window.innerHeight * 1.05) {
item.classList.add("is-visible");
} else {
revealObserver.observe(item);
}
});
}
window.addEventListener("load", async () => {
if (!window.location.hash) return;
const target = document.querySelector(window.location.hash);
if (!target) return;
if (document.fonts?.ready) await document.fonts.ready;
requestAnimationFrame(() => {
const top = target.getBoundingClientRect().top + window.scrollY - 64;
window.scrollTo({ top, behavior: "instant" });
});
});