153 lines
4.0 KiB
JavaScript
153 lines
4.0 KiB
JavaScript
(function() {
|
|
'use strict';
|
|
|
|
// Check for reduced motion preference
|
|
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
|
|
// Reveal on scroll
|
|
function initRevealOnScroll() {
|
|
if (prefersReducedMotion) {
|
|
// If reduced motion is preferred, show all elements immediately
|
|
document.querySelectorAll('.reveal').forEach(el => {
|
|
el.classList.add('revealed');
|
|
});
|
|
return;
|
|
}
|
|
|
|
const revealElements = document.querySelectorAll('.reveal');
|
|
|
|
const observerOptions = {
|
|
root: null,
|
|
rootMargin: '0px 0px -10% 0px',
|
|
threshold: 0.1
|
|
};
|
|
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add('revealed');
|
|
observer.unobserve(entry.target);
|
|
}
|
|
});
|
|
}, observerOptions);
|
|
|
|
revealElements.forEach(el => observer.observe(el));
|
|
}
|
|
|
|
// Smooth scroll for anchor links
|
|
function initSmoothScroll() {
|
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
anchor.addEventListener('click', function(e) {
|
|
const targetId = this.getAttribute('href');
|
|
if (targetId === '#') return;
|
|
|
|
const targetElement = document.querySelector(targetId);
|
|
if (!targetElement) return;
|
|
|
|
e.preventDefault();
|
|
|
|
targetElement.scrollIntoView({
|
|
behavior: prefersReducedMotion ? 'auto' : 'smooth',
|
|
block: 'start'
|
|
});
|
|
|
|
// Update focus for accessibility
|
|
targetElement.setAttribute('tabindex', '-1');
|
|
targetElement.focus();
|
|
});
|
|
});
|
|
}
|
|
|
|
// Header background on scroll
|
|
function initHeaderScroll() {
|
|
const header = document.querySelector('.site-header');
|
|
if (!header) return;
|
|
|
|
let ticking = false;
|
|
|
|
function updateHeader() {
|
|
const scrollY = window.scrollY;
|
|
|
|
if (scrollY > 100) {
|
|
header.style.background = 'rgba(245, 240, 232, 0.95)';
|
|
header.style.backdropFilter = 'blur(10px)';
|
|
header.style.boxShadow = '0 2px 20px rgba(139, 109, 76, 0.1)';
|
|
} else {
|
|
header.style.background = 'linear-gradient(to bottom, var(--color-cream) 0%, rgba(245, 240, 232, 0) 100%)';
|
|
header.style.backdropFilter = 'none';
|
|
header.style.boxShadow = 'none';
|
|
}
|
|
|
|
ticking = false;
|
|
}
|
|
|
|
window.addEventListener('scroll', () => {
|
|
if (!ticking) {
|
|
requestAnimationFrame(updateHeader);
|
|
ticking = true;
|
|
}
|
|
}, { passive: true });
|
|
}
|
|
|
|
// Parallax effect for hero shapes
|
|
function initParallax() {
|
|
if (prefersReducedMotion) return;
|
|
|
|
const shapes = document.querySelectorAll('.floating-shape');
|
|
if (!shapes.length) return;
|
|
|
|
let ticking = false;
|
|
|
|
function updateParallax() {
|
|
const scrollY = window.scrollY;
|
|
const windowHeight = window.innerHeight;
|
|
|
|
if (scrollY < windowHeight) {
|
|
shapes.forEach((shape, index) => {
|
|
const speed = 0.1 + (index * 0.05);
|
|
const yOffset = scrollY * speed;
|
|
shape.style.transform = `translateY(${yOffset}px)`;
|
|
});
|
|
}
|
|
|
|
ticking = false;
|
|
}
|
|
|
|
window.addEventListener('scroll', () => {
|
|
if (!ticking) {
|
|
requestAnimationFrame(updateParallax);
|
|
ticking = true;
|
|
}
|
|
}, { passive: true });
|
|
}
|
|
|
|
// Badge rotation pause on hover
|
|
function initBadgeInteraction() {
|
|
const badge = document.querySelector('.hero-badge');
|
|
if (!badge) return;
|
|
|
|
badge.addEventListener('mouseenter', () => {
|
|
badge.style.animationPlayState = 'paused';
|
|
});
|
|
|
|
badge.addEventListener('mouseleave', () => {
|
|
badge.style.animationPlayState = 'running';
|
|
});
|
|
}
|
|
|
|
// Initialize all
|
|
function init() {
|
|
initRevealOnScroll();
|
|
initSmoothScroll();
|
|
initHeaderScroll();
|
|
initParallax();
|
|
initBadgeInteraction();
|
|
}
|
|
|
|
// Run on DOM ready
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
} else {
|
|
init();
|
|
}
|
|
})(); |