fiws-page/js/commissions.js

101 lines
3.7 KiB
JavaScript

const commissionPage = document.querySelector(".commissions-page");
if (commissionPage) {
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const finePointer = window.matchMedia("(hover: hover) and (pointer: fine)").matches;
if (finePointer && !reduceMotion) {
const hero = document.querySelector(".commission-hero-new");
window.addEventListener("pointermove", (event) => {
commissionPage.style.setProperty("--mx", `${event.clientX}px`);
commissionPage.style.setProperty("--my", `${event.clientY}px`);
if (hero) {
const bounds = hero.getBoundingClientRect();
hero.style.setProperty("--hx", `${event.clientX - bounds.left}px`);
hero.style.setProperty("--hy", `${event.clientY - bounds.top}px`);
}
}, { passive: true });
}
const clock = document.querySelector(".scope-clock");
if (clock) {
const startedAt = Date.now();
const updateClock = () => {
const seconds = Math.floor((Date.now() - startedAt) / 1000);
const hours = String(Math.floor(seconds / 3600)).padStart(2, "0");
const minutes = String(Math.floor((seconds % 3600) / 60)).padStart(2, "0");
const remainder = String(seconds % 60).padStart(2, "0");
clock.textContent = `${hours}:${minutes}:${remainder}`;
};
updateClock();
window.setInterval(updateClock, 1000);
}
const rotatingWord = document.querySelector(".commission-word");
if (rotatingWord && !reduceMotion) {
const words = (rotatingWord.dataset.words || "weird").split(",");
let wordIndex = 0;
window.setInterval(() => {
rotatingWord.classList.add("is-changing");
window.setTimeout(() => {
wordIndex = (wordIndex + 1) % words.length;
rotatingWord.textContent = words[wordIndex];
}, 110);
window.setTimeout(() => rotatingWord.classList.remove("is-changing"), 280);
}, 2800);
}
const filterButtons = document.querySelectorAll("[data-price-filter]");
const priceGroups = document.querySelectorAll("[data-price-category]");
const visibleCount = document.querySelector("#price-visible-count");
filterButtons.forEach((button) => {
button.addEventListener("click", () => {
const selected = button.dataset.priceFilter;
let count = 0;
filterButtons.forEach((candidate) => {
const active = candidate === button;
candidate.classList.toggle("is-active", active);
candidate.setAttribute("aria-pressed", String(active));
});
priceGroups.forEach((group) => {
const visible = selected === "all" || group.dataset.priceCategory === selected;
group.hidden = !visible;
if (visible) count += group.querySelectorAll(".price-list > div").length;
});
if (visibleCount) visibleCount.textContent = String(count);
});
});
const copyBrief = document.querySelector("#copy-brief");
const copyStatus = document.querySelector("#copy-status");
const brief = [
"Hi Alex — I have a commission request.",
"",
"What I want to build or fix:",
"Current system / versions:",
"What happens now:",
"What I want to happen:",
"What counts as done:",
"Budget range:",
"Deadline, if any:",
"Useful logs / screenshots:",
].join("\n");
if (copyBrief && copyStatus) {
copyBrief.addEventListener("click", async () => {
try {
await navigator.clipboard.writeText(brief);
copyStatus.textContent = "Commission brief copied. Paste it into an email, Telegram, or Discord.";
} catch {
copyStatus.textContent = "Clipboard access was blocked. Email me the goal, setup, symptoms, and any logs.";
}
window.setTimeout(() => { copyStatus.textContent = ""; }, 4000);
});
}
}