// ============================================ // Smooth Scrolling für Navigation 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 - 70; window.scrollTo({ top: offsetTop, behavior: 'smooth' }); // Navbar in Mobile schließen const navbarCollapse = document.querySelector('.navbar-collapse'); if (navbarCollapse.classList.contains('show')) { navbarCollapse.classList.remove('show'); } } }); }); // ============================================ // Navbar beim Scrollen // ============================================ let lastScroll = 0; const navbar = document.querySelector('.navbar'); window.addEventListener('scroll', () => { const currentScroll = window.pageYOffset; // Navbar Schatten beim Scrollen if (currentScroll > 100) { navbar.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.15)'; } else { navbar.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)'; } lastScroll = currentScroll; }); // ============================================ // Active Navigation Link beim Scrollen // ============================================ const sections = document.querySelectorAll('section[id]'); const navLinks = document.querySelectorAll('.nav-link'); window.addEventListener('scroll', () => { let current = ''; sections.forEach(section => { const sectionTop = section.offsetTop; const sectionHeight = section.clientHeight; if (window.pageYOffset >= (sectionTop - 100)) { current = section.getAttribute('id'); } }); navLinks.forEach(link => { link.classList.remove('active'); if (link.getAttribute('href') === `#${current}`) { link.classList.add('active'); } }); }); // ============================================ // Fade-in Animation beim Scrollen // ============================================ const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -100px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; } }); }, observerOptions); // Cards beobachten document.querySelectorAll('.card').forEach((card) => { card.style.opacity = '0'; card.style.transform = 'translateY(30px)'; card.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; observer.observe(card); }); // ============================================ // Card Tilt Effekt (optional) // ============================================ document.querySelectorAll('.hover-lift').forEach(card => { card.addEventListener('mousemove', (e) => { const rect = card.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const centerX = rect.width / 2; const centerY = rect.height / 2; const rotateX = (y - centerY) / 20; const rotateY = (centerX - x) / 20; card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) translateY(-10px)`; }); card.addEventListener('mouseleave', () => { card.style.transform = 'perspective(1000px) rotateX(0) rotateY(0) translateY(0)'; }); }); // ============================================ // Button Ripple Effekt // ============================================ document.querySelectorAll('.btn').forEach(button => { button.addEventListener('click', function(e) { const ripple = document.createElement('span'); const rect = this.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = e.clientX - rect.left - size / 2; const y = e.clientY - rect.top - size / 2; ripple.style.width = ripple.style.height = size + 'px'; ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; ripple.classList.add('ripple'); this.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); }); }); // CSS für Ripple Effekt dynamisch hinzufügen const style = document.createElement('style'); style.textContent = ` .btn { position: relative; overflow: hidden; } .ripple { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.5); transform: scale(0); animation: ripple-animation 0.6s ease-out; pointer-events: none; } @keyframes ripple-animation { to { transform: scale(4); opacity: 0; } } `; document.head.appendChild(style); // ============================================ // Jahr im Footer automatisch aktualisieren // ============================================ const currentYear = new Date().getFullYear(); const footerText = document.querySelector('footer p'); if (footerText && footerText.textContent.includes('©')) { footerText.textContent = `© ${currentYear} traidendorf`; } // ============================================ // Loading Animation (optional) // ============================================ window.addEventListener('load', () => { document.body.style.opacity = '0'; document.body.style.transition = 'opacity 0.5s ease'; setTimeout(() => { document.body.style.opacity = '1'; }, 100); }); // ============================================ // Externe Links in neuem Tab öffnen // ============================================ document.querySelectorAll('a[href^="http"]').forEach(link => { if (!link.hasAttribute('target')) { link.setAttribute('target', '_blank'); link.setAttribute('rel', 'noopener noreferrer'); } }); // ============================================ // Console Message // ============================================ console.log('%c Willkommen auf traidendorf.de! ', 'background: linear-gradient(135deg, #2c5f2d 0%, #7d9b76 100%); color: white; padding: 10px 20px; font-size: 16px; font-weight: bold;'); console.log('%c Website erstellt mit ❤️ für Traidendorf ', 'color: #2c5f2d; font-size: 12px;'); // ============================================ // Back to Top Button // ============================================ const backToTopButton = document.getElementById('backToTop'); // Button anzeigen/ausblenden beim Scrollen window.addEventListener('scroll', () => { if (window.pageYOffset > 300) { backToTopButton.classList.add('show'); } else { backToTopButton.classList.remove('show'); } });