Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kinetic scrolling #20

Merged
merged 3 commits into from
Sep 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ TODO-list for the Egui project. If you looking for something to do, look here.
* [x] Scroll-wheel input
* [x] Drag background to scroll
* [ ] Horizontal scrolling
* [ ] Kinetic scrolling
* [X] Kinetic scrolling
* [ ] Text
* [ ] Unicode
* [ ] Shared mutable expanding texture map?
Expand Down
2 changes: 1 addition & 1 deletion egui/src/containers/area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl State {
}
}

/// An area on the screen that can be move by dragging.
/// An area on the screen that can be moved by dragging.
///
/// This forms the base of the `Window` container.
#[derive(Clone, Copy, Debug)]
Expand Down
25 changes: 24 additions & 1 deletion egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ pub(crate) struct State {
offset: Vec2,

show_scroll: bool,

/// Momentum, used for kinetic scrolling
#[cfg_attr(feature = "serde", serde(skip))]
pub vel: Vec2,
}

impl Default for State {
fn default() -> Self {
Self {
offset: Vec2::zero(),
show_scroll: false,
vel: Vec2::zero(),
}
}
}
Expand Down Expand Up @@ -153,8 +158,26 @@ impl Prepared {
if content_is_too_small {
// Drag contents to scroll (for touch screens mostly):
let content_response = ui.interact(inner_rect, id.with("area"), Sense::drag());

let input = ui.input();
if content_response.active {
state.offset.y -= ui.input().mouse.delta.y;
state.offset.y -= input.mouse.delta.y;
state.vel = input.mouse.velocity;
} else {
let stop_speed = 20.0; // Pixels per second.
let friction_coeff = 1000.0; // Pixels per second squared.
let dt = input.unstable_dt;

let friction = friction_coeff * dt;
if friction > state.vel.length() || state.vel.length() < stop_speed {
state.vel = Vec2::zero();
} else {
state.vel -= friction * state.vel.normalized();
// Offset has an inverted coordinate system compared to
// the velocity, so we subtract it instead of adding it
state.offset.y -= state.vel.y * dt;
ui.ctx().request_repaint();
}
}
}

Expand Down