Added support for fling on touch devices.
This commit is contained in:
parent
17d4cfb263
commit
eb3f8f9b10
51
src/lib.rs
51
src/lib.rs
|
|
@ -30,6 +30,7 @@ impl Plugin for ScrollViewPlugin {
|
||||||
input_mouse_pressed_move,
|
input_mouse_pressed_move,
|
||||||
input_touch_pressed_move,
|
input_touch_pressed_move,
|
||||||
scroll_events,
|
scroll_events,
|
||||||
|
fling_update,
|
||||||
scroll_update,
|
scroll_update,
|
||||||
)
|
)
|
||||||
.chain(),
|
.chain(),
|
||||||
|
|
@ -44,12 +45,18 @@ pub struct ScrollView {
|
||||||
/// Field which control speed of the scrolling.
|
/// Field which control speed of the scrolling.
|
||||||
/// Could be negative number to implement invert scroll
|
/// Could be negative number to implement invert scroll
|
||||||
pub scroll_speed: f32,
|
pub scroll_speed: f32,
|
||||||
|
/// Amount of friction to apply to slow down the fling
|
||||||
|
pub friction: f32,
|
||||||
|
/// Current vertical velocity
|
||||||
|
pub velocity: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ScrollView {
|
impl Default for ScrollView {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
scroll_speed: 1200.0,
|
scroll_speed: 1200.0,
|
||||||
|
friction: 4.2,
|
||||||
|
velocity: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -174,24 +181,19 @@ fn update_size(
|
||||||
|
|
||||||
fn input_touch_pressed_move(
|
fn input_touch_pressed_move(
|
||||||
touches: Res<Touches>,
|
touches: Res<Touches>,
|
||||||
mut q: Query<(&Children, &Interaction), With<ScrollView>>,
|
mut q: Query<(&Interaction, &mut ScrollView)>,
|
||||||
mut content_q: Query<&mut ScrollableContent>,
|
time: Res<Time>,
|
||||||
) {
|
) {
|
||||||
for t in touches.iter() {
|
for t in touches.iter() {
|
||||||
let Some(touch) = touches.get_pressed(t.id()) else {
|
let Some(touch) = touches.get_pressed(t.id()) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (children, &interaction) in q.iter_mut() {
|
for (&interaction, mut view) in q.iter_mut() {
|
||||||
if interaction != Interaction::Pressed {
|
if interaction != Interaction::Pressed {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for child in children.iter() {
|
view.velocity = (view.velocity + touch.delta().y / time.delta_secs()) / 2.0;
|
||||||
let Ok(mut scroll) = content_q.get_mut(child) else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
scroll.scroll_by(touch.delta().y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -232,3 +234,34 @@ fn scroll_update(mut q: Query<(&ScrollableContent, &mut Node), Changed<Scrollabl
|
||||||
style.top = Val::Px(scroll.pos_y);
|
style.top = Val::Px(scroll.pos_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fling_update(
|
||||||
|
mut q_view: Query<(&mut ScrollView, &Children)>,
|
||||||
|
mut q_scroll: Query<&mut ScrollableContent>,
|
||||||
|
time: Res<Time>,
|
||||||
|
) {
|
||||||
|
for (mut view, children) in q_view.iter_mut() {
|
||||||
|
let mut iter = q_scroll.iter_many_mut(children);
|
||||||
|
while let Some(mut scroll) = iter.fetch_next() {
|
||||||
|
if view.velocity.abs() > 16.0 {
|
||||||
|
let (value, velocity) = calc_velocity(
|
||||||
|
scroll.pos_y,
|
||||||
|
view.velocity,
|
||||||
|
-view.friction,
|
||||||
|
time.delta_secs(),
|
||||||
|
);
|
||||||
|
view.velocity = velocity;
|
||||||
|
scroll.pos_y = value.clamp(-scroll.max_scroll, 0.);
|
||||||
|
} else {
|
||||||
|
view.velocity = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_velocity(value: f32, velocity: f32, friction: f32, delta_t: f32) -> (f32, f32) {
|
||||||
|
(
|
||||||
|
value - velocity / friction + velocity / friction * (friction * delta_t).exp(),
|
||||||
|
velocity * (delta_t * friction).exp(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue