116 lines
3.2 KiB
JavaScript
116 lines
3.2 KiB
JavaScript
/* ===== IQON — Interactive Scripts ===== */
|
|
|
|
// ——— Scroll Reveal ———
|
|
const reveals = document.querySelectorAll(".reveal");
|
|
|
|
const revealObserver = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add("on");
|
|
revealObserver.unobserve(entry.target);
|
|
}
|
|
});
|
|
},
|
|
{ threshold: 0.12, rootMargin: "0px 0px -40px 0px" }
|
|
);
|
|
|
|
reveals.forEach((item) => {
|
|
revealObserver.observe(item);
|
|
});
|
|
|
|
// ——— Active Nav Section Tracking ———
|
|
const navLinks = document.querySelectorAll(".main-nav a");
|
|
const sectionIds = ["approach", "services", "cases", "contacts"];
|
|
|
|
const sectionObserver = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
navLinks.forEach((link) => {
|
|
link.classList.toggle(
|
|
"active",
|
|
link.getAttribute("href") === `#${entry.target.id}`
|
|
);
|
|
});
|
|
}
|
|
});
|
|
},
|
|
{ threshold: 0.35, rootMargin: "-80px 0px 0px 0px" }
|
|
);
|
|
|
|
sectionIds.forEach((id) => {
|
|
const section = document.getElementById(id);
|
|
if (section) {
|
|
sectionObserver.observe(section);
|
|
}
|
|
});
|
|
|
|
// ——— Navbar Shrink on Scroll ———
|
|
const topbar = document.getElementById("topbar") || document.querySelector(".topbar");
|
|
let lastScrollY = 0;
|
|
let ticking = false;
|
|
|
|
function handleScroll() {
|
|
if (!topbar) {
|
|
ticking = false;
|
|
return;
|
|
}
|
|
const scrolled = window.scrollY > 60;
|
|
topbar.classList.toggle("scrolled", scrolled);
|
|
ticking = false;
|
|
}
|
|
|
|
window.addEventListener("scroll", () => {
|
|
if (!ticking) {
|
|
requestAnimationFrame(handleScroll);
|
|
ticking = true;
|
|
}
|
|
});
|
|
|
|
// ——— Smooth Scroll for Anchor Links ———
|
|
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
|
anchor.addEventListener("click", function (e) {
|
|
const target = document.querySelector(this.getAttribute("href"));
|
|
if (target) {
|
|
e.preventDefault();
|
|
const offset = (topbar ? topbar.offsetHeight : 0) + 12;
|
|
const top = target.getBoundingClientRect().top + window.scrollY - offset;
|
|
window.scrollTo({ top, behavior: "smooth" });
|
|
}
|
|
});
|
|
});
|
|
|
|
// ——— Chart Bar Animation ———
|
|
const chartBox = document.querySelector(".chart-box");
|
|
if (chartBox) {
|
|
const chartObserver = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
const bars = chartBox.querySelectorAll("span");
|
|
bars.forEach((bar, i) => {
|
|
bar.style.transition = `height 0.8s ${0.1 + i * 0.08}s cubic-bezier(0.34, 1.56, 0.64, 1)`;
|
|
bar.style.height = bar.style.height; // trigger reflow
|
|
});
|
|
chartObserver.unobserve(entry.target);
|
|
}
|
|
});
|
|
},
|
|
{ threshold: 0.5 }
|
|
);
|
|
chartObserver.observe(chartBox);
|
|
}
|
|
|
|
// ——— Service Tile Hover Glow ———
|
|
const serviceTiles = document.querySelectorAll(".service-tile");
|
|
serviceTiles.forEach((tile) => {
|
|
tile.addEventListener("mousemove", (e) => {
|
|
const rect = tile.getBoundingClientRect();
|
|
const x = e.clientX - rect.left;
|
|
const y = e.clientY - rect.top;
|
|
tile.style.setProperty("--mouse-x", `${x}px`);
|
|
tile.style.setProperty("--mouse-y", `${y}px`);
|
|
});
|
|
});
|