// Mobile Menu Toggle const mobileToggle = document.getElementById('mobileToggle'); const navMenu = document.getElementById('navMenu'); mobileToggle.addEventListener('click', () => { navMenu.classList.toggle('active'); // Animate hamburger to X const spans = mobileToggle.querySelectorAll('span'); if (navMenu.classList.contains('active')) { spans[0].style.transform = 'rotate(45deg) translate(5px, 5px)'; spans[1].style.opacity = '0'; spans[2].style.transform = 'rotate(-45deg) translate(7px, -6px)'; } else { spans[0].style.transform = 'none'; spans[1].style.opacity = '1'; spans[2].style.transform = 'none'; } }); // Close mobile menu when clicking on a link const navLinks = document.querySelectorAll('.nav-link'); navLinks.forEach(link => { link.addEventListener('click', () => { navMenu.classList.remove('active'); const spans = mobileToggle.querySelectorAll('span'); spans[0].style.transform = 'none'; spans[1].style.opacity = '1'; spans[2].style.transform = 'none'; }); }); // Navbar scroll effect const nav = document.getElementById('nav'); let lastScroll = 0; window.addEventListener('scroll', () => { const currentScroll = window.pageYOffset; if (currentScroll > 50) { nav.classList.add('scrolled'); } else { nav.classList.remove('scrolled'); } lastScroll = currentScroll; }); // 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) { const offsetTop = target.offsetTop - 80; window.scrollTo({ top: offsetTop, behavior: 'smooth' }); } }); }); // Animate on Scroll (AOS) implementation function initAOS() { const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('aos-animate'); } }); }, observerOptions); // Observe all elements with data-aos attribute document.querySelectorAll('[data-aos]').forEach(element => { observer.observe(element); }); } // Initialize AOS when DOM is loaded document.addEventListener('DOMContentLoaded', initAOS); // Animate skill bars when they come into view const skillObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const progressBars = entry.target.querySelectorAll('.skill-progress'); progressBars.forEach(bar => { const width = bar.style.width; bar.style.width = '0'; setTimeout(() => { bar.style.width = width; }, 100); }); skillObserver.unobserve(entry.target); } }); }, { threshold: 0.5 }); const skillsSection = document.querySelector('.skills'); if (skillsSection) { skillObserver.observe(skillsSection); } // Contact Form Handling const contactForm = document.getElementById('contactForm'); contactForm.addEventListener('submit', (e) => { e.preventDefault(); // Get form data const formData = { name: document.getElementById('name').value, email: document.getElementById('email').value, subject: document.getElementById('subject').value, message: document.getElementById('message').value }; // In a real application, you would send this data to a server console.log('Form submitted:', formData); // Show success message showNotification('Thank you for your message! I\'ll get back to you soon.', 'success'); // Reset form contactForm.reset(); }); // Notification function function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `notification notification-${type}`; notification.textContent = message; notification.style.cssText = ` position: fixed; top: 100px; right: 20px; background: ${type === 'success' ? '#10b981' : '#3b82f6'}; color: white; padding: 1rem 1.5rem; border-radius: 8px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); z-index: 10000; animation: slideIn 0.3s ease; `; document.body.appendChild(notification); setTimeout(() => { notification.style.animation = 'slideOut 0.3s ease'; setTimeout(() => { document.body.removeChild(notification); }, 300); }, 3000); } // Add animation keyframes const style = document.createElement('style'); style.textContent = ` @keyframes slideIn { from { transform: translateX(400px); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(400px); opacity: 0; } } `; document.head.appendChild(style); // Parallax effect for hero section window.addEventListener('scroll', () => { const scrolled = window.pageYOffset; const hero = document.querySelector('.hero'); if (hero && scrolled < window.innerHeight) { const parallaxElements = hero.querySelectorAll('.floating-card'); parallaxElements.forEach((element, index) => { const speed = 0.5 + (index * 0.1); element.style.transform = `translateY(${scrolled * speed}px)`; }); } }); // Add active state to navigation based on scroll position window.addEventListener('scroll', () => { const sections = document.querySelectorAll('section[id]'); const scrollY = window.pageYOffset; sections.forEach(section => { const sectionHeight = section.offsetHeight; const sectionTop = section.offsetTop - 100; const sectionId = section.getAttribute('id'); const navLink = document.querySelector(`.nav-link[href="#${sectionId}"]`); if (navLink && scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) { document.querySelectorAll('.nav-link').forEach(link => { link.style.color = ''; }); navLink.style.color = 'var(--primary-color)'; } }); }); // Preload animation for page load window.addEventListener('load', () => { document.body.style.opacity = '0'; setTimeout(() => { document.body.style.transition = 'opacity 0.5s ease'; document.body.style.opacity = '1'; }, 100); });