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
586 lines
16 KiB
Markdown
586 lines
16 KiB
Markdown
# Animationssystem für Console-Modul
|
|
|
|
## Übersicht
|
|
|
|
Das Animationssystem bietet eine umfassende Lösung für Animationen im Console-Modul. Es unterstützt sowohl UI-Elemente in der TUI als auch Text-Animationen im Console-Output. Das System ist modular aufgebaut, erweiterbar und vollständig in den EventLoop integriert.
|
|
|
|
## Features
|
|
|
|
- **Mehrere Animationstypen**: Fade-In/Out, Slide, Typewriter, Marquee, Pulse
|
|
- **Keyframe-basierte Animationen**: Komplexe Animationen mit Easing-Functions
|
|
- **Composite Animationen**: Kombination mehrerer Animationen (parallel oder sequenziell)
|
|
- **EventLoop Integration**: Automatische Updates im Render-Loop
|
|
- **TUI & Console-Output**: Unterstützung für beide Anwendungsfälle
|
|
- **Factory & Builder Pattern**: Einfache Erstellung von Animationen
|
|
|
|
## Architektur
|
|
|
|
### Core-Komponenten
|
|
|
|
#### Animation Interface
|
|
|
|
Basis-Interface für alle Animationen:
|
|
|
|
```php
|
|
interface Animation
|
|
{
|
|
public function start(): void;
|
|
public function stop(): void;
|
|
public function pause(): void;
|
|
public function resume(): void;
|
|
public function update(float $deltaTime): bool;
|
|
public function isActive(): bool;
|
|
public function getProgress(): float;
|
|
public function getDuration(): float;
|
|
public function getDelay(): float;
|
|
public function isLooping(): bool;
|
|
public function onStart(callable $callback): self;
|
|
public function onComplete(callable $callback): self;
|
|
public function onPause(callable $callback): self;
|
|
public function onResume(callable $callback): self;
|
|
}
|
|
```
|
|
|
|
#### AnimationManager
|
|
|
|
Verwaltet mehrere Animationen gleichzeitig und aktualisiert sie automatisch:
|
|
|
|
```php
|
|
$animationManager = new AnimationManager();
|
|
|
|
// Animation hinzufügen
|
|
$animationManager->add($animation);
|
|
|
|
// Animationen aktualisieren (wird automatisch vom EventLoop aufgerufen)
|
|
$animationManager->update($deltaTime);
|
|
|
|
// Animation entfernen
|
|
$animationManager->remove($animation);
|
|
|
|
// Alle Animationen löschen
|
|
$animationManager->clear();
|
|
```
|
|
|
|
#### Easing Functions
|
|
|
|
Unterstützte Easing-Functions:
|
|
|
|
- `LINEAR` - Lineare Interpolation
|
|
- `EASE_IN` - Langsam starten
|
|
- `EASE_OUT` - Langsam enden
|
|
- `EASE_IN_OUT` - Langsam starten und enden
|
|
- `EASE_IN_QUAD` - Quadratische Beschleunigung
|
|
- `EASE_OUT_QUAD` - Quadratische Verzögerung
|
|
- `EASE_IN_OUT_QUAD` - Quadratische Beschleunigung und Verzögerung
|
|
- `BOUNCE` - Bounce-Effekt
|
|
- `ELASTIC` - Elastischer Effekt
|
|
|
|
## Animation-Typen
|
|
|
|
### FadeAnimation
|
|
|
|
Fade-In/Out Effekte für Text oder UI-Elemente:
|
|
|
|
```php
|
|
use App\Framework\Console\Animation\AnimationFactory;
|
|
use App\Framework\Console\Animation\EasingFunction;
|
|
|
|
// Fade-In
|
|
$fadeIn = AnimationFactory::fadeIn(1.0, EasingFunction::EASE_IN);
|
|
|
|
// Fade-Out
|
|
$fadeOut = AnimationFactory::fadeOut(1.0, EasingFunction::EASE_OUT);
|
|
|
|
// Custom Fade
|
|
$fade = AnimationFactory::fade(
|
|
duration: 2.0,
|
|
startOpacity: 0.0,
|
|
endOpacity: 1.0,
|
|
easing: EasingFunction::EASE_IN_OUT
|
|
);
|
|
```
|
|
|
|
### SlideAnimation
|
|
|
|
Slide-Effekte in verschiedene Richtungen:
|
|
|
|
```php
|
|
use App\Framework\Console\Animation\Types\SlideDirection;
|
|
|
|
// Von links
|
|
$slideFromLeft = AnimationFactory::slideInFromLeft(
|
|
distance: 20,
|
|
duration: 1.0
|
|
);
|
|
|
|
// Von rechts
|
|
$slideFromRight = AnimationFactory::slideInFromRight(
|
|
distance: 20,
|
|
duration: 1.0
|
|
);
|
|
|
|
// Custom Slide
|
|
$slide = AnimationFactory::slide(
|
|
direction: SlideDirection::UP,
|
|
distance: 10,
|
|
duration: 0.5,
|
|
easing: EasingFunction::EASE_OUT
|
|
);
|
|
```
|
|
|
|
### TypewriterAnimation
|
|
|
|
Typewriter-Effekt für Text:
|
|
|
|
```php
|
|
$typewriter = AnimationFactory::typewriter(
|
|
text: 'Hello, this is a typewriter animation!',
|
|
charactersPerSecond: 10.0
|
|
);
|
|
|
|
// Schnell
|
|
$fast = AnimationFactory::typewriter('Fast text', 20.0);
|
|
|
|
// Langsam
|
|
$slow = AnimationFactory::typewriter('Slow text', 5.0);
|
|
```
|
|
|
|
### MarqueeAnimation
|
|
|
|
Scrolling Text (Marquee):
|
|
|
|
```php
|
|
$marquee = AnimationFactory::marquee(
|
|
text: 'This is a scrolling marquee text',
|
|
width: 80,
|
|
speed: 1.0,
|
|
loop: true
|
|
);
|
|
|
|
// Schnell
|
|
$fastMarquee = AnimationFactory::marquee('Fast scrolling', 50, 5.0);
|
|
|
|
// Langsam
|
|
$slowMarquee = AnimationFactory::marquee('Slow scrolling', 50, 0.5);
|
|
```
|
|
|
|
### PulseAnimation
|
|
|
|
Pulsing-Effekte für Hervorhebungen:
|
|
|
|
```php
|
|
$pulse = AnimationFactory::pulse(
|
|
duration: 1.0,
|
|
scaleStart: 1.0,
|
|
scaleEnd: 1.2,
|
|
pulseSpeed: 2.0
|
|
);
|
|
|
|
// Sanft
|
|
$gentle = PulseAnimation::gentle(2.0);
|
|
|
|
// Stark
|
|
$strong = PulseAnimation::strong(1.0);
|
|
```
|
|
|
|
### KeyframeAnimation
|
|
|
|
Keyframe-basierte Animationen mit komplexen Interpolationen:
|
|
|
|
```php
|
|
use App\Framework\Console\Animation\AnimationFrame;
|
|
|
|
$keyframes = [
|
|
new AnimationFrame(0.0, 0, EasingFunction::EASE_IN),
|
|
new AnimationFrame(0.5, 100, EasingFunction::EASE_IN_OUT),
|
|
new AnimationFrame(1.0, 200, EasingFunction::EASE_OUT),
|
|
];
|
|
|
|
$keyframeAnimation = AnimationFactory::keyframe(
|
|
keyframes: $keyframes,
|
|
duration: 2.0,
|
|
loop: false
|
|
);
|
|
```
|
|
|
|
### CompositeAnimation
|
|
|
|
Kombination mehrerer Animationen:
|
|
|
|
```php
|
|
use App\Framework\Console\Animation\CompositeAnimation;
|
|
use App\Framework\Console\Animation\SequenceType;
|
|
|
|
$fadeIn = AnimationFactory::fadeIn(0.5);
|
|
$slide = AnimationFactory::slideInFromLeft(20, 0.5);
|
|
|
|
// Parallel (gleichzeitig)
|
|
$parallel = new CompositeAnimation(
|
|
animations: [$fadeIn, $slide],
|
|
sequenceType: SequenceType::PARALLEL,
|
|
loop: false
|
|
);
|
|
|
|
// Sequenziell (nacheinander)
|
|
$sequential = new CompositeAnimation(
|
|
animations: [$fadeIn, $slide],
|
|
sequenceType: SequenceType::SEQUENTIAL,
|
|
loop: false
|
|
);
|
|
```
|
|
|
|
### SpinnerAnimation
|
|
|
|
Animation-basierter Spinner:
|
|
|
|
```php
|
|
use App\Framework\Console\Animation\Types\SpinnerAnimation;
|
|
use App\Framework\Console\SpinnerStyle;
|
|
|
|
$spinner = AnimationFactory::spinner(
|
|
frames: SpinnerStyle::DOTS,
|
|
message: 'Loading...',
|
|
frameInterval: 0.1
|
|
);
|
|
|
|
// Oder direkt
|
|
$spinner = SpinnerAnimation::fromStyle(
|
|
style: SpinnerStyle::BARS,
|
|
message: 'Processing...',
|
|
frameInterval: 0.1
|
|
);
|
|
```
|
|
|
|
## Verwendung in Console-Output
|
|
|
|
### Einfache Text-Animationen
|
|
|
|
```php
|
|
use App\Framework\Console\ConsoleOutput;
|
|
|
|
$output = new ConsoleOutput();
|
|
|
|
// Fade-In
|
|
$output->animateFadeIn('Hello World!', 1.0);
|
|
|
|
// Fade-Out
|
|
$output->animateFadeOut('Goodbye!', 1.0);
|
|
|
|
// Typewriter
|
|
$output->animateTypewriter('This appears character by character', 10.0);
|
|
|
|
// Marquee
|
|
$output->animateMarquee('Scrolling text', 80, 1.0);
|
|
|
|
// Custom Animation
|
|
$customAnimation = AnimationFactory::fadeIn(2.0);
|
|
$output->animateText('Custom animated text', $customAnimation);
|
|
|
|
// Animationen aktualisieren
|
|
$output->updateAnimations(0.016); // ~60 FPS
|
|
```
|
|
|
|
### Animation Manager Zugriff
|
|
|
|
```php
|
|
$animationManager = $output->getAnimationManager();
|
|
|
|
// Animationen direkt hinzufügen
|
|
$animationManager->add($animation);
|
|
|
|
// Animationen aktualisieren
|
|
$animationManager->update($deltaTime);
|
|
```
|
|
|
|
## Verwendung in TUI
|
|
|
|
### TuiAnimationRenderer
|
|
|
|
```php
|
|
use App\Framework\Console\Animation\TuiAnimationRenderer;
|
|
use App\Framework\Console\Animation\AnimationFactory;
|
|
use App\Framework\Console\Animation\Types\SlideDirection;
|
|
|
|
$animationRenderer = $tuiRenderer->getAnimationRenderer();
|
|
|
|
if ($animationRenderer !== null) {
|
|
// Element animieren
|
|
$animationRenderer->fadeInElement('menu-item-1', 0.5);
|
|
$animationRenderer->slideInElement(
|
|
'button-1',
|
|
SlideDirection::LEFT,
|
|
20,
|
|
0.5
|
|
);
|
|
$animationRenderer->pulseElement('highlight-1', 1.0);
|
|
|
|
// Custom Animation
|
|
$customAnimation = AnimationFactory::fadeIn(1.0);
|
|
$animationRenderer->animateElement('element-id', $customAnimation);
|
|
|
|
// Animation stoppen
|
|
$animationRenderer->stopElement('element-id');
|
|
|
|
// Animationswerte abrufen
|
|
$opacity = $animationRenderer->getElementOpacity('element-id');
|
|
$position = $animationRenderer->getElementPosition('element-id');
|
|
$scale = $animationRenderer->getElementScale('element-id');
|
|
}
|
|
```
|
|
|
|
### Integration in TuiRenderer
|
|
|
|
Der `TuiRenderer` aktualisiert Animationen automatisch im Render-Loop:
|
|
|
|
```php
|
|
// In TuiRenderer::render()
|
|
if ($this->animationRenderer !== null) {
|
|
$this->animationRenderer->update(0.016); // ~60 FPS
|
|
}
|
|
```
|
|
|
|
## Factory & Builder Pattern
|
|
|
|
### AnimationFactory
|
|
|
|
Einfache Erstellung von Animationen:
|
|
|
|
```php
|
|
use App\Framework\Console\Animation\AnimationFactory;
|
|
|
|
$fadeIn = AnimationFactory::fadeIn(1.0);
|
|
$fadeOut = AnimationFactory::fadeOut(1.0);
|
|
$slide = AnimationFactory::slideInFromLeft(20, 1.0);
|
|
$typewriter = AnimationFactory::typewriter('Text', 10.0);
|
|
$marquee = AnimationFactory::marquee('Text', 80, 1.0);
|
|
$pulse = AnimationFactory::pulse(1.0);
|
|
$spinner = AnimationFactory::spinner(SpinnerStyle::DOTS, 'Loading...');
|
|
$keyframe = AnimationFactory::keyframe($keyframes, 2.0);
|
|
```
|
|
|
|
### AnimationBuilder
|
|
|
|
Fluent Builder für komplexe Konfigurationen:
|
|
|
|
```php
|
|
use App\Framework\Console\Animation\AnimationBuilder;
|
|
|
|
$animation = AnimationBuilder::fade(0.0, 1.0)
|
|
->duration(2.0)
|
|
->delay(0.5)
|
|
->loop(false)
|
|
->easing(EasingFunction::EASE_IN_OUT)
|
|
->onStart(function ($anim) {
|
|
echo "Animation started\n";
|
|
})
|
|
->onComplete(function ($anim) {
|
|
echo "Animation completed\n";
|
|
})
|
|
->onPause(function ($anim) {
|
|
echo "Animation paused\n";
|
|
})
|
|
->onResume(function ($anim) {
|
|
echo "Animation resumed\n";
|
|
})
|
|
->build();
|
|
```
|
|
|
|
## EventLoop Integration
|
|
|
|
Der `EventLoop` kann automatisch Animationen aktualisieren:
|
|
|
|
```php
|
|
use App\Framework\Console\Components\EventLoop\EventLoop;
|
|
use App\Framework\Console\Components\EventLoop\EventLoopConfig;
|
|
use App\Framework\Console\Animation\AnimationManager;
|
|
|
|
$animationManager = new AnimationManager();
|
|
$eventBuffer = new EventBuffer();
|
|
$config = new EventLoopConfig();
|
|
|
|
// EventLoop mit AnimationManager erstellen
|
|
$eventLoop = new EventLoop($eventBuffer, $config, $animationManager);
|
|
|
|
// Animationen werden automatisch aktualisiert
|
|
// Oder manuell:
|
|
$eventLoop->updateAnimations(0.016);
|
|
```
|
|
|
|
## Callbacks
|
|
|
|
Animationen unterstützen Callbacks für verschiedene Events:
|
|
|
|
```php
|
|
$animation = AnimationFactory::fadeIn(1.0)
|
|
->onStart(function (Animation $anim) {
|
|
echo "Animation started\n";
|
|
})
|
|
->onComplete(function (Animation $anim) {
|
|
echo "Animation completed\n";
|
|
})
|
|
->onPause(function (Animation $anim) {
|
|
echo "Animation paused\n";
|
|
})
|
|
->onResume(function (Animation $anim) {
|
|
echo "Animation resumed\n";
|
|
});
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### Performance
|
|
|
|
1. **Animation Manager wiederverwenden**: Erstellen Sie einen `AnimationManager` pro Anwendung und verwenden Sie ihn für alle Animationen.
|
|
|
|
2. **Animationen entfernen**: Entfernen Sie abgeschlossene Animationen, um Speicher zu sparen:
|
|
```php
|
|
$animation->onComplete(function ($anim) use ($manager) {
|
|
$manager->remove($anim);
|
|
});
|
|
```
|
|
|
|
3. **Update-Frequenz**: Aktualisieren Sie Animationen mit ~60 FPS (0.016 Sekunden):
|
|
```php
|
|
$animationManager->update(0.016);
|
|
```
|
|
|
|
### Code-Organisation
|
|
|
|
1. **Factory verwenden**: Verwenden Sie `AnimationFactory` für einfache Animationen statt direkte Instanziierung.
|
|
|
|
2. **Builder für komplexe Animationen**: Verwenden Sie `AnimationBuilder` für komplexe Konfigurationen.
|
|
|
|
3. **Keyframes für komplexe Animationen**: Verwenden Sie `KeyframeAnimation` für komplexe Animationen mit mehreren Zuständen.
|
|
|
|
### Fehlerbehandlung
|
|
|
|
```php
|
|
try {
|
|
$animation = AnimationFactory::fadeIn(1.0);
|
|
$animationManager->add($animation);
|
|
$animation->start();
|
|
} catch (\InvalidArgumentException $e) {
|
|
// Handle invalid animation parameters
|
|
error_log("Animation error: " . $e->getMessage());
|
|
}
|
|
```
|
|
|
|
## Beispiel: Demo Command
|
|
|
|
Ein vollständiges Beispiel finden Sie in:
|
|
|
|
`src/Framework/Console/Examples/AnimationDemoCommand.php`
|
|
|
|
Ausführen mit:
|
|
|
|
```bash
|
|
php console.php demo:animation
|
|
```
|
|
|
|
## Erweiterung
|
|
|
|
### Neue Animation-Typen hinzufügen
|
|
|
|
1. Erstellen Sie eine neue Klasse in `src/Framework/Console/Animation/Types/`
|
|
2. Implementieren Sie das `Animation` Interface oder erweitern Sie `BaseAnimation`
|
|
3. Implementieren Sie `updateAnimation(float $progress)` und `getCurrentValue()`
|
|
4. Fügen Sie Factory-Methoden zu `AnimationFactory` hinzu
|
|
|
|
Beispiel:
|
|
|
|
```php
|
|
final class CustomAnimation extends BaseAnimation
|
|
{
|
|
protected function updateAnimation(float $progress): void
|
|
{
|
|
// Custom animation logic
|
|
}
|
|
|
|
public function getCurrentValue(): mixed
|
|
{
|
|
// Return current animated value
|
|
}
|
|
}
|
|
```
|
|
|
|
## API-Referenz
|
|
|
|
### Animation Interface
|
|
|
|
- `start(): void` - Startet die Animation
|
|
- `stop(): void` - Stoppt die Animation
|
|
- `pause(): void` - Pausiert die Animation
|
|
- `resume(): void` - Setzt die Animation fort
|
|
- `update(float $deltaTime): bool` - Aktualisiert die Animation
|
|
- `isActive(): bool` - Prüft ob Animation aktiv ist
|
|
- `getProgress(): float` - Gibt Fortschritt zurück (0.0-1.0)
|
|
- `getDuration(): float` - Gibt Dauer zurück
|
|
- `getDelay(): float` - Gibt Verzögerung zurück
|
|
- `isLooping(): bool` - Prüft ob Animation loopt
|
|
- `onStart(callable $callback): self` - Setzt Start-Callback
|
|
- `onComplete(callable $callback): self` - Setzt Complete-Callback
|
|
- `onPause(callable $callback): self` - Setzt Pause-Callback
|
|
- `onResume(callable $callback): self` - Setzt Resume-Callback
|
|
|
|
### AnimationManager
|
|
|
|
- `add(Animation $animation): void` - Fügt Animation hinzu
|
|
- `remove(Animation $animation): void` - Entfernt Animation
|
|
- `update(float $deltaTime): void` - Aktualisiert alle Animationen
|
|
- `clear(): void` - Löscht alle Animationen
|
|
- `getActiveAnimations(): array` - Gibt aktive Animationen zurück
|
|
- `getActiveCount(): int` - Gibt Anzahl aktiver Animationen zurück
|
|
- `getTotalCount(): int` - Gibt Gesamtanzahl zurück
|
|
|
|
### ConsoleOutput
|
|
|
|
- `animateFadeIn(string $text, float $duration = 1.0): void`
|
|
- `animateFadeOut(string $text, float $duration = 1.0): void`
|
|
- `animateTypewriter(string $text, float $charactersPerSecond = 10.0): void`
|
|
- `animateMarquee(string $text, int $width = 80, float $speed = 1.0): void`
|
|
- `animateText(string $text, Animation $animation): void`
|
|
- `updateAnimations(float $deltaTime = 0.016): void`
|
|
- `getAnimationManager(): AnimationManager`
|
|
|
|
### TuiAnimationRenderer
|
|
|
|
- `animateElement(string $elementId, Animation $animation): void`
|
|
- `fadeInElement(string $elementId, float $duration = 0.5): void`
|
|
- `fadeOutElement(string $elementId, float $duration = 0.5): void`
|
|
- `pulseElement(string $elementId, float $duration = 1.0): void`
|
|
- `slideInElement(string $elementId, SlideDirection $direction, int $distance, float $duration = 0.5): void`
|
|
- `stopElement(string $elementId): void`
|
|
- `getElementOpacity(string $elementId): float`
|
|
- `getElementPosition(string $elementId): int`
|
|
- `getElementScale(string $elementId): float`
|
|
- `hasAnimation(string $elementId): bool`
|
|
- `update(float $deltaTime): void`
|
|
- `clear(): void`
|
|
|
|
## Troubleshooting
|
|
|
|
### Animationen laufen nicht
|
|
|
|
1. **AnimationManager prüfen**: Stellen Sie sicher, dass ein `AnimationManager` vorhanden ist.
|
|
2. **Update-Aufrufe**: Stellen Sie sicher, dass `update()` regelmäßig aufgerufen wird.
|
|
3. **Animation starten**: Rufen Sie `start()` auf der Animation auf.
|
|
|
|
### Performance-Probleme
|
|
|
|
1. **Zu viele Animationen**: Reduzieren Sie die Anzahl gleichzeitiger Animationen.
|
|
2. **Update-Frequenz**: Erhöhen Sie das Update-Intervall (z.B. 0.033 für 30 FPS).
|
|
3. **Abgeschlossene Animationen**: Entfernen Sie abgeschlossene Animationen.
|
|
|
|
### Animationen werden nicht angezeigt
|
|
|
|
1. **TUI-Integration**: Für TUI-Animationen muss `TuiAnimationRenderer` verwendet werden.
|
|
2. **Console-Output**: Für Text-Animationen muss `ConsoleOutput::animateText()` verwendet werden.
|
|
3. **Update-Loop**: Stellen Sie sicher, dass der Update-Loop läuft.
|
|
|
|
## Weitere Ressourcen
|
|
|
|
- **Plan-Dokument**: `console-modul-refactoring.plan.md`
|
|
- **Demo Command**: `src/Framework/Console/Examples/AnimationDemoCommand.php`
|
|
- **Framework Guidelines**: `docs/claude/guidelines.md`
|
|
|