Files
piglet/src/animation/timeline.rs
Sebastian Krüger b1ad87fc26 Complete piglet implementation with animations and effects
- Implement complete animation system with 20+ motion effects
- Add 18+ easing functions (quad, cubic, elastic, back, bounce)
- Implement color system with palette and gradient support
- Add parser for durations, colors, and CSS gradients
- Create comprehensive test suite (14 tests passing)
- Add linting and formatting with clippy/rustfmt
- Support for figlet integration with custom fonts
- Terminal rendering with crossterm
- Fix all clippy warnings and lint issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 03:00:20 +01:00

124 lines
2.6 KiB
Rust

use std::time::{Duration, Instant};
pub struct Timeline {
duration_ms: u64,
fps: u32,
start_time: Option<Instant>,
current_frame: usize,
total_frames: usize,
}
impl Timeline {
pub fn new(duration_ms: u64, fps: u32) -> Self {
let total_frames = ((duration_ms as f64 / 1000.0) * fps as f64).ceil() as usize;
Self {
duration_ms,
fps,
start_time: None,
current_frame: 0,
total_frames,
}
}
pub fn start(&mut self) {
self.start_time = Some(Instant::now());
self.current_frame = 0;
}
#[allow(dead_code)]
pub fn reset(&mut self) {
self.start_time = None;
self.current_frame = 0;
}
pub fn is_complete(&self) -> bool {
self.current_frame >= self.total_frames
}
pub fn progress(&self) -> f64 {
if self.total_frames == 0 {
return 1.0;
}
(self.current_frame as f64 / self.total_frames as f64).min(1.0)
}
pub fn next_frame(&mut self) -> bool {
if self.is_complete() {
return false;
}
self.current_frame += 1;
true
}
pub fn frame_duration(&self) -> Duration {
Duration::from_millis(1000 / self.fps as u64)
}
#[allow(dead_code)]
pub fn elapsed(&self) -> Duration {
self.start_time
.map(|start| start.elapsed())
.unwrap_or(Duration::ZERO)
}
#[allow(dead_code)]
pub fn current_frame(&self) -> usize {
self.current_frame
}
#[allow(dead_code)]
pub fn total_frames(&self) -> usize {
self.total_frames
}
pub fn fps(&self) -> u32 {
self.fps
}
pub fn duration_ms(&self) -> u64 {
self.duration_ms
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_timeline_creation() {
let timeline = Timeline::new(1000, 30);
assert_eq!(timeline.total_frames(), 30);
assert_eq!(timeline.fps(), 30);
}
#[test]
fn test_timeline_progress() {
let mut timeline = Timeline::new(1000, 10);
timeline.start();
assert_eq!(timeline.progress(), 0.0);
for _ in 0..5 {
timeline.next_frame();
}
assert_eq!(timeline.progress(), 0.5);
}
#[test]
fn test_timeline_completion() {
let mut timeline = Timeline::new(1000, 10);
timeline.start();
assert!(!timeline.is_complete());
for _ in 0..10 {
timeline.next_frame();
}
assert!(timeline.is_complete());
}
}