- Remove trust-indicators JavaScript animations from animations-enhanced.js - Clean up translation keys for removed indicator elements - Remove selector references from config.js - Fix missing video reference (hero-tech-pattern.mp4) - Remove massive unused CSS sections: timeline, digital-beat, neural network viz - Reduce animations.css from 2669 to 272 lines (90% size reduction) This removes code that was referencing non-existent HTML elements and large unused visual effects from previous design iterations. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
253 Zeilen
8.4 KiB
JavaScript
253 Zeilen
8.4 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.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;
|
|
},
|
|
|
|
|
|
// 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();
|
|
} |