panels
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
#import "modules/std.sx";
|
||||
#import "modules/math";
|
||||
|
||||
// --- Lerpable protocol (inline — static dispatch, no vtable) ---
|
||||
|
||||
Lerpable :: protocol #inline {
|
||||
lerp :: (b: Self, t: f32) -> Self;
|
||||
}
|
||||
|
||||
// --- Easing Functions ---
|
||||
|
||||
ease_linear :: (t: f32) -> f32 { t; }
|
||||
@@ -106,3 +112,56 @@ SpringFloat :: struct {
|
||||
and abs(self.velocity) < self.threshold;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Animated(T) — generic duration-based animation for any Lerpable type ---
|
||||
|
||||
Animated :: struct ($T: Lerpable) {
|
||||
current: T;
|
||||
from: T;
|
||||
to: T;
|
||||
elapsed: f32;
|
||||
duration: f32;
|
||||
active: bool;
|
||||
|
||||
make :: (value: T) -> Animated(T) {
|
||||
Animated(T).{
|
||||
current = value,
|
||||
from = value,
|
||||
to = value,
|
||||
elapsed = 0.0,
|
||||
duration = 0.0,
|
||||
active = false
|
||||
};
|
||||
}
|
||||
|
||||
// Jump immediately to value (no animation). Used to avoid animating from zero on first layout.
|
||||
set_immediate :: (self: *Animated(T), value: T) {
|
||||
self.current = value;
|
||||
self.from = value;
|
||||
self.to = value;
|
||||
self.elapsed = 0.0;
|
||||
self.active = false;
|
||||
}
|
||||
|
||||
// Start animating towards target.
|
||||
animate_to :: (self: *Animated(T), target: T, dur: f32) {
|
||||
self.from = self.current;
|
||||
self.to = target;
|
||||
self.elapsed = 0.0;
|
||||
self.duration = dur;
|
||||
self.active = true;
|
||||
}
|
||||
|
||||
tick :: (self: *Animated(T), dt: f32) {
|
||||
if !self.active { return; }
|
||||
self.elapsed += dt;
|
||||
t := clamp(self.elapsed / self.duration, 0.0, 1.0);
|
||||
self.current = self.from.lerp(self.to, t);
|
||||
if t >= 1.0 {
|
||||
self.current = self.to;
|
||||
self.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
is_animating :: (self: *Animated(T)) -> bool { self.active; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user