1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-31 05:40:03 -04:00

Quickly animate scroll when calling ui.scroll_to_cursor etc (#4119)

Uses ease-in-ease-out interpolation, with a time between 0.1s and 0.3s,
depending on the distance needed to scroll.


![smooth-scroll-to-target](https://github.com/emilk/egui/assets/1148717/c5c8556d-476b-4597-842b-aa0e5927fbb9)
This commit is contained in:
Emil Ernerfeldt
2024-03-04 20:00:13 +01:00
committed by GitHub
parent e29022efc4
commit 18eeb01f57
6 changed files with 141 additions and 22 deletions

View File

@@ -383,6 +383,52 @@ pub fn exponential_smooth_factor(
1.0 - (1.0 - reach_this_fraction).powf(dt / in_this_many_seconds)
}
/// If you have a value animating over time,
/// how much towards its target do you need to move it this frame?
///
/// You only need to store the start time and target value in order to animate using this function.
///
/// ``` rs
/// struct Animation {
/// current_value: f32,
///
/// animation_time_span: (f64, f64),
/// target_value: f32,
/// }
///
/// impl Animation {
/// fn update(&mut self, now: f64, dt: f32) {
/// let t = interpolation_factor(self.animation_time_span, now, dt, ease_in_ease_out);
/// self.current_value = emath::lerp(self.current_value..=self.target_value, t);
/// }
/// }
/// ```
pub fn interpolation_factor(
(start_time, end_time): (f64, f64),
current_time: f64,
dt: f32,
easing: impl Fn(f32) -> f32,
) -> f32 {
let animation_duration = (end_time - start_time) as f32;
let prev_time = current_time - dt as f64;
let prev_t = easing((prev_time - start_time) as f32 / animation_duration);
let end_t = easing((current_time - start_time) as f32 / animation_duration);
if end_t < 1.0 {
(end_t - prev_t) / (1.0 - prev_t)
} else {
1.0
}
}
/// Ease in, ease out.
///
/// `f(0) = 0, f'(0) = 0, f(1) = 1, f'(1) = 0`.
#[inline]
pub fn ease_in_ease_out(t: f32) -> f32 {
let t = t.clamp(0.0, 1.0);
(3.0 * t * t - 2.0 * t * t * t).clamp(0.0, 1.0)
}
// ----------------------------------------------------------------------------
/// An assert that is only active when `emath` is compiled with the `extra_asserts` feature