74 lines
2.9 KiB
JavaScript
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();
|
|
}
|
|
});
|