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)]
|
#[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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue