Features: - Complete Luftglanz drone cleaning website - AI chat assistant integrated with OpenAI API - Expert product advice for AGO Quart and Mellerud cleaning products - Formal German language support (Sie form) - Secure PHP backend for API calls - Responsive design with mobile support - Product-specific knowledge base - Safety statements from manufacturers - Multi-page integration (index, products, services, contact) Technical components: - AI chat widget (js/ai-chat.js) - Chat styling (css/components/ai-chat.css) - Backend API (ai-chat-api.php) - Product knowledge base with detailed specifications - Demo and documentation files
335 lines
15 KiB
JavaScript
335 lines
15 KiB
JavaScript
/**
|
|
* Roof Cleaning Drone Background Animations
|
|
* Creates animated drones with water spray effects
|
|
*/
|
|
(function() {
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Apply the background to the entire site
|
|
applyCleanBackground();
|
|
|
|
// Add animated drones to hero section
|
|
enhanceHeroSection();
|
|
|
|
// Add water droplet effects to service cards
|
|
enhanceServiceCards();
|
|
});
|
|
|
|
function applyCleanBackground() {
|
|
// Remove any existing star/cosmic backgrounds
|
|
const existingStars = document.querySelector('.stars');
|
|
if (existingStars) {
|
|
existingStars.remove();
|
|
}
|
|
|
|
// Add clean background to body
|
|
document.body.style.background = '#f8f9fa';
|
|
document.body.style.backgroundImage = `
|
|
linear-gradient(120deg, rgba(99, 183, 241, 0.1) 0%, transparent 40%),
|
|
linear-gradient(240deg, rgba(220, 237, 249, 0.2) 0%, transparent 40%)
|
|
`;
|
|
|
|
// Add subtle diagonal pattern
|
|
const pattern = document.createElement('div');
|
|
pattern.className = 'clean-pattern';
|
|
pattern.style.position = 'fixed';
|
|
pattern.style.top = '0';
|
|
pattern.style.left = '0';
|
|
pattern.style.width = '100%';
|
|
pattern.style.height = '100%';
|
|
pattern.style.pointerEvents = 'none';
|
|
pattern.style.opacity = '0.03';
|
|
pattern.style.zIndex = '-1';
|
|
pattern.style.backgroundImage = `
|
|
repeating-linear-gradient(
|
|
45deg,
|
|
#3498db,
|
|
#3498db 2px,
|
|
transparent 2px,
|
|
transparent 10px
|
|
)
|
|
`;
|
|
document.body.appendChild(pattern);
|
|
|
|
// Update text colors for better contrast on light background
|
|
document.querySelectorAll('p, h1, h2, h3, h4, h5, h6').forEach(el => {
|
|
// Only change if still using the dark theme colors
|
|
if (getComputedStyle(el).color === 'rgb(216, 216, 255)' ||
|
|
getComputedStyle(el).color === 'rgb(143, 143, 183)') {
|
|
el.style.color = '#505050';
|
|
}
|
|
});
|
|
}
|
|
|
|
function enhanceHeroSection() {
|
|
const heroSection = document.querySelector('.hero');
|
|
if (!heroSection) return;
|
|
|
|
// Remove any existing background
|
|
if (heroSection.style.backgroundImage.includes('stars-bg.jpg')) {
|
|
heroSection.style.backgroundImage = 'none';
|
|
}
|
|
|
|
// Create a sky gradient background
|
|
heroSection.style.background = 'linear-gradient(to bottom, #87CEEB 0%, #e6f7ff 100%)';
|
|
heroSection.style.position = 'relative';
|
|
heroSection.style.overflow = 'hidden';
|
|
|
|
// Create animation container
|
|
const animationContainer = document.createElement('div');
|
|
animationContainer.className = 'drone-animation-container';
|
|
animationContainer.style.position = 'absolute';
|
|
animationContainer.style.top = '0';
|
|
animationContainer.style.left = '0';
|
|
animationContainer.style.width = '100%';
|
|
animationContainer.style.height = '100%';
|
|
animationContainer.style.pointerEvents = 'none';
|
|
animationContainer.style.zIndex = '1';
|
|
heroSection.appendChild(animationContainer);
|
|
|
|
// Add roof silhouette
|
|
const roofSilhouette = document.createElement('div');
|
|
roofSilhouette.className = 'roof-silhouette';
|
|
roofSilhouette.style.position = 'absolute';
|
|
roofSilhouette.style.bottom = '0';
|
|
roofSilhouette.style.left = '0';
|
|
roofSilhouette.style.width = '100%';
|
|
roofSilhouette.style.height = '20%';
|
|
roofSilhouette.style.background = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDIwMCI+PHBhdGggZD0iTTAgMjAwVjE1MEg1MEwxMDAgMTAwTDE1MCAxNTBIMjAwTDI1MCAxMDBMMzAwIDE1MEgzNTBMNDAwIDUwTDQ1MCAxNTBINTAwTDU1MCAxMDBMNjAwIDE1MEg2NTBMNzAwIDEwMEw3NTAgMTUwSDgwMEw4NTAgNTBMOTAwIDE1MEg5NTBMMTAwMCAxMDBMMTA1MCAxNTBIMTEwMEwxMTUwIDEwMEwxMjAwIDE1MFYyMDBIMFoiIGZpbGw9IiNlMGUwZTAiIGZpbGwtb3BhY2l0eT0iMC40Ii8+PC9zdmc+")';
|
|
roofSilhouette.style.backgroundSize = 'cover';
|
|
roofSilhouette.style.zIndex = '0';
|
|
animationContainer.appendChild(roofSilhouette);
|
|
|
|
// Create multiple drones with spray effects
|
|
createCleaningDrone(animationContainer, 20, 30, -1, 20);
|
|
createCleaningDrone(animationContainer, 60, 20, 1, 25);
|
|
createCleaningDrone(animationContainer, 40, 50, -1, 30);
|
|
|
|
// Add keyframes for animations
|
|
addDroneAnimationStyles();
|
|
}
|
|
|
|
function createCleaningDrone(container, startX, startY, direction, duration) {
|
|
// Create drone container
|
|
const droneElement = document.createElement('div');
|
|
droneElement.className = 'cleaning-drone';
|
|
droneElement.style.position = 'absolute';
|
|
droneElement.style.left = `${startX}%`;
|
|
droneElement.style.top = `${startY}%`;
|
|
droneElement.style.width = '60px';
|
|
droneElement.style.height = '60px';
|
|
droneElement.style.zIndex = '2';
|
|
|
|
// Calculate unique animation name
|
|
const animationName = `drone-path-${startX}-${startY}`;
|
|
droneElement.style.animation = `${animationName} ${duration}s linear infinite`;
|
|
|
|
// Create drone body
|
|
const droneBody = document.createElement('div');
|
|
droneBody.className = 'drone-body';
|
|
droneBody.style.position = 'relative';
|
|
droneBody.style.width = '40px';
|
|
droneBody.style.height = '40px';
|
|
droneBody.style.borderRadius = '50%';
|
|
droneBody.style.backgroundColor = '#3498db';
|
|
droneBody.style.border = '2px solid #2980b9';
|
|
droneBody.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.2)';
|
|
droneBody.style.margin = '0 auto';
|
|
droneBody.style.zIndex = '2';
|
|
droneElement.appendChild(droneBody);
|
|
|
|
// Add central hub
|
|
const droneHub = document.createElement('div');
|
|
droneHub.className = 'drone-hub';
|
|
droneHub.style.position = 'absolute';
|
|
droneHub.style.top = '50%';
|
|
droneHub.style.left = '50%';
|
|
droneHub.style.width = '15px';
|
|
droneHub.style.height = '15px';
|
|
droneHub.style.borderRadius = '50%';
|
|
droneHub.style.backgroundColor = '#fff';
|
|
droneHub.style.transform = 'translate(-50%, -50%)';
|
|
droneHub.style.zIndex = '3';
|
|
droneBody.appendChild(droneHub);
|
|
|
|
// Add propellers
|
|
for (let i = 0; i < 4; i++) {
|
|
const propContainer = document.createElement('div');
|
|
propContainer.className = 'propeller-container';
|
|
propContainer.style.position = 'absolute';
|
|
propContainer.style.width = '15px';
|
|
propContainer.style.height = '15px';
|
|
|
|
// Position propellers around drone
|
|
switch(i) {
|
|
case 0: // top left
|
|
propContainer.style.top = '-10px';
|
|
propContainer.style.left = '-10px';
|
|
break;
|
|
case 1: // top right
|
|
propContainer.style.top = '-10px';
|
|
propContainer.style.right = '-10px';
|
|
break;
|
|
case 2: // bottom left
|
|
propContainer.style.bottom = '-10px';
|
|
propContainer.style.left = '-10px';
|
|
break;
|
|
case 3: // bottom right
|
|
propContainer.style.bottom = '-10px';
|
|
propContainer.style.right = '-10px';
|
|
break;
|
|
}
|
|
|
|
// Create propeller
|
|
const propeller = document.createElement('div');
|
|
propeller.className = 'propeller';
|
|
propeller.style.width = '100%';
|
|
propeller.style.height = '100%';
|
|
propeller.style.borderRadius = '50%';
|
|
propeller.style.borderTop = '2px solid rgba(255,255,255,0.8)';
|
|
propeller.style.borderLeft = '2px solid rgba(255,255,255,0.6)';
|
|
propeller.style.animation = 'spin-propeller 0.15s linear infinite';
|
|
propContainer.appendChild(propeller);
|
|
|
|
droneBody.appendChild(propContainer);
|
|
}
|
|
|
|
// Create water spray effect
|
|
const waterSpray = document.createElement('div');
|
|
waterSpray.className = 'water-spray';
|
|
waterSpray.style.position = 'absolute';
|
|
waterSpray.style.bottom = '-20px';
|
|
waterSpray.style.left = '50%';
|
|
waterSpray.style.transform = 'translateX(-50%)';
|
|
waterSpray.style.width = '30px';
|
|
waterSpray.style.height = '50px';
|
|
waterSpray.style.zIndex = '1';
|
|
droneElement.appendChild(waterSpray);
|
|
|
|
// Add water droplets to the spray
|
|
for (let i = 0; i < 12; i++) {
|
|
const droplet = document.createElement('div');
|
|
droplet.className = 'water-droplet';
|
|
droplet.style.position = 'absolute';
|
|
droplet.style.width = `${3 + Math.random() * 3}px`;
|
|
droplet.style.height = `${5 + Math.random() * 7}px`;
|
|
droplet.style.backgroundColor = 'rgba(173, 216, 230, 0.7)';
|
|
droplet.style.borderRadius = '50%';
|
|
|
|
// Randomize position within spray
|
|
const angle = Math.random() * 30 - 15; // -15 to 15 degrees
|
|
const distance = 5 + Math.random() * 45; // 5 to 50px
|
|
|
|
droplet.style.top = `${distance}px`;
|
|
droplet.style.left = '50%';
|
|
droplet.style.transform = `translateX(-50%) rotate(${angle}deg)`;
|
|
|
|
// Different animation duration for each droplet
|
|
const fallDuration = 0.5 + Math.random() * 0.5;
|
|
droplet.style.animation = `fall-droplet ${fallDuration}s infinite linear`;
|
|
|
|
waterSpray.appendChild(droplet);
|
|
}
|
|
|
|
// Create path animation for this specific drone
|
|
const keyframesStyle = document.createElement('style');
|
|
keyframesStyle.innerHTML = `
|
|
@keyframes ${animationName} {
|
|
0% {
|
|
transform: translateX(${direction > 0 ? '-100px' : '100vw'}) translateY(0px) rotate(${direction > 0 ? '0deg' : '180deg'});
|
|
}
|
|
25% {
|
|
transform: translateX(${direction > 0 ? 'calc(20vw)' : 'calc(80vw - 100px)'}) translateY(-20px) rotate(${direction > 0 ? '0deg' : '180deg'});
|
|
}
|
|
50% {
|
|
transform: translateX(${direction > 0 ? 'calc(40vw)' : 'calc(60vw - 100px)'}) translateY(30px) rotate(${direction > 0 ? '0deg' : '180deg'});
|
|
}
|
|
75% {
|
|
transform: translateX(${direction > 0 ? 'calc(60vw)' : 'calc(40vw - 100px)'}) translateY(-15px) rotate(${direction > 0 ? '0deg' : '180deg'});
|
|
}
|
|
100% {
|
|
transform: translateX(${direction > 0 ? '100vw' : '-100px'}) translateY(10px) rotate(${direction > 0 ? '0deg' : '180deg'});
|
|
}
|
|
}
|
|
`;
|
|
document.head.appendChild(keyframesStyle);
|
|
|
|
container.appendChild(droneElement);
|
|
}
|
|
|
|
function addDroneAnimationStyles() {
|
|
const styleSheet = document.createElement('style');
|
|
styleSheet.innerHTML = `
|
|
@keyframes spin-propeller {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
|
|
@keyframes fall-droplet {
|
|
0% {
|
|
opacity: 0.8;
|
|
transform: translateX(-50%) translateY(0) scale(1);
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
transform: translateX(-50%) translateY(30px) scale(0.5);
|
|
}
|
|
}
|
|
`;
|
|
document.head.appendChild(styleSheet);
|
|
}
|
|
|
|
function enhanceServiceCards() {
|
|
const serviceCards = document.querySelectorAll('.service-card');
|
|
if (!serviceCards.length) return;
|
|
|
|
serviceCards.forEach(card => {
|
|
// Update card styling to match clean theme
|
|
card.style.backgroundColor = 'white';
|
|
card.style.borderRadius = '10px';
|
|
card.style.boxShadow = '0 10px 30px rgba(0, 0, 0, 0.1)';
|
|
card.style.border = '1px solid rgba(0, 0, 0, 0.05)';
|
|
card.style.overflow = 'hidden';
|
|
|
|
// Add water droplet accent at the top
|
|
const waterAccent = document.createElement('div');
|
|
waterAccent.className = 'water-accent';
|
|
waterAccent.style.height = '5px';
|
|
waterAccent.style.width = '100%';
|
|
waterAccent.style.position = 'absolute';
|
|
waterAccent.style.top = '0';
|
|
waterAccent.style.left = '0';
|
|
waterAccent.style.background = 'linear-gradient(90deg, #3498db, #00c2cb)';
|
|
card.prepend(waterAccent);
|
|
|
|
// Add subtle cleaning pattern to each card
|
|
addCleaningIconToCard(card);
|
|
});
|
|
}
|
|
|
|
function addCleaningIconToCard(card) {
|
|
// Create a container for the icon
|
|
const iconContainer = document.createElement('div');
|
|
iconContainer.className = 'cleaning-icon';
|
|
iconContainer.style.position = 'absolute';
|
|
iconContainer.style.top = '15px';
|
|
iconContainer.style.right = '15px';
|
|
iconContainer.style.width = '30px';
|
|
iconContainer.style.height = '30px';
|
|
iconContainer.style.opacity = '0.1';
|
|
|
|
// Randomly choose between different cleaning icons
|
|
const icons = [
|
|
// Water droplet
|
|
`<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 20C16.4183 20 20 16.4183 20 12C20 7.58172 12 3 12 3C12 3 4 7.58172 4 12C4 16.4183 7.58172 20 12 20Z" fill="#3498db"/></svg>`,
|
|
// Spray bottle
|
|
`<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8 3H11V5H13V3H16V5H14V7H17L19 10V21H6V10L8 7H11V5H8V3ZM8 10V19H17V10L15.8 8H9.2L8 10Z" fill="#3498db"/></svg>`,
|
|
// Drone
|
|
`<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 8C13.1046 8 14 7.10457 14 6C14 4.89543 13.1046 4 12 4C10.8954 4 10 4.89543 10 6C10 7.10457 10.8954 8 12 8Z" fill="#3498db"/><path d="M4 10C5.10457 10 6 9.10457 6 8C6 6.89543 5.10457 6 4 6C2.89543 6 2 6.89543 2 8C2 9.10457 2.89543 10 4 10Z" fill="#3498db"/><path d="M20 10C21.1046 10 22 9.10457 22 8C22 6.89543 21.1046 6 20 6C18.8954 6 18 6.89543 18 8C18 9.10457 18.8954 10 20 10Z" fill="#3498db"/><path d="M12 20C13.1046 20 14 19.1046 14 18C14 16.8954 13.1046 16 12 16C10.8954 16 10 16.8954 10 18C10 19.1046 10.8954 20 12 20Z" fill="#3498db"/><path d="M12 8V16M4 10L10 16M20 10L14 16" stroke="#3498db" stroke-width="2" stroke-linecap="round"/></svg>`
|
|
];
|
|
|
|
// Choose a random icon
|
|
iconContainer.innerHTML = icons[Math.floor(Math.random() * icons.length)];
|
|
card.appendChild(iconContainer);
|
|
}
|
|
})();
|