// Intersection Observer for scroll animations document.addEventListener('DOMContentLoaded', function() { const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.classList.add('animate-fade-in'); } }); }, observerOptions); // Observe elements that should animate on scroll const elementsToObserve = document.querySelectorAll('section'); elementsToObserve.forEach(el => { observer.observe(el); }); // Stat counter animation const animateCounters = () => { const counters = document.querySelectorAll('[data-count]'); counters.forEach(counter => { const target = parseInt(counter.getAttribute('data-count')); const duration = 2000; const step = target / (duration / 16); let current = 0; const timer = setInterval(() => { current += step; if (current >= target) { counter.textContent = target; clearInterval(timer); } else { counter.textContent = Math.floor(current); } }, 16); }); }; // Trigger counter animation when stats section is visible const statsSection = document.querySelector('.grid'); if (statsSection) { const statsObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { animateCounters(); statsObserver.unobserve(entry.target); } }); }, { threshold: 0.5 }); statsObserver.observe(statsSection); } }); // Mobile menu toggle function toggleMobileMenu() { const mobileMenu = document.querySelector('.mobile-menu'); const overlay = document.querySelector('.overlay'); const hamburger = document.querySelector('.hamburger'); if (mobileMenu && overlay && hamburger) { mobileMenu.classList.toggle('active'); overlay.classList.toggle('active'); hamburger.classList.toggle('active'); } } // Close mobile menu when clicking overlay function closeMobileMenu() { const mobileMenu = document.querySelector('.mobile-menu'); const overlay = document.querySelector('.overlay'); const hamburger = document.querySelector('.hamburger'); if (mobileMenu && overlay && hamburger) { mobileMenu.classList.remove('active'); overlay.classList.remove('active'); hamburger.classList.remove('active'); } } // Work filtering functionality (for work page) let selectedCategory = 'all'; function showCategory(category) { selectedCategory = category; // Update tab buttons const tabButtons = document.querySelectorAll('.tab-button'); tabButtons.forEach(btn => { if (btn.getAttribute('onclick').includes(category)) { btn.classList.add('bg-gray-900', 'text-white'); btn.classList.remove('bg-gray-200', 'text-gray-700'); } else { btn.classList.add('bg-gray-200', 'text-gray-700'); btn.classList.remove('bg-gray-900', 'text-white'); } }); // Show/hide projects with animation const tabContents = document.querySelectorAll('.tab-content'); tabContents.forEach(content => { content.classList.remove('active'); }); const activeContent = document.querySelector(`.tab-content[data-category="${category}"]`); if (activeContent) { setTimeout(() => { activeContent.classList.add('active'); }, 100); } } // Project modal functionality (for work page) function openProject(title) { const modal = document.createElement('div'); modal.className = 'fixed inset-0 z-50 flex items-center justify-center p-4 modal-backdrop'; modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; modal.innerHTML = `
${title}

${title}

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.

Web Design Branding UI/UX
Start a Similar Project
`; document.body.appendChild(modal); document.body.style.overflow = 'hidden'; // Animate in setTimeout(() => { modal.firstElementChild.style.transform = 'scale(1)'; }, 10); // Re-render Feather icons if (window.feather) { feather.replace(); } } function closeProject() { const modal = document.querySelector('.modal-backdrop'); if (modal) { modal.firstElementChild.style.transform = 'scale(0.95)'; setTimeout(() => { modal.remove(); document.body.style.overflow = ''; }, 300); } } // Close modal when clicking outside document.addEventListener('click', function(e) { if (e.target.classList.contains('modal-backdrop')) { closeProject(); } }); // Form submission handler (for contact page) function submitContactForm(e) { e.preventDefault(); const form = e.target; const formData = new FormData(form); const submitBtn = form.querySelector('button[type="submit"]'); // Show loading state const originalBtnText = submitBtn.innerHTML; submitBtn.innerHTML = 'Sending'; submitBtn.disabled = true; // Simulate form submission setTimeout(() => { // Success message const successMessage = document.createElement('div'); successMessage.className = 'mb-6 p-4 bg-green-100 text-green-700 rounded-lg'; successMessage.innerHTML = `
Thank you for your message! We'll get back to you soon.
`; form.parentNode.insertBefore(successMessage, form); form.reset(); // Reset button submitBtn.innerHTML = originalBtnText; submitBtn.disabled = false; // Re-render Feather icons if (window.feather) { feather.replace(); } // Remove success message after 5 seconds setTimeout(() => { successMessage.remove(); }, 5000); }, 2000); } // Smooth scroll to top function scrollToTop() { window.scrollTo({ top: 0, behavior: 'smooth' }); } // Parallax effect for hero section window.addEventListener('scroll', () => { const scrolled = window.pageYOffset; const parallax = document.querySelector('.parallax-bg'); if (parallax && window.innerWidth > 768) { const yPos = -(scrolled * 0.5); parallax.style.transform = `translateY(${yPos}px)`; } }); // Add hover effect to project cards document.addEventListener('DOMContentLoaded', () => { const projectCards = document.querySelectorAll('.project-card'); projectCards.forEach(card => { card.addEventListener('mouseenter', () => { card.style.transform = 'translateY(-8px)'; }); card.addEventListener('mouseleave', () => { card.style.transform = 'translateY(0)'; }); }); }); // Lazy loading images function lazyLoadImages() { const images = document.querySelectorAll('img[loading="lazy"]'); if ('IntersectionObserver' in window) { const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src || img.src; img.classList.remove('opacity-0'); img.classList.add('opacity-100'); observer.unobserve(img); } }); }); images.forEach(img => imageObserver.observe(img)); } } // Initialize lazy loading lazyLoadImages(); // Keyboard navigation for accessibility document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { closeProject(); closeMobileMenu(); } });