Spaces:
Running
Running
| // Logic to handle navigation active state based on scroll position | |
| document.addEventListener('DOMContentLoaded', () => { | |
| const sections = document.querySelectorAll('section[id]'); | |
| const navLinks = document.querySelectorAll('.nav-link'); | |
| const observerOptions = { | |
| root: null, | |
| rootMargin: '0px', | |
| threshold: 0.3 | |
| }; | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| const id = entry.target.getAttribute('id'); | |
| navLinks.forEach(link => { | |
| link.classList.remove('active'); | |
| if (link.getAttribute('href') === `#${id}`) { | |
| link.classList.add('active'); | |
| } | |
| }); | |
| } | |
| }); | |
| }, observerOptions); | |
| sections.forEach(section => observer.observe(section)); | |
| // Scroll reveal animation | |
| const revealElements = document.querySelectorAll('.reveal, .reveal-left, .reveal-right'); | |
| const revealObserver = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| entry.target.classList.add('active'); | |
| } | |
| }); | |
| }, { threshold: 0.1 }); | |
| revealElements.forEach(el => revealObserver.observe(el)); | |
| // Initialize components when DOM is ready | |
| const initComponents = () => { | |
| // Initialize Terminal | |
| const terminal = document.querySelector('custom-terminal'); | |
| if (terminal && terminal.initTerminal) { | |
| setTimeout(() => terminal.initTerminal(), 3000); | |
| } | |
| // Initialize Projects scroll | |
| const projects = document.querySelector('custom-projects'); | |
| if (projects && projects.initScrollNavigation) { | |
| projects.initScrollNavigation(); | |
| } | |
| // Initialize Skills filter | |
| const skills = document.querySelector('custom-skills'); | |
| if (skills && skills.initFilter) { | |
| skills.initFilter(); | |
| } | |
| }; | |
| // Dispatch event to notify components that the DOM is ready | |
| window.dispatchEvent(new Event('app-ready')); | |
| // Initialize components | |
| initComponents(); | |
| // Parallax effect for hero section | |
| window.addEventListener('scroll', () => { | |
| const scrolled = window.pageYOffset; | |
| const hero = document.querySelector('custom-hero'); | |
| if (hero) { | |
| const shapes = hero.shadowRoot?.querySelector('.floating-shapes'); | |
| if (shapes) { | |
| shapes.style.transform = `translateY(${scrolled * 0.3}px)`; | |
| } | |
| } | |
| }); | |
| // Magnetic button effect | |
| const magneticBtns = document.querySelectorAll('.magnetic-btn'); | |
| magneticBtns.forEach(btn => { | |
| btn.addEventListener('mousemove', (e) => { | |
| const rect = btn.getBoundingClientRect(); | |
| const x = e.clientX - rect.left - rect.width / 2; | |
| const y = e.clientY - rect.top - rect.height / 2; | |
| btn.style.transform = `translate(${x * 0.3}px, ${y * 0.3}px)`; | |
| }); | |
| btn.addEventListener('mouseleave', () => { | |
| btn.style.transform = 'translate(0, 0)'; | |
| }); | |
| }); | |
| // 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' | |
| }); | |
| } | |
| }); | |
| }); | |
| // Add reveal classes to skill cards | |
| const skillCards = document.querySelectorAll('.skill-card'); | |
| skillCards.forEach((card, index) => { | |
| card.classList.add('reveal'); | |
| card.style.transitionDelay = `${index * 0.1}s`; | |
| }); | |
| // Add reveal classes to project containers | |
| const projectContainers = document.querySelectorAll('.project-container'); | |
| projectContainers.forEach((card, index) => { | |
| card.classList.add('reveal'); | |
| card.style.transitionDelay = `${index * 0.15}s`; | |
| }); | |
| }); | |
| // Typing effect for hero | |
| function typeWriter(element, text, speed = 50) { | |
| let i = 0; | |
| element.innerHTML = ''; | |
| function type() { | |
| if (i < text.length) { | |
| element.innerHTML += text.charAt(i); | |
| i++; | |
| setTimeout(type, speed); | |
| } | |
| } | |
| type(); | |
| } | |