Initial commit
This commit is contained in:
@@ -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
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user