This commit is contained in:
2026-07-20 10:49:30 -05:00
parent 10bacc5a3c
commit 8f344ea37e
4 changed files with 277 additions and 65 deletions
+123
View File
@@ -0,0 +1,123 @@
const mottos = [
"Stay humble enough to learn, and confident enough to build.",
"Make it work. Then make it quiet.",
"Good systems leave room for people.",
"Read the logs before blaming the network.",
];
const glyphs = "01#@$%&*+<>/\\";
function prefersReducedMotion(): boolean {
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
}
function initName(): void {
const button = document.querySelector<HTMLButtonElement>("[data-name-play]");
if (!button) return;
const original = button.textContent?.trim() || "Owen Rummage";
let timer = 0;
button.addEventListener("click", () => {
window.clearInterval(timer);
if (prefersReducedMotion()) {
button.classList.toggle("is-glitched");
return;
}
let frame = 0;
timer = window.setInterval(() => {
button.textContent = [...original]
.map((letter, index) => {
if (letter === " " || index < frame / 2) return letter;
return glyphs[Math.floor(Math.random() * glyphs.length)];
})
.join("");
frame += 1;
if (frame > original.length * 2) {
window.clearInterval(timer);
button.textContent = original;
}
}, 34);
});
}
function initRoles(): void {
document.querySelectorAll<HTMLElement>("[data-role-play]").forEach((role) => {
const pin = role.querySelector<HTMLButtonElement>("[data-role-pin]");
const toggle = () => {
const pinned = role.classList.toggle("is-pinned");
pin?.setAttribute("aria-pressed", String(pinned));
};
role.addEventListener("dblclick", toggle);
pin?.addEventListener("click", toggle);
});
}
function initMotto(): void {
const button = document.querySelector<HTMLButtonElement>("[data-motto-play]");
if (!button) return;
let index = 0;
button.addEventListener("click", () => {
index = (index + 1) % mottos.length;
button.classList.remove("is-swapping");
void button.offsetWidth;
button.textContent = mottos[index];
button.classList.add("is-swapping");
});
}
function celebrate(): void {
const layer = document.createElement("div");
layer.className = "play-layer";
layer.setAttribute("aria-hidden", "true");
const count = prefersReducedMotion() ? 8 : 28;
for (let i = 0; i < count; i += 1) {
const bit = document.createElement("i");
bit.textContent = i % 3 === 0 ? "#" : i % 3 === 1 ? "0" : "1";
bit.style.setProperty("--x", `${Math.random() * 100}vw`);
bit.style.setProperty("--delay", `${Math.random() * 0.6}s`);
bit.style.setProperty("--drift", `${Math.random() * 80 - 40}px`);
layer.appendChild(bit);
}
document.body.appendChild(layer);
window.setTimeout(() => layer.remove(), 2600);
}
function initSecrets(): void {
const home = document.querySelector<HTMLButtonElement>("[data-home-play]");
home?.addEventListener("click", celebrate);
const sequence = [
"ArrowUp",
"ArrowUp",
"ArrowDown",
"ArrowDown",
"ArrowLeft",
"ArrowRight",
"ArrowLeft",
"ArrowRight",
"b",
"a",
];
let position = 0;
window.addEventListener("keydown", (event) => {
position = event.key.toLowerCase() === sequence[position]?.toLowerCase() ? position + 1 : 0;
if (position === sequence.length) {
celebrate();
position = 0;
}
});
}
function init(): void {
initName();
initRoles();
initMotto();
initSecrets();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init, { once: true });
} else {
init();
}