410 lines
13 KiB
JavaScript
410 lines
13 KiB
JavaScript
// Cookie Banner Functionality
|
|
const cookieBanner = document.getElementById('cookie-banner');
|
|
const acceptCookiesBtn = document.getElementById('accept-cookies');
|
|
const declineCookiesBtn = document.getElementById('decline-cookies');
|
|
const cookieNotice = document.getElementById('cookie-notice');
|
|
const viewerIframe = document.getElementById('viewer-iframe');
|
|
const reopenCookieBannerBtn = document.getElementById('reopen-cookie-banner');
|
|
|
|
const COOKIE_CONSENT_KEY = 'cookieConsent';
|
|
const VIEWER_URL = 'https://mx-static.markilux.com/360/16981/16981.html';
|
|
|
|
// Check cookie consent on page load
|
|
function checkCookieConsent() {
|
|
const consent = localStorage.getItem(COOKIE_CONSENT_KEY);
|
|
|
|
if (consent === null) {
|
|
// No consent given yet, show banner
|
|
cookieBanner.classList.remove('hidden');
|
|
showCookieNotice();
|
|
} else if (consent === 'accepted') {
|
|
// Cookies accepted, load 3D viewer
|
|
load3DViewer();
|
|
} else {
|
|
// Cookies declined, show notice
|
|
showCookieNotice();
|
|
}
|
|
}
|
|
|
|
// Accept cookies
|
|
if (acceptCookiesBtn) {
|
|
acceptCookiesBtn.addEventListener('click', () => {
|
|
localStorage.setItem(COOKIE_CONSENT_KEY, 'accepted');
|
|
cookieBanner.classList.add('hidden');
|
|
load3DViewer();
|
|
});
|
|
}
|
|
|
|
// Decline cookies
|
|
if (declineCookiesBtn) {
|
|
declineCookiesBtn.addEventListener('click', () => {
|
|
localStorage.setItem(COOKIE_CONSENT_KEY, 'declined');
|
|
cookieBanner.classList.add('hidden');
|
|
showCookieNotice();
|
|
});
|
|
}
|
|
|
|
// Reopen cookie banner
|
|
if (reopenCookieBannerBtn) {
|
|
reopenCookieBannerBtn.addEventListener('click', () => {
|
|
cookieBanner.classList.remove('hidden');
|
|
});
|
|
}
|
|
|
|
// Load 3D viewer
|
|
function load3DViewer() {
|
|
if (cookieNotice) cookieNotice.classList.add('hidden');
|
|
if (viewerIframe) viewerIframe.src = VIEWER_URL;
|
|
}
|
|
|
|
// Show cookie notice instead of viewer
|
|
function showCookieNotice() {
|
|
if (cookieNotice) cookieNotice.classList.remove('hidden');
|
|
if (viewerIframe) viewerIframe.src = '';
|
|
}
|
|
|
|
// Mobile Menu Toggle
|
|
const mobileMenuToggle = document.getElementById('mobile-menu-toggle');
|
|
const mobileMenu = document.getElementById('mobile-menu');
|
|
|
|
if (mobileMenuToggle && mobileMenu) {
|
|
mobileMenuToggle.addEventListener('click', () => {
|
|
mobileMenu.classList.toggle('active');
|
|
});
|
|
|
|
// Close mobile menu when clicking on a link
|
|
mobileMenu.querySelectorAll('a').forEach(link => {
|
|
link.addEventListener('click', () => {
|
|
mobileMenu.classList.remove('active');
|
|
});
|
|
});
|
|
}
|
|
|
|
// Hero Carousel
|
|
const heroCarousel = document.getElementById('hero-carousel');
|
|
if (heroCarousel) {
|
|
const heroSlides = heroCarousel.querySelectorAll('.carousel-slide');
|
|
const heroIndicators = heroCarousel.querySelectorAll('.indicator');
|
|
let heroCurrentSlide = 0;
|
|
const heroSlideCount = heroSlides.length;
|
|
|
|
function showHeroSlide(index) {
|
|
heroSlides.forEach((slide, i) => {
|
|
slide.classList.toggle('active', i === index);
|
|
});
|
|
heroIndicators.forEach((indicator, i) => {
|
|
indicator.classList.toggle('active', i === index);
|
|
});
|
|
heroCurrentSlide = index;
|
|
}
|
|
|
|
function nextHeroSlide() {
|
|
const next = (heroCurrentSlide + 1) % heroSlideCount;
|
|
showHeroSlide(next);
|
|
}
|
|
|
|
// Auto-rotate hero carousel
|
|
setInterval(nextHeroSlide, 5000);
|
|
|
|
// Click on indicators
|
|
heroIndicators.forEach((indicator, index) => {
|
|
indicator.addEventListener('click', () => {
|
|
showHeroSlide(index);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Leistungen Carousel
|
|
const leistungenTrack = document.getElementById('leistungen-track');
|
|
const leistungenPrevBtn = document.getElementById('leistungen-prev');
|
|
const leistungenNextBtn = document.getElementById('leistungen-next');
|
|
const leistungenIndicators = document.querySelectorAll('#leistungen-indicators .indicator');
|
|
|
|
if (leistungenTrack && leistungenPrevBtn && leistungenNextBtn) {
|
|
const leistungenSlides = leistungenTrack.querySelectorAll('.leistung-slide');
|
|
let leistungenCurrentSlide = 0;
|
|
const leistungenSlideCount = leistungenSlides.length;
|
|
|
|
function showLeistungenSlide(index) {
|
|
leistungenTrack.style.transform = `translateX(-${index * 100}%)`;
|
|
leistungenSlides.forEach((slide, i) => {
|
|
slide.classList.toggle('active', i === index);
|
|
});
|
|
if (leistungenIndicators.length > 0) {
|
|
leistungenIndicators.forEach((indicator, i) => {
|
|
indicator.classList.toggle('active', i === index);
|
|
});
|
|
}
|
|
leistungenCurrentSlide = index;
|
|
}
|
|
|
|
leistungenPrevBtn.addEventListener('click', () => {
|
|
const prev = (leistungenCurrentSlide - 1 + leistungenSlideCount) % leistungenSlideCount;
|
|
showLeistungenSlide(prev);
|
|
});
|
|
|
|
leistungenNextBtn.addEventListener('click', () => {
|
|
const next = (leistungenCurrentSlide + 1) % leistungenSlideCount;
|
|
showLeistungenSlide(next);
|
|
});
|
|
|
|
// Click on indicators
|
|
leistungenIndicators.forEach((indicator, index) => {
|
|
indicator.addEventListener('click', () => {
|
|
showLeistungenSlide(index);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Referenzen Slideshow
|
|
const referenzenSlideshow = document.getElementById('referenzen-slideshow');
|
|
if (referenzenSlideshow) {
|
|
const referenzenSlides = referenzenSlideshow.querySelectorAll('.slideshow-slide');
|
|
const referenzenIndicators = referenzenSlideshow.querySelectorAll('.indicator');
|
|
let referenzenCurrentSlide = 0;
|
|
const referenzenSlideCount = referenzenSlides.length;
|
|
|
|
function showReferenzenSlide(index) {
|
|
referenzenSlides.forEach((slide, i) => {
|
|
slide.classList.toggle('active', i === index);
|
|
});
|
|
referenzenIndicators.forEach((indicator, i) => {
|
|
indicator.classList.toggle('active', i === index);
|
|
});
|
|
referenzenCurrentSlide = index;
|
|
}
|
|
|
|
function nextReferenzenSlide() {
|
|
const next = (referenzenCurrentSlide + 1) % referenzenSlideCount;
|
|
showReferenzenSlide(next);
|
|
}
|
|
|
|
// Auto-rotate referenzen slideshow
|
|
setInterval(nextReferenzenSlide, 6000);
|
|
|
|
// Click on indicators
|
|
referenzenIndicators.forEach((indicator, index) => {
|
|
indicator.addEventListener('click', () => {
|
|
showReferenzenSlide(index);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Contact Form
|
|
const contactForm = document.getElementById('contact-form');
|
|
const formSuccess = document.getElementById('form-success');
|
|
const formError = document.getElementById('form-error');
|
|
|
|
if (contactForm) {
|
|
contactForm.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
|
|
const formData = new FormData(contactForm);
|
|
const data = {
|
|
name: formData.get('name'),
|
|
email: formData.get('email'),
|
|
phone: formData.get('phone'),
|
|
subject: formData.get('subject'),
|
|
message: formData.get('message'),
|
|
privacy: formData.get('privacy')
|
|
};
|
|
|
|
// Basic validation
|
|
if (!data.name || !data.email || !data.subject || !data.message || !data.privacy) {
|
|
alert('Bitte füllen Sie alle Pflichtfelder aus.');
|
|
return;
|
|
}
|
|
|
|
// Email validation
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(data.email)) {
|
|
alert('Bitte geben Sie eine gültige E-Mail-Adresse ein.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Simulate form submission (replace with actual endpoint)
|
|
// In a real implementation, you would send this to a server endpoint
|
|
// that handles the email sending (e.g., using nodemailer, SendGrid, etc.)
|
|
|
|
// For demonstration, we'll simulate a successful submission
|
|
await simulateFormSubmission(data);
|
|
|
|
// Show success message
|
|
contactForm.classList.add('hidden');
|
|
if (formSuccess) formSuccess.classList.remove('hidden');
|
|
if (formError) formError.classList.add('hidden');
|
|
|
|
// Reset form
|
|
contactForm.reset();
|
|
|
|
// Hide success message after 5 seconds and show form again
|
|
setTimeout(() => {
|
|
if (formSuccess) formSuccess.classList.add('hidden');
|
|
contactForm.classList.remove('hidden');
|
|
}, 5000);
|
|
|
|
} catch (error) {
|
|
console.error('Form submission error:', error);
|
|
if (formError) formError.classList.remove('hidden');
|
|
if (formSuccess) formSuccess.classList.add('hidden');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Simulate form submission (replace with actual API call)
|
|
function simulateFormSubmission(data) {
|
|
return new Promise((resolve, reject) => {
|
|
// Simulate network delay
|
|
setTimeout(() => {
|
|
console.log('Form data submitted:', data);
|
|
// Simulate 95% success rate for demo
|
|
if (Math.random() > 0.05) {
|
|
resolve({ success: true });
|
|
} else {
|
|
reject(new Error('Network error'));
|
|
}
|
|
}, 1000);
|
|
});
|
|
}
|
|
|
|
// Smooth scroll for 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 headerOffset = 70;
|
|
const elementPosition = target.getBoundingClientRect().top;
|
|
const offsetPosition = elementPosition + window.pageYOffset - headerOffset;
|
|
|
|
window.scrollTo({
|
|
top: offsetPosition,
|
|
behavior: 'smooth'
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
// Navbar scroll effect
|
|
let lastScroll = 0;
|
|
const navbar = document.getElementById('navbar');
|
|
|
|
window.addEventListener('scroll', () => {
|
|
const currentScroll = window.pageYOffset;
|
|
|
|
if (currentScroll > 100) {
|
|
navbar.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.1)';
|
|
} else {
|
|
navbar.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)';
|
|
}
|
|
|
|
lastScroll = currentScroll;
|
|
});
|
|
|
|
// Initialize on page load
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
checkCookieConsent();
|
|
initNavHighlight();
|
|
});
|
|
|
|
// Navigation highlight bubble functionality
|
|
function initNavHighlight() {
|
|
const highlight = document.getElementById('nav-highlight');
|
|
const navLinks = document.querySelectorAll('.nav-links li');
|
|
const sections = document.querySelectorAll('section[id]');
|
|
|
|
if (!highlight || navLinks.length === 0) return;
|
|
|
|
function updateHighlight(element) {
|
|
if (!element) {
|
|
highlight.classList.remove('active');
|
|
return;
|
|
}
|
|
|
|
const link = element.querySelector('a');
|
|
if (!link) return;
|
|
|
|
const linkRect = link.getBoundingClientRect();
|
|
const navContainerRect = document.querySelector('.nav-container').getBoundingClientRect();
|
|
|
|
highlight.style.width = `${linkRect.width}px`;
|
|
highlight.style.height = `${linkRect.height}px`;
|
|
highlight.style.left = `${linkRect.left - navContainerRect.left}px`;
|
|
highlight.style.top = `${linkRect.top - navContainerRect.top}px`;
|
|
highlight.classList.add('active');
|
|
}
|
|
|
|
function getCurrentSection() {
|
|
const scrollPos = window.scrollY + window.innerHeight / 3;
|
|
|
|
for (let i = sections.length - 1; i >= 0; i--) {
|
|
const section = sections[i];
|
|
const sectionTop = section.offsetTop;
|
|
const sectionHeight = section.offsetHeight;
|
|
|
|
if (scrollPos >= sectionTop && scrollPos < sectionTop + sectionHeight) {
|
|
return section.id;
|
|
}
|
|
}
|
|
return sections[0]?.id;
|
|
}
|
|
|
|
// Check if we're in the home section (at the top of the page)
|
|
function isInHomeSection() {
|
|
return window.scrollY < window.innerHeight / 2;
|
|
}
|
|
|
|
function updateActiveNav() {
|
|
// Hide bubble when in home section
|
|
if (isInHomeSection()) {
|
|
highlight.classList.remove('active');
|
|
return;
|
|
}
|
|
|
|
const currentSection = getCurrentSection();
|
|
|
|
navLinks.forEach(li => {
|
|
const section = li.getAttribute('data-section');
|
|
if (section === currentSection) {
|
|
updateHighlight(li);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Update on scroll with snap-friendly timing
|
|
let ticking = false;
|
|
window.addEventListener('scroll', () => {
|
|
if (!ticking) {
|
|
window.requestAnimationFrame(() => {
|
|
updateActiveNav();
|
|
ticking = false;
|
|
});
|
|
ticking = true;
|
|
}
|
|
}, { passive: true });
|
|
|
|
// Initial update
|
|
updateActiveNav();
|
|
|
|
// Update on hover
|
|
navLinks.forEach(li => {
|
|
li.addEventListener('mouseenter', () => {
|
|
updateHighlight(li);
|
|
});
|
|
});
|
|
|
|
// Reset to current section on mouse leave from nav
|
|
document.querySelector('.nav-links').addEventListener('mouseleave', () => {
|
|
updateActiveNav();
|
|
});
|
|
}
|
|
|
|
// Handle visibility change to pause/resume carousels
|
|
document.addEventListener('visibilitychange', () => {
|
|
if (document.hidden) {
|
|
// Page is hidden, could pause animations here if needed
|
|
} else {
|
|
// Page is visible again
|
|
}
|
|
}); |