// Counter animation for statistics function animateCounters() { const counters = document.querySelectorAll('.counter'); counters.forEach(counter => { const target = parseInt(counter.getAttribute('data-target')); const increment = target / 100; let current = 0; const updateCounter = () => { current += increment; if (current < target) { counter.textContent = Math.ceil(current); requestAnimationFrame(updateCounter); } else { counter.textContent = target; } }; updateCounter(); }); } // Intersection Observer for animations const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -100px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('animate-fade-in'); // Trigger counter animation when stats section is visible if (entry.target.querySelector('.counter')) { animateCounters(); } } }); }, observerOptions); // Observe all sections document.addEventListener('DOMContentLoaded', () => { const sections = document.querySelectorAll('section'); sections.forEach(section => observer.observe(section)); }); // Product filtering function filterProducts(category) { const products = document.querySelectorAll('#productsGrid .product-card'); const buttons = document.querySelectorAll('button[onclick^="filterProducts"]'); // Update active button buttons.forEach(btn => { btn.classList.remove('tab-active'); if (btn.getAttribute('onclick').includes(category)) { btn.classList.add('tab-active'); } }); // Filter products products.forEach(product => { if (category === 'all' || product.getAttribute('data-category') === category) { product.style.display = 'block'; setTimeout(() => { product.style.opacity = '1'; product.style.transform = 'scale(1)'; }, 10); } else { product.style.opacity = '0'; product.style.transform = 'scale(0.9)'; setTimeout(() => { product.style.display = 'none'; }, 300); } }); } // Smooth scroll for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // Parallax effect for hero section window.addEventListener('scroll', () => { const scrolled = window.pageYOffset; const parallax = document.querySelector('.hero-section'); if (parallax) { parallax.style.transform = `translateY(${scrolled * 0.5}px)`; } }); // Mobile menu toggle (if needed) function toggleMobileMenu() { const menu = document.querySelector('.mobile-menu'); if (menu) { menu.classList.toggle('active'); } } // Form validation function validateForm(form) { const inputs = form.querySelectorAll('input[required], textarea[required], select[required]'); let isValid = true; inputs.forEach(input => { if (!input.value.trim()) { input.classList.add('border-red-500'); isValid = false; } else { input.classList.remove('border-red-500'); } }); return isValid; } // Email validation function validateEmail(email) { const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return re.test(email); } // Phone number formatting function formatPhoneNumber(input) { const phoneNumber = input.value.replace(/\D/g, ''); const formattedNumber = phoneNumber.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3'); input.value = formattedNumber; } // Lazy loading for images document.addEventListener('DOMContentLoaded', () => { const images = document.querySelectorAll('img[data-src]'); const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.classList.remove('lazy'); imageObserver.unobserve(img); } }); }); images.forEach(img => imageObserver.observe(img)); }); // Sticky header window.addEventListener('scroll', () => { const header = document.querySelector('header'); if (header) { if (window.scrollY > 100) { header.classList.add('shadow-lg'); } else { header.classList.remove('shadow-lg'); } } }); // Copy to clipboard functionality function copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { showNotification('Copied to clipboard!'); }); } // Show notification function showNotification(message, type = 'success') { const notification = document.createElement('div'); notification.className = `fixed top-4 right-4 px-6 py-3 rounded-lg shadow-lg z-50 animate-fade-in ${ type === 'success' ? 'bg-green-500 text-white' : 'bg-red-500 text-white' }`; notification.textContent = message; document.body.appendChild(notification); setTimeout(() => { notification.style.opacity = '0'; setTimeout(() => { document.body.removeChild(notification); }, 300); }, 3000); } // Dark mode toggle function toggleDarkMode() { document.body.classList.toggle('dark-mode'); localStorage.setItem('darkMode', document.body.classList.contains('dark-mode')); } // Load dark mode preference document.addEventListener('DOMContentLoaded', () => { if (localStorage.getItem('darkMode') === 'true') { document.body.classList.add('dark-mode'); } }); // Initialize tooltips document.addEventListener('DOMContentLoaded', () => { const tooltips = document.querySelectorAll('[data-tooltip]'); tooltips.forEach(element => { element.addEventListener('mouseenter', (e) => { const tooltip = document.createElement('div'); tooltip.className = 'absolute bg-gray-800 text-white text-sm px-2 py-1 rounded z-50'; tooltip.textContent = e.target.getAttribute('data-tooltip'); tooltip.style.top = `${e.target.offsetTop - 30}px`; tooltip.style.left = `${e.target.offsetLeft}px`; tooltip.id = 'tooltip'; document.body.appendChild(tooltip); }); element.addEventListener('mouseleave', () => { const tooltip = document.getElementById('tooltip'); if (tooltip) { document.body.removeChild(tooltip); } }); }); }); // Accordion functionality function toggleAccordion(element) { const content = element.nextElementSibling; const icon = element.querySelector('.accordion-icon'); content.classList.toggle('hidden'); icon.classList.toggle('rotate-180'); } // Tab functionality function switchTab(tabId, contentId) { // Hide all tab contents const contents = document.querySelectorAll('[id^="tab-content-"]'); contents.forEach(content => content.classList.add('hidden')); // Remove active class from all tabs const tabs = document.querySelectorAll('[id^="tab-"]'); tabs.forEach(tab => tab.classList.remove('active')); // Show selected content document.getElementById(contentId).classList.remove('hidden'); // Add active class to selected tab document.getElementById(tabId).classList.add('active'); } // Search functionality function searchItems(searchTerm, items) { const filtered = items.filter(item => item.textContent.toLowerCase().includes(searchTerm.toLowerCase()) ); return filtered; } // Debounce function for search function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } // Performance monitoring window.addEventListener('load', () => { if ('performance' in window) { const perfData = window.performance.timing; const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart; console.log(`Page load time: ${pageLoadTime}ms`); } }); // Error handling window.addEventListener('error', (e) => { console.error('JavaScript error:', e.error); // You can send errors to a monitoring service here }); // Service worker registration for PWA if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js') .then(registration => { console.log('SW registered: ', registration); }) .catch(registrationError => { console.log('SW registration failed: ', registrationError); }); }); }