Add new function to animate f32 values (#1039)

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
BctfN0HUK7Yg 2022-01-17 16:57:09 +03:00 committed by GitHub
parent d6b32b7956
commit 87ac7446da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 0 deletions

View file

@ -3,6 +3,7 @@ use crate::{emath::remap_clamp, Id, IdMap, InputState};
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub(crate) struct AnimationManager { pub(crate) struct AnimationManager {
bools: IdMap<BoolAnim>, bools: IdMap<BoolAnim>,
values: IdMap<ValueAnim>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -12,6 +13,14 @@ struct BoolAnim {
toggle_time: f64, toggle_time: f64,
} }
#[derive(Clone, Debug)]
struct ValueAnim {
from_value: f32,
to_value: f32,
/// when did `value` last toggle?
toggle_time: f64,
}
impl AnimationManager { impl AnimationManager {
/// See `Context::animate_bool` for documentation /// See `Context::animate_bool` for documentation
pub fn animate_bool( 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
}
}
}
} }

View file

@ -922,6 +922,24 @@ impl Context {
animated_value 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. /// Clear memory of any animations.
pub fn clear_animations(&self) { pub fn clear_animations(&self) {
self.write().animation_manager = Default::default(); self.write().animation_manager = Default::default();