-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First pass at making a scroll handling component; wire up to fader
Many open questions: * Delta direction may vary based on "natural scroll" setting in OS? * Does it work on trackpads or do we need to use `scroll` event instead? * There are different delta modes (pixels vs lines etc) * Actual delta seems fixed in increments of 100 but this may be specific to my OS / browser * I am putting the direction in their own enum variant (instead of negative) but given we have to use a negative number later, this might not be useful. * There are other event attributes that web_sys doesn't expose which may have more complete data for making sure the way we interpret scroll deltas is more normalised. Ideally, we could detect the minimum scroll increment and pass a single Up/Down scroll increment internally. Right now I'm passing 100 or -100 to the fader and then scaling that down by 0.001 but that doesn't feel right.
- Loading branch information
Showing
4 changed files
with
129 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
pub mod drag_target; | ||
pub mod scroll_target; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
use gloo_events::{EventListener, EventListenerOptions}; | ||
use wasm_bindgen::JsCast; | ||
use web_sys::{WheelEvent, Element}; | ||
use yew::{html, Component, ComponentLink, Html, ShouldRender, Properties, NodeRef, Children, Callback, Renderable}; | ||
|
||
#[derive(Properties, Clone)] | ||
pub struct ScrollProps { | ||
#[prop_or_default] | ||
pub on_scroll: Option<Callback<Scroll>>, | ||
|
||
#[prop_or_default] | ||
pub children: Children, | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub enum Scroll { | ||
Up(f64), | ||
Down(f64), | ||
} | ||
|
||
pub struct ScrollTarget { | ||
link: ComponentLink<Self>, | ||
props: ScrollProps, | ||
container: NodeRef, | ||
// state: Option<ScrollState>, | ||
} | ||
|
||
impl Component for ScrollTarget { | ||
type Properties = ScrollProps; | ||
type Message = (); | ||
|
||
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self { | ||
ScrollTarget { | ||
link, | ||
props, | ||
container: NodeRef::default(), | ||
} | ||
} | ||
|
||
fn change(&mut self, props: Self::Properties) -> ShouldRender { | ||
self.props = props; | ||
true | ||
} | ||
|
||
fn update(&mut self, msg: Self::Message) -> ShouldRender { | ||
crate::log!("{:?}", msg); | ||
false | ||
} | ||
|
||
// yew doesn't know about `onwheel` and tries to call `to_string()`, so | ||
// attaching event handler manually. | ||
fn mounted(&mut self) -> ShouldRender { | ||
if let Some(el) = self.container.cast::<Element>() { | ||
let options = EventListenerOptions::enable_prevent_default(); | ||
let wheel = EventListener::new_with_options( | ||
&el, "wheel", options, | ||
{ | ||
let on_scroll = self.props.on_scroll.clone(); | ||
move |ev| { | ||
if let Some(on_scroll) = &on_scroll { | ||
if let Some(ev) = ev.dyn_ref::<WheelEvent>().cloned() { | ||
let delta = ev.delta_y(); | ||
|
||
let scroll = if delta < 0.0 { | ||
Scroll::Up(delta.abs()) | ||
} else { | ||
Scroll::Down(delta.abs()) | ||
}; | ||
|
||
ev.prevent_default(); | ||
ev.stop_propagation(); | ||
on_scroll.emit(scroll); | ||
} | ||
} | ||
} | ||
} | ||
); | ||
|
||
// TODO: maybe store this in the state. Unclear when this is dropped | ||
// if forgotten. | ||
wheel.forget(); | ||
} | ||
|
||
false | ||
} | ||
|
||
fn view(&self) -> Html { | ||
html! { | ||
<div | ||
class="scroll-target-container" | ||
ref={self.container.clone()} | ||
> | ||
{self.props.children.render()} | ||
</div> | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters