diff options
Diffstat (limited to 'src/animation.zig')
| -rw-r--r-- | src/animation.zig | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/animation.zig b/src/animation.zig index 855fef03..713a8a30 100644 --- a/src/animation.zig +++ b/src/animation.zig @@ -1132,6 +1132,9 @@ pub fn Fade(comptime Value: type) type { to: Value, displayed: Value, step: u16 = transition_steps, + /// Set off from partway through another fade: it eases out (moving + /// at once) instead of in and out, so it never stalls (§7.2). + retargeted: bool = false, pub fn init(value: Value) Self { return .{ .from = value, .to = value, .displayed = value }; @@ -1142,19 +1145,25 @@ pub fn Fade(comptime Value: type) type { } pub fn retarget(a: *Self, target: Value) void { + a.retargeted = a.isActive(); a.from = a.displayed; a.to = target; a.step = if (std.meta.eql(a.from, target)) transition_steps else 0; if (a.step == transition_steps) a.displayed = target; } + /// A state change eases in and out (§8.1); a retargeted one out. + const resolution: u16 = 1000; + pub fn advance(a: *Self) void { if (!a.isActive()) return; a.step += 1; + const t = @as(f32, @floatFromInt(a.step)) / @as(f32, @floatFromInt(transition_steps)); + const eased = sample(if (a.retargeted) .out_cubic else .smooth, t); a.displayed = if (a.step == transition_steps) a.to else - Value.interpolate(a.from, a.to, a.step, transition_steps); + Value.interpolate(a.from, a.to, @intFromFloat(@round(eased * resolution)), resolution); } pub fn snap(a: *Self, value: Value) void { |
