Files
Websites/Profice WebSite/scripts/tech-onepager.min.js
2026-02-06 09:30:59 +01:00

1 line
11 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function(){// ===== SYSTEM GRAPHIC ANIMATIONS ===== const systemGraphic = document.getElementById('systemGraphic');const connections = document.getElementById('connections');const dataPoints = document.getElementById('dataPoints');if (systemGraphic && connections && dataPoints){initializeSystemGraphic();}function initializeSystemGraphic(){const nodes = systemGraphic.querySelectorAll('.node');const centralNode = systemGraphic.querySelector('.central-node');// Draw connection lines drawConnections();// Create animated data points createDataPoints();// Add node interactions nodes.forEach(node =>{node.addEventListener('mouseenter', function(){activateConnection(this);});node.addEventListener('mouseleave', function(){deactivateConnections();});// Special handling for central node if (node.classList.contains('central-node')){node.addEventListener('click', function(){triggerCentralNode(this);});}});// Scroll-based activation setupScrollActivation();}function drawConnections(){const centralNode = systemGraphic.querySelector('.central-node');const otherNodes = systemGraphic.querySelectorAll('.node:not(.central-node)');const centralRect = centralNode.getBoundingClientRect();const graphicRect = systemGraphic.getBoundingClientRect();const centerX = centralRect.left - graphicRect.left + centralRect.width / 2;const centerY = centralRect.top - graphicRect.top + centralRect.height / 2;connections.innerHTML = '';otherNodes.forEach(node =>{const nodeRect = node.getBoundingClientRect();const nodeX = nodeRect.left - graphicRect.left + nodeRect.width / 2;const nodeY = nodeRect.top - graphicRect.top + nodeRect.height / 2;const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');line.setAttribute('x1', centerX);line.setAttribute('y1', centerY);line.setAttribute('x2', nodeX);line.setAttribute('y2', nodeY);line.setAttribute('class', 'connection-line');line.setAttribute('data-target', node.dataset.node);connections.appendChild(line);});}function createDataPoints(){setInterval(() =>{if (Math.random() > 0.7){const dataPoint = document.createElement('div');dataPoint.className = 'data-point';const startNode = systemGraphic.querySelectorAll('.node:not(.central-node)')[ Math.floor(Math.random() * 5) ];const centralNode = systemGraphic.querySelector('.central-node');const startRect = startNode.getBoundingClientRect();const centralRect = centralNode.getBoundingClientRect();const graphicRect = systemGraphic.getBoundingClientRect();const startX = startRect.left - graphicRect.left + startRect.width / 2;const startY = startRect.top - graphicRect.top + startRect.height / 2;const endX = centralRect.left - graphicRect.left + centralRect.width / 2;const endY = centralRect.top - graphicRect.top + centralRect.height / 2;dataPoint.style.left = startX + 'px';dataPoint.style.top = startY + 'px';dataPoints.appendChild(dataPoint);// Animate along path animateDataPoint(dataPoint, startX, startY, endX, endY);// Remove after animation setTimeout(() =>{dataPoint.remove();}, 3000);}}, 800);}function animateDataPoint(point, startX, startY, endX, endY){const duration = 3000;const startTime = Date.now();function animate(){const elapsed = Date.now() - startTime;const progress = Math.min(elapsed / duration, 1);const easeProgress = 1 - Math.pow(1 - progress, 3);// Ease out cubic const currentX = startX + (endX - startX) * easeProgress;const currentY = startY + (endY - startY) * easeProgress;point.style.left = currentX + 'px';point.style.top = currentY + 'px';if (progress < 1){requestAnimationFrame(animate);}}requestAnimationFrame(animate);}function triggerCentralNode(node){// Add triggered class for growth animation node.classList.add('triggered');// Activate all connections const lines = connections.querySelectorAll('.connection-line');lines.forEach((line, index) =>{setTimeout(() =>{line.classList.add('active');}, index * 100);});// Remove triggered class after animation setTimeout(() =>{node.classList.remove('triggered');// Deactivate connections setTimeout(() =>{lines.forEach(line => line.classList.remove('active'));}, 500);}, 2000);}function activateConnection(node){const targetNode = node.dataset.node;const line = connections.querySelector(`[data-target="${targetNode}"]`);if (line){line.classList.add('active');}}function deactivateConnections(){const lines = connections.querySelectorAll('.connection-line');lines.forEach(line => line.classList.remove('active'));}function setupScrollActivation(){const observer = new IntersectionObserver((entries) =>{entries.forEach(entry =>{if (entry.isIntersecting){const lines = connections.querySelectorAll('.connection-line');lines.forEach((line, index) =>{setTimeout(() =>{line.classList.add('active');setTimeout(() =>{line.classList.remove('active');}, 2000);}, index * 200);});}});},{threshold: 0.5});observer.observe(systemGraphic);}// ===== PROCESS LINE ANIMATION ===== const processLine = document.getElementById('processLine');const processSteps = document.querySelectorAll('.process-step');const processConnectors = document.querySelectorAll('.process-connector');const stepDetails = document.querySelectorAll('.step-detail');if (processLine){setupProcessAnimation();}function setupProcessAnimation(){const observer = new IntersectionObserver((entries) =>{entries.forEach(entry =>{if (entry.isIntersecting){animateProcessLine();observer.unobserve(entry.target);}});},{threshold: 0.3});observer.observe(processLine);}function animateProcessLine(){// Animate connectors sequentially processConnectors.forEach((connector, index) =>{setTimeout(() =>{connector.classList.add('active');}, 500 + (index * 500));});// Activate steps sequentially processSteps.forEach((step, index) =>{setTimeout(() =>{step.classList.add('active');activateStepDetail(index + 1);}, 200 + (index * 500));});}function activateStepDetail(stepNumber){const detail = document.querySelector(`[data-step-detail="${stepNumber}"]`);if (detail){setTimeout(() =>{detail.classList.add('active');}, 300);}}// Step click interactions processSteps.forEach((step, index) =>{step.addEventListener('click', () =>{// Reset all steps processSteps.forEach(s => s.classList.remove('active'));processConnectors.forEach(c => c.classList.remove('active'));stepDetails.forEach(d => d.classList.remove('active'));// Activate up to clicked step for (let i = 0;i <= index;i++){processSteps[i].classList.add('active');activateStepDetail(i + 1);if (i < processConnectors.length){processConnectors[i].classList.add('active');}}});});// ===== INTERACTION CARD ANIMATIONS ===== const phoneInteraction = document.getElementById('phoneInteraction');const chatInteraction = document.getElementById('chatInteraction');if (phoneInteraction){setupPhoneInteraction();}if (chatInteraction){setupChatInteraction();}function setupPhoneInteraction(){const microphone = phoneInteraction.querySelector('.microphone');const pulseRing = phoneInteraction.querySelector('.pulse-ring');if (microphone && pulseRing){microphone.addEventListener('mouseenter', () =>{pulseRing.style.animation = 'pulse 0.8s infinite';});microphone.addEventListener('mouseleave', () =>{pulseRing.style.animation = 'pulse 2s infinite';});microphone.addEventListener('click', () =>{// Simulate phone call initiation microphone.style.transform = 'scale(0.95)';setTimeout(() =>{microphone.style.transform = 'scale(1.1)';setTimeout(() =>{microphone.style.transform = 'scale(1)';}, 200);}, 100);// Show feedback showInteractionFeedback('KI Telefon wird verbunden...');});}}function setupChatInteraction(){const chatWindow = chatInteraction.querySelector('.chat-window');const typingIndicator = chatInteraction.querySelector('.typing-indicator');if (chatWindow && typingIndicator){chatInteraction.addEventListener('mouseenter', () =>{// Start typing animation const spans = typingIndicator.querySelectorAll('span');spans.forEach((span, index) =>{span.style.animation = 'typing 1.4s infinite ease-in-out';span.style.animationDelay = `${-0.32 + (index * 0.16)}s`;});});const chatBtn = chatInteraction.querySelector('.interaction-btn.secondary');if (chatBtn){chatBtn.addEventListener('click', () =>{showInteractionFeedback('KI Chat wird gestartet...');});}}}function showInteractionFeedback(message){// Create temporary feedback element const feedback = document.createElement('div');feedback.style.cssText = ` position: fixed;top: 100px;left: 50%;transform: translateX(-50%);background: var(--accent-teal);color: white;padding: 16px 24px;border-radius: 8px;font-weight: 600;z-index: 10000;box-shadow: 0 8px 30px rgba(38, 166, 154, 0.4);animation: slideDown 0.3s ease;`;feedback.textContent = message;document.body.appendChild(feedback);setTimeout(() =>{feedback.style.animation = 'slideUp 0.3s ease';setTimeout(() =>{feedback.remove();}, 300);}, 2000);}// ===== HERO BUTTON INTERACTIONS ===== const kiPhoneBtn = document.getElementById('kiPhoneBtn');const chatBtn = document.getElementById('chatBtn');if (kiPhoneBtn){kiPhoneBtn.addEventListener('click', () =>{showInteractionFeedback('KI Telefon wird verbunden...');// Scroll to interaction section document.getElementById('interaction')?.scrollIntoView({behavior: 'smooth', block: 'center'});});}if (chatBtn){chatBtn.addEventListener('click', () =>{showInteractionFeedback('KI Chat wird gestartet...');// Scroll to interaction section document.getElementById('interaction')?.scrollIntoView({behavior: 'smooth', block: 'center'});});}// ===== SYSTEM CARD HOVER EFFECTS ===== const systemCards = document.querySelectorAll('.system-card');systemCards.forEach(card =>{card.addEventListener('mouseenter', function(){// Add subtle glow effect this.style.boxShadow = '0 20px 40px rgba(38, 166, 154, 0.15)';});card.addEventListener('mouseleave', function(){this.style.boxShadow = '0 12px 30px rgba(79, 71, 71, 0.1)';});});// ===== DATA CARD ANIMATIONS ===== const dataCards = document.querySelectorAll('.data-card');const dataCardObserver = new IntersectionObserver((entries) =>{entries.forEach((entry, index) =>{if (entry.isIntersecting){setTimeout(() =>{entry.target.style.animation = 'fadeInUp 0.6s ease forwards';}, index * 100);dataCardObserver.unobserve(entry.target);}});},{threshold: 0.1});dataCards.forEach(card =>{dataCardObserver.observe(card);});// ===== SMOOTH SCROLL FOR INTERNAL LINKS ===== document.querySelectorAll('a[href^="#"]').forEach(anchor =>{anchor.addEventListener('click', function (e){e.preventDefault();const target = document.querySelector(this.getAttribute('href'));if (target){target.scrollIntoView({behavior: 'smooth', block: 'start'});}});});// ===== UTILITY ANIMATIONS ===== // Add CSS animations dynamically const style = document.createElement('style');style.textContent = ` @keyframes slideDown{from{opacity: 0;transform: translate(-50%, -20px);}to{opacity: 1;transform: translate(-50%, 0);}}@keyframes slideUp{from{opacity: 1;transform: translate(-50%, 0);}to{opacity: 0;transform: translate(-50%, -20px);}}@keyframes fadeInUp{from{opacity: 0;transform: translateY(30px);}to{opacity: 1;transform: translateY(0);}}`;document.head.appendChild(style);// ===== PERFORMANCE OPTIMIZATION ===== // Throttle scroll events let ticking = false;function requestTick(){if (!ticking){requestAnimationFrame(updateScrollEffects);ticking = true;setTimeout(() =>{ticking = false;}, 16);}}function updateScrollEffects(){// Add scroll-based effects here if needed // Parallax, fade-ins, etc.}window.addEventListener('scroll', requestTick,{passive: true});// ===== INITIALIZATION COMPLETE ===== console.log('Tech-Onepager initialized successfully');});