Initial commit

This commit is contained in:
2026-01-30 09:21:13 +01:00
commit 3c0deac320
7 changed files with 2254 additions and 0 deletions
+410
View File
@@ -0,0 +1,410 @@
// 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
}
});