diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index ab7da8aff..3b3925c9d 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -621,20 +621,28 @@ impl ScrollArea { .interact_rect .map(|rect| ui.interact(rect, id.with("area"), Sense::drag())); - if content_response_option.map(|response| response.dragged()) == Some(true) { + if content_response_option + .as_ref() + .is_some_and(|response| response.dragged()) + { for d in 0..2 { if scroll_enabled[d] { ui.input(|input| { state.offset[d] -= input.pointer.delta()[d]; - state.vel[d] = input.pointer.velocity()[d]; }); state.scroll_stuck_to_end[d] = false; state.offset_target[d] = None; - } else { - state.vel[d] = 0.0; } } } else { + // Apply the cursor velocity to the scroll area when the user releases the drag. + if content_response_option + .as_ref() + .is_some_and(|response| response.drag_stopped()) + { + state.vel = + scroll_enabled.to_vec2() * ui.input(|input| input.pointer.velocity()); + } for d in 0..2 { // Kinetic scrolling let stop_speed = 20.0; // Pixels per second. diff --git a/crates/emath/src/vec2b.rs b/crates/emath/src/vec2b.rs index f241de64e..673f2959e 100644 --- a/crates/emath/src/vec2b.rs +++ b/crates/emath/src/vec2b.rs @@ -1,3 +1,5 @@ +use crate::Vec2; + /// Two bools, one for each axis (X and Y). #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] @@ -43,6 +45,12 @@ impl Vec2b { y: self.y || other.y, } } + + /// Convert to a float `Vec2` where the components are 1.0 for `true` and 0.0 for `false`. + #[inline] + pub fn to_vec2(self) -> Vec2 { + Vec2::new(self.x.into(), self.y.into()) + } } impl From for Vec2b {