2026-03-23 11:37:38 +00:00

74 lines
2.9 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
const navLinks = document.querySelectorAll('a.nav-link[href^="#"]');
navLinks.forEach((link) => {
link.addEventListener('click', (event) => {
const targetId = link.getAttribute('href');
const target = document.querySelector(targetId);
if (target) {
event.preventDefault();
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
const toastEl = document.querySelector('.toast');
if (toastEl && window.bootstrap) {
const toast = new bootstrap.Toast(toastEl, { delay: 4000 });
toast.show();
}
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const orbs = Array.from(document.querySelectorAll('.bg-orb'));
const cursorGlow = document.querySelector('.bg-cursor-glow');
const parallaxItems = Array.from(document.querySelectorAll('[data-parallax]'));
if (!prefersReducedMotion && (orbs.length || cursorGlow || parallaxItems.length)) {
const pointer = { x: window.innerWidth / 2, y: window.innerHeight / 3 };
const smooth = { x: pointer.x, y: pointer.y };
let scrollY = window.scrollY;
const render = () => {
smooth.x += (pointer.x - smooth.x) * 0.08;
smooth.y += (pointer.y - smooth.y) * 0.08;
orbs.forEach((orb, index) => {
const depth = Number(orb.dataset.depth || 20);
const direction = index % 2 === 0 ? 1 : -1;
const dx = ((smooth.x / window.innerWidth) - 0.5) * depth * direction;
const dy = ((smooth.y / window.innerHeight) - 0.5) * depth;
orb.style.transform = `translate3d(${dx}px, ${dy}px, 0)`;
});
parallaxItems.forEach((item, index) => {
const depth = Number(item.dataset.parallax || 12);
const direction = Number(item.dataset.parallaxDirection || (index % 2 === 0 ? 1 : -1));
const rawMoveX = ((smooth.x / window.innerWidth) - 0.5) * depth * 0.7 * direction;
const rawMoveY = ((smooth.y / window.innerHeight) - 0.5) * depth * 0.45 + (scrollY * 0.004 * depth * direction);
const limitX = Math.max(8, depth * 1.6);
const limitY = Math.max(10, depth * 1.8);
const moveX = Math.max(-limitX, Math.min(limitX, rawMoveX));
const moveY = Math.max(-limitY, Math.min(limitY, rawMoveY));
item.style.transform = `translate3d(${moveX}px, ${moveY}px, 0) scale(1.02)`;
});
if (cursorGlow) {
cursorGlow.style.transform = `translate3d(${smooth.x}px, ${smooth.y}px, 0)`;
}
window.requestAnimationFrame(render);
};
window.addEventListener('pointermove', (event) => {
pointer.x = event.clientX;
pointer.y = event.clientY;
}, { passive: true });
window.addEventListener('scroll', () => {
scrollY = window.scrollY;
pointer.y = window.innerHeight / 3 + (window.scrollY * 0.08);
}, { passive: true });
render();
}
});