development 31-10-2025
This commit is contained in:
parent
7cf3558ba7
commit
fa2ebd457d
47 changed files with 2980 additions and 452 deletions
|
|
@ -1 +1,162 @@
|
|||
// App JS ohne Alpine-Initialisierung. Alpine wird von Livewire verwaltet.
|
||||
// Premium Scroll Animations with Intersection Observer
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Warte bis DOM vollständig geladen ist
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initAnimations);
|
||||
} else {
|
||||
initAnimations();
|
||||
}
|
||||
|
||||
function initAnimations() {
|
||||
// Intersection Observer Konfiguration
|
||||
const observerOptions = {
|
||||
threshold: 0.15,
|
||||
rootMargin: '0px 0px -80px 0px'
|
||||
};
|
||||
|
||||
// Erstelle Observer
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
// Füge is-visible Klasse mit kleinem Delay hinzu für sanfteren Effekt
|
||||
setTimeout(() => {
|
||||
entry.target.classList.add('is-visible');
|
||||
}, 50);
|
||||
|
||||
// Observer beenden nach Animation für bessere Performance
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, observerOptions);
|
||||
|
||||
// Finde alle Elemente mit Animation-Klassen
|
||||
const animatedElements = document.querySelectorAll(
|
||||
'.scroll-animate, .fade-in, .slide-up, .slide-right, .slide-left, .scale-in'
|
||||
);
|
||||
|
||||
// Beobachte jedes Element
|
||||
animatedElements.forEach(el => {
|
||||
observer.observe(el);
|
||||
});
|
||||
|
||||
// Smooth Scroll für Anchor-Links
|
||||
document.addEventListener('click', function(e) {
|
||||
const target = e.target.closest('a[href^="#"]');
|
||||
if (target && target.hash) {
|
||||
const targetElement = document.querySelector(target.hash);
|
||||
|
||||
if (targetElement) {
|
||||
e.preventDefault();
|
||||
const headerOffset = 80;
|
||||
const elementPosition = targetElement.getBoundingClientRect().top;
|
||||
const offsetPosition = elementPosition + window.pageYOffset - headerOffset;
|
||||
|
||||
window.scrollTo({
|
||||
top: offsetPosition,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Scroll Progress Indicator
|
||||
initScrollProgress();
|
||||
|
||||
// Premium Sticky Header
|
||||
initStickyHeader();
|
||||
}
|
||||
|
||||
function initStickyHeader() {
|
||||
const header = document.getElementById('main-header');
|
||||
if (!header) return;
|
||||
|
||||
let lastScrollTop = 0;
|
||||
let scrollTimeout = null;
|
||||
|
||||
function handleHeaderScroll() {
|
||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
|
||||
// Add/Remove scrolled class for enhanced shadow
|
||||
if (scrollTop > 50) {
|
||||
header.classList.add('scrolled');
|
||||
} else {
|
||||
header.classList.remove('scrolled');
|
||||
}
|
||||
|
||||
// Optional: Hide header on scroll down, show on scroll up
|
||||
// Uncomment if you want auto-hide behavior
|
||||
/*
|
||||
if (scrollTop > lastScrollTop && scrollTop > 100) {
|
||||
// Scrolling down
|
||||
header.classList.add('hide');
|
||||
} else {
|
||||
// Scrolling up
|
||||
header.classList.remove('hide');
|
||||
}
|
||||
*/
|
||||
|
||||
lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
|
||||
}
|
||||
|
||||
// Listen to scroll with throttling
|
||||
let headerTicking = false;
|
||||
window.addEventListener('scroll', function() {
|
||||
if (!headerTicking) {
|
||||
window.requestAnimationFrame(function() {
|
||||
handleHeaderScroll();
|
||||
headerTicking = false;
|
||||
});
|
||||
headerTicking = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Initial check
|
||||
handleHeaderScroll();
|
||||
}
|
||||
|
||||
function initScrollProgress() {
|
||||
// Erstelle Progress Bar Element
|
||||
const progressBar = document.createElement('div');
|
||||
progressBar.className = 'scroll-progress-bar';
|
||||
document.body.appendChild(progressBar);
|
||||
|
||||
// Update Progress on Scroll
|
||||
function updateProgress() {
|
||||
const windowHeight = window.innerHeight;
|
||||
const documentHeight = document.documentElement.scrollHeight;
|
||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
|
||||
// Berechne Progress (0-100%)
|
||||
const scrollPercentage = (scrollTop / (documentHeight - windowHeight)) * 100;
|
||||
|
||||
// Update Bar Width
|
||||
progressBar.style.width = `${Math.min(scrollPercentage, 100)}%`;
|
||||
|
||||
// Optional: Show/Hide basierend auf Scroll-Position
|
||||
if (scrollTop > 100) {
|
||||
progressBar.classList.add('visible');
|
||||
} else {
|
||||
progressBar.classList.remove('visible');
|
||||
}
|
||||
}
|
||||
|
||||
// Listen to scroll events mit Throttling für Performance
|
||||
let ticking = false;
|
||||
window.addEventListener('scroll', function() {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(function() {
|
||||
updateProgress();
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Initial update
|
||||
updateProgress();
|
||||
}
|
||||
})();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue