Add new function to animate f32 values (#1039)
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
parent
d6b32b7956
commit
87ac7446da
2 changed files with 70 additions and 0 deletions
|
@ -3,6 +3,7 @@ use crate::{emath::remap_clamp, Id, IdMap, InputState};
|
|||
#[derive(Clone, Default)]
|
||||
pub(crate) struct AnimationManager {
|
||||
bools: IdMap<BoolAnim>,
|
||||
values: IdMap<ValueAnim>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -12,6 +13,14 @@ struct BoolAnim {
|
|||
toggle_time: f64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct ValueAnim {
|
||||
from_value: f32,
|
||||
to_value: f32,
|
||||
/// when did `value` last toggle?
|
||||
toggle_time: f64,
|
||||
}
|
||||
|
||||
impl AnimationManager {
|
||||
/// See `Context::animate_bool` for documentation
|
||||
pub fn animate_bool(
|
||||
|
@ -56,4 +65,47 @@ impl AnimationManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn animate_value(
|
||||
&mut self,
|
||||
input: &InputState,
|
||||
animation_time: f32,
|
||||
id: Id,
|
||||
value: f32,
|
||||
) -> f32 {
|
||||
match self.values.get_mut(&id) {
|
||||
None => {
|
||||
self.values.insert(
|
||||
id,
|
||||
ValueAnim {
|
||||
from_value: value,
|
||||
to_value: value,
|
||||
toggle_time: -f64::INFINITY, // long time ago
|
||||
},
|
||||
);
|
||||
value
|
||||
}
|
||||
Some(anim) => {
|
||||
let time_since_toggle = (input.time - anim.toggle_time) as f32;
|
||||
// On the frame we toggle we don't want to return the old value,
|
||||
// so we extrapolate forwards:
|
||||
let time_since_toggle = time_since_toggle + input.predicted_dt;
|
||||
let current_value = remap_clamp(
|
||||
time_since_toggle,
|
||||
0.0..=animation_time,
|
||||
anim.from_value..=anim.to_value,
|
||||
);
|
||||
if anim.to_value != value {
|
||||
anim.from_value = current_value; //start new animation from current position of playing animation
|
||||
anim.to_value = value;
|
||||
anim.toggle_time = input.time;
|
||||
}
|
||||
if animation_time == 0.0 {
|
||||
anim.from_value = value;
|
||||
anim.to_value = value;
|
||||
}
|
||||
current_value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -922,6 +922,24 @@ impl Context {
|
|||
animated_value
|
||||
}
|
||||
|
||||
/// Allows you to smoothly change the f32 value.
|
||||
/// At the first call the value is written to memory.
|
||||
/// When it is called with a new value, it linearly interpolates to it in the given time.
|
||||
pub fn animate_value_with_time(&self, id: Id, value: f32, animation_time: f32) -> f32 {
|
||||
let animated_value = {
|
||||
let ctx_impl = &mut *self.write();
|
||||
ctx_impl
|
||||
.animation_manager
|
||||
.animate_value(&ctx_impl.input, animation_time, id, value)
|
||||
};
|
||||
let animation_in_progress = animated_value != value;
|
||||
if animation_in_progress {
|
||||
self.request_repaint();
|
||||
}
|
||||
|
||||
animated_value
|
||||
}
|
||||
|
||||
/// Clear memory of any animations.
|
||||
pub fn clear_animations(&self) {
|
||||
self.write().animation_manager = Default::default();
|
||||
|
|
Loading…
Reference in a new issue