Files
Website/js/animations-enhanced.js
2025-08-17 14:16:58 +02:00

303 Zeilen
10 KiB
JavaScript

/**
* Enhanced Animations and Interactions
* Premium effects for modern web experience
*/
const EnhancedAnimations = {
init() {
this.initScrollAnimations();
this.initParallaxEffects();
this.initMagneticButtons();
this.initTextAnimations();
this.initCardTilt();
this.initSmoothScroll();
this.initCursorEffects();
this.initNumberCounters();
this.initRevealOnScroll();
this.initNavbarEffects();
},
// Smooth scroll with easing
initSmoothScroll() {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
const offset = 100;
const targetPosition = target.offsetTop - offset;
window.scrollTo({
top: targetPosition,
behavior: 'smooth'
});
}
});
});
},
// Parallax scrolling effects
initParallaxEffects() {
const parallaxElements = document.querySelectorAll('.parallax');
let ticking = false;
function updateParallax() {
const scrolled = window.pageYOffset;
parallaxElements.forEach(element => {
const speed = element.dataset.speed || 0.5;
const yPos = -(scrolled * speed);
element.style.transform = `translateY(${yPos}px)`;
});
ticking = false;
}
function requestTick() {
if (!ticking) {
window.requestAnimationFrame(updateParallax);
ticking = true;
}
}
window.addEventListener('scroll', requestTick);
},
// Magnetic button effects
initMagneticButtons() {
const magneticButtons = document.querySelectorAll('.primary-button, .secondary-button, .cta-button');
magneticButtons.forEach(button => {
button.addEventListener('mousemove', (e) => {
const rect = button.getBoundingClientRect();
const x = e.clientX - rect.left - rect.width / 2;
const y = e.clientY - rect.top - rect.height / 2;
button.style.transform = `translate(${x * 0.2}px, ${y * 0.2}px) scale(1.05)`;
});
button.addEventListener('mouseleave', () => {
button.style.transform = '';
});
});
},
// Advanced text animations
initTextAnimations() {
// Typewriter effect for hero title - DISABLED to prevent duplication
// The title already has CSS animations applied
/* Commented out to fix duplication issue
const heroTitle = document.querySelector('.main-title');
if (heroTitle && !heroTitle.dataset.animated) {
heroTitle.dataset.animated = 'true';
const text = heroTitle.textContent;
heroTitle.textContent = '';
heroTitle.style.opacity = '1';
let index = 0;
const typeWriter = () => {
if (index < text.length) {
heroTitle.textContent += text.charAt(index);
index++;
setTimeout(typeWriter, 50);
}
};
// Start typewriter after a short delay
setTimeout(typeWriter, 500);
}
*/
// Word-by-word reveal for hero text
const heroText = document.querySelector('.hero-text');
if (heroText) {
const words = heroText.textContent.split(' ');
heroText.innerHTML = words.map(word =>
`<span class="word-reveal" style="opacity: 0; display: inline-block; transform: translateY(20px); transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);">${word}</span>`
).join(' ');
const wordSpans = heroText.querySelectorAll('.word-reveal');
wordSpans.forEach((word, index) => {
setTimeout(() => {
word.style.opacity = '1';
word.style.transform = 'translateY(0)';
}, 1000 + index * 100);
});
}
},
// 3D card tilt effect
initCardTilt() {
const cards = document.querySelectorAll('.tool-card, .value-card, .why-card');
cards.forEach(card => {
card.addEventListener('mousemove', (e) => {
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const rotateX = (y - centerY) / 10;
const rotateY = (centerX - x) / 10;
card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.02)`;
});
card.addEventListener('mouseleave', () => {
card.style.transform = '';
});
});
},
// Custom cursor effects - DISABLED
initCursorEffects() {
// Cursor removed as requested
return;
},
// Animated number counters
initNumberCounters() {
const counters = document.querySelectorAll('.indicator-value');
const animationDuration = 2000;
let hasAnimated = false;
const animateCounters = () => {
if (hasAnimated) return;
counters.forEach(counter => {
const target = parseFloat(counter.dataset.target);
const start = 0;
const increment = target / (animationDuration / 16);
let current = start;
const updateCounter = () => {
current += increment;
if (current < target) {
counter.textContent = Math.floor(current);
requestAnimationFrame(updateCounter);
} else {
counter.textContent = target % 1 === 0 ? target : target.toFixed(1);
}
};
updateCounter();
});
hasAnimated = true;
};
// Trigger on scroll into view
const observerOptions = {
threshold: 0.5
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animateCounters();
}
});
}, observerOptions);
const indicatorsSection = document.querySelector('.trust-indicators');
if (indicatorsSection) {
observer.observe(indicatorsSection);
}
},
// Reveal elements on scroll
initRevealOnScroll() {
const revealElements = document.querySelectorAll('.about-panel, .tool-card, .value-card, .why-card, .competency-item');
revealElements.forEach((element, index) => {
element.style.opacity = '0';
element.style.transform = 'translateY(50px)';
element.style.transition = 'all 0.8s cubic-bezier(0.4, 0, 0.2, 1)';
});
const revealOnScroll = () => {
const windowHeight = window.innerHeight;
revealElements.forEach((element, index) => {
const elementTop = element.getBoundingClientRect().top;
const elementVisible = 100;
if (elementTop < windowHeight - elementVisible) {
setTimeout(() => {
element.style.opacity = '1';
element.style.transform = 'translateY(0)';
}, index * 50);
}
});
};
window.addEventListener('scroll', revealOnScroll);
revealOnScroll(); // Check on initial load
},
// Scroll-based animations
initScrollAnimations() {
let lastScrollY = window.scrollY;
let ticking = false;
function updateScrollAnimations() {
const scrollY = window.scrollY;
const scrollDirection = scrollY > lastScrollY ? 'down' : 'up';
// Hero parallax
const hero = document.querySelector('.hero-content');
if (hero) {
hero.style.transform = `translateY(${scrollY * 0.5}px)`;
hero.style.opacity = 1 - (scrollY / 800);
}
// Video parallax
const heroVideos = document.querySelector('.hero-video-container');
if (heroVideos) {
heroVideos.style.transform = `translateY(${scrollY * 0.3}px) scale(${1 + scrollY * 0.0003})`;
}
lastScrollY = scrollY;
ticking = false;
}
function requestTick() {
if (!ticking) {
window.requestAnimationFrame(updateScrollAnimations);
ticking = true;
}
}
window.addEventListener('scroll', requestTick);
},
// Enhanced navbar effects
initNavbarEffects() {
const navbar = document.querySelector('.navbar');
let lastScrollY = window.scrollY;
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
if (scrollY > 50) {
navbar.classList.add('scrolled');
} else {
navbar.classList.remove('scrolled');
}
// Keep navbar always visible
navbar.style.transform = 'translateY(0)';
lastScrollY = scrollY;
});
}
};
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => EnhancedAnimations.init());
} else {
EnhancedAnimations.init();
}