fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
302
resources/js/modules/animation-system/AnimationSystem.js
Normal file
302
resources/js/modules/animation-system/AnimationSystem.js
Normal file
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
* Unified Animation System
|
||||
*
|
||||
* Consolidates all scroll animation modules into a single, unified system.
|
||||
* Replaces: scrollfx, parallax, scroll-timeline, scroll-loop, scroll-dependent, sticky-fade, sticky-steps
|
||||
*/
|
||||
|
||||
import { Logger } from '../../core/logger.js';
|
||||
import { ScrollAnimation } from './ScrollAnimation.js';
|
||||
import { TimelineAnimation } from './TimelineAnimation.js';
|
||||
|
||||
/**
|
||||
* AnimationSystem - Unified animation system
|
||||
*/
|
||||
export class AnimationSystem {
|
||||
constructor(config = {}) {
|
||||
this.config = {
|
||||
enabled: config.enabled ?? true,
|
||||
useIntersectionObserver: config.useIntersectionObserver ?? true,
|
||||
throttleDelay: config.throttleDelay || 16, // ~60fps
|
||||
...config
|
||||
};
|
||||
|
||||
this.animations = new Map(); // Map<element, Animation>
|
||||
this.observers = new Map(); // Map<element, IntersectionObserver>
|
||||
this.scrollHandler = null;
|
||||
this.isScrolling = false;
|
||||
|
||||
// Initialize
|
||||
if (this.config.enabled) {
|
||||
this.init();
|
||||
}
|
||||
|
||||
Logger.info('[AnimationSystem] Initialized', {
|
||||
enabled: this.config.enabled,
|
||||
useIntersectionObserver: this.config.useIntersectionObserver
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AnimationSystem instance
|
||||
*/
|
||||
static create(config = {}) {
|
||||
return new AnimationSystem(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize animation system
|
||||
*/
|
||||
init() {
|
||||
// Set up scroll handler
|
||||
if (!this.config.useIntersectionObserver) {
|
||||
this.setupScrollHandler();
|
||||
}
|
||||
|
||||
// Auto-initialize elements with data attributes
|
||||
this.autoInitialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up scroll handler
|
||||
*/
|
||||
setupScrollHandler() {
|
||||
let ticking = false;
|
||||
|
||||
this.scrollHandler = () => {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(() => {
|
||||
this.updateAnimations();
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', this.scrollHandler, { passive: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-initialize elements with data attributes
|
||||
*/
|
||||
autoInitialize() {
|
||||
// Fade in on scroll (scrollfx)
|
||||
this.initializeFadeIn();
|
||||
|
||||
// Parallax
|
||||
this.initializeParallax();
|
||||
|
||||
// Scroll timeline
|
||||
this.initializeTimeline();
|
||||
|
||||
// Sticky fade
|
||||
this.initializeStickyFade();
|
||||
|
||||
// Sticky steps
|
||||
this.initializeStickySteps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize fade-in animations (scrollfx)
|
||||
*/
|
||||
initializeFadeIn() {
|
||||
const elements = document.querySelectorAll('.fade-in-on-scroll, .zoom-in, [data-animate="fade-in"]');
|
||||
elements.forEach(element => {
|
||||
this.registerAnimation(element, {
|
||||
type: 'fade-in',
|
||||
offset: parseFloat(element.dataset.offset) || 0.85,
|
||||
delay: parseFloat(element.dataset.delay) || 0,
|
||||
once: element.dataset.once !== 'false'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize parallax animations
|
||||
*/
|
||||
initializeParallax() {
|
||||
const elements = document.querySelectorAll('[data-parallax], .parallax');
|
||||
elements.forEach(element => {
|
||||
const speed = parseFloat(element.dataset.parallax || element.dataset.speed) || 0.5;
|
||||
this.registerAnimation(element, {
|
||||
type: 'parallax',
|
||||
speed
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize timeline animations (scroll-timeline)
|
||||
*/
|
||||
initializeTimeline() {
|
||||
const elements = document.querySelectorAll('[data-scroll-timeline], [data-scroll-step]');
|
||||
elements.forEach(element => {
|
||||
this.registerAnimation(element, {
|
||||
type: 'timeline',
|
||||
steps: element.dataset.scrollSteps ? parseInt(element.dataset.scrollSteps) : null,
|
||||
triggerPoint: parseFloat(element.dataset.triggerPoint) || 0.4
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize sticky fade animations
|
||||
*/
|
||||
initializeStickyFade() {
|
||||
const elements = document.querySelectorAll('[data-sticky-fade], .sticky-fade');
|
||||
elements.forEach(element => {
|
||||
this.registerAnimation(element, {
|
||||
type: 'sticky-fade',
|
||||
fadeStart: parseFloat(element.dataset.fadeStart) || 0,
|
||||
fadeEnd: parseFloat(element.dataset.fadeEnd) || 1
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize sticky steps animations
|
||||
*/
|
||||
initializeStickySteps() {
|
||||
const elements = document.querySelectorAll('[data-sticky-steps], .sticky-steps');
|
||||
elements.forEach(element => {
|
||||
const steps = element.dataset.stickySteps ? parseInt(element.dataset.stickySteps) : 3;
|
||||
this.registerAnimation(element, {
|
||||
type: 'sticky-steps',
|
||||
steps
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an animation
|
||||
*/
|
||||
registerAnimation(element, config) {
|
||||
if (this.animations.has(element)) {
|
||||
Logger.warn('[AnimationSystem] Animation already registered for element', element);
|
||||
return;
|
||||
}
|
||||
|
||||
let animation;
|
||||
|
||||
switch (config.type) {
|
||||
case 'fade-in':
|
||||
case 'zoom-in':
|
||||
animation = new ScrollAnimation(element, {
|
||||
type: config.type,
|
||||
offset: config.offset || 0.85,
|
||||
delay: config.delay || 0,
|
||||
once: config.once !== false
|
||||
});
|
||||
break;
|
||||
|
||||
case 'parallax':
|
||||
animation = new ScrollAnimation(element, {
|
||||
type: 'parallax',
|
||||
speed: config.speed || 0.5
|
||||
});
|
||||
break;
|
||||
|
||||
case 'timeline':
|
||||
animation = new TimelineAnimation(element, {
|
||||
steps: config.steps,
|
||||
triggerPoint: config.triggerPoint || 0.4
|
||||
});
|
||||
break;
|
||||
|
||||
case 'sticky-fade':
|
||||
animation = new ScrollAnimation(element, {
|
||||
type: 'sticky-fade',
|
||||
fadeStart: config.fadeStart || 0,
|
||||
fadeEnd: config.fadeEnd || 1
|
||||
});
|
||||
break;
|
||||
|
||||
case 'sticky-steps':
|
||||
animation = new ScrollAnimation(element, {
|
||||
type: 'sticky-steps',
|
||||
steps: config.steps || 3
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
Logger.warn('[AnimationSystem] Unknown animation type', config.type);
|
||||
return;
|
||||
}
|
||||
|
||||
this.animations.set(element, animation);
|
||||
|
||||
// Set up observer if using IntersectionObserver
|
||||
if (this.config.useIntersectionObserver) {
|
||||
this.setupObserver(element, animation);
|
||||
}
|
||||
|
||||
Logger.debug('[AnimationSystem] Animation registered', { element, type: config.type });
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up IntersectionObserver for element
|
||||
*/
|
||||
setupObserver(element, animation) {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
animation.enter();
|
||||
} else if (!animation.config.once) {
|
||||
animation.exit();
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: animation.config.offset || 0.85,
|
||||
rootMargin: '0px'
|
||||
});
|
||||
|
||||
observer.observe(element);
|
||||
this.observers.set(element, observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all animations (for scroll-based updates)
|
||||
*/
|
||||
updateAnimations() {
|
||||
this.animations.forEach((animation, element) => {
|
||||
if (animation.needsUpdate) {
|
||||
animation.update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove animation
|
||||
*/
|
||||
removeAnimation(element) {
|
||||
const animation = this.animations.get(element);
|
||||
if (animation) {
|
||||
animation.destroy();
|
||||
this.animations.delete(element);
|
||||
}
|
||||
|
||||
const observer = this.observers.get(element);
|
||||
if (observer) {
|
||||
observer.disconnect();
|
||||
this.observers.delete(element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy animation system
|
||||
*/
|
||||
destroy() {
|
||||
// Remove all animations
|
||||
this.animations.forEach((animation, element) => {
|
||||
this.removeAnimation(element);
|
||||
});
|
||||
|
||||
// Remove scroll handler
|
||||
if (this.scrollHandler) {
|
||||
window.removeEventListener('scroll', this.scrollHandler);
|
||||
}
|
||||
|
||||
Logger.info('[AnimationSystem] Destroyed');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user