Files
michaelschiemer/resources/js/modules/animation-system/TimelineAnimation.js
Michael Schiemer 36ef2a1e2c
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
fix: Gitea Traefik routing and connection pool optimization
- 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
2025-11-09 14:46:15 +01:00

158 lines
4.0 KiB
JavaScript

/**
* Timeline Animation
*
* Handles scroll timeline animations (scroll-timeline, scroll-loop)
*/
import { Logger } from '../../core/logger.js';
/**
* TimelineAnimation - Scroll timeline animation
*/
export class TimelineAnimation {
constructor(element, config = {}) {
this.element = element;
this.config = {
steps: config.steps || null,
triggerPoint: config.triggerPoint || 0.4,
loop: config.loop ?? false,
...config
};
this.currentStep = 0;
this.triggered = false;
// Initialize
this.init();
}
/**
* Initialize timeline animation
*/
init() {
// Set initial step
this.element.setAttribute('data-scroll-step', '0');
this.element.classList.add('scroll-timeline');
}
/**
* Enter animation
*/
enter() {
if (this.triggered && !this.config.loop) {
return;
}
this.triggered = true;
this.update();
}
/**
* Exit animation
*/
exit() {
if (this.config.loop) {
this.currentStep = 0;
this.update();
}
}
/**
* Update animation based on scroll position
*/
update() {
const rect = this.element.getBoundingClientRect();
const viewportHeight = window.innerHeight;
const triggerY = viewportHeight * this.config.triggerPoint;
if (rect.top < triggerY && rect.bottom > 0) {
// Calculate progress
const progress = Math.max(0, Math.min(1, (triggerY - rect.top) / (rect.height + viewportHeight)));
if (this.config.steps) {
// Step-based animation
const step = Math.floor(progress * this.config.steps);
this.setStep(step);
} else {
// Continuous animation
this.setProgress(progress);
}
}
}
/**
* Set step
*/
setStep(step) {
if (step === this.currentStep) {
return;
}
this.currentStep = step;
this.element.setAttribute('data-scroll-step', step.toString());
// Remove old step classes
for (let i = 0; i <= this.config.steps; i++) {
this.element.classList.remove(`step-${i}`);
}
// Add new step class
this.element.classList.add(`step-${step}`);
// Trigger event
this.triggerStepEvent(step);
}
/**
* Set progress (continuous)
*/
setProgress(progress) {
this.element.setAttribute('data-scroll-progress', progress.toString());
this.element.style.setProperty('--scroll-progress', progress.toString());
// Trigger event
this.triggerProgressEvent(progress);
}
/**
* Trigger step event
*/
triggerStepEvent(step) {
const event = new CustomEvent('scroll-timeline:step', {
detail: { step, element: this.element },
bubbles: true
});
this.element.dispatchEvent(event);
}
/**
* Trigger progress event
*/
triggerProgressEvent(progress) {
const event = new CustomEvent('scroll-timeline:progress', {
detail: { progress, element: this.element },
bubbles: true
});
this.element.dispatchEvent(event);
}
/**
* Destroy animation
*/
destroy() {
this.element.removeAttribute('data-scroll-step');
this.element.removeAttribute('data-scroll-progress');
this.element.style.removeProperty('--scroll-progress');
this.element.classList.remove('scroll-timeline');
// Remove step classes
for (let i = 0; i <= 10; i++) {
this.element.classList.remove(`step-${i}`);
}
this.currentStep = 0;
this.triggered = false;
}
}