euv_ui/hook/use_intersection_observer/
impl.rs1use super::*;
2
3impl UseIntersectionObserver {
5 pub(crate) fn new() -> Self {
11 Self {
12 target: NodeRef::new(),
13 visible: Signal::create(false),
14 ratio: Signal::create(0.0),
15 teardown: Rc::new(RefCell::new(None)),
16 }
17 }
18
19 pub fn is_visible(&self) -> bool {
25 self.get_visible().get()
26 }
27
28 pub fn current_ratio(&self) -> f64 {
34 self.get_ratio().get()
35 }
36
37 pub(crate) fn attach(&self) {
43 #[cfg(target_arch = "wasm32")]
44 {
45 let visible: Signal<bool> = self.get_visible();
46 let ratio: Signal<f64> = self.get_ratio();
47 let closure: Closure<dyn FnMut(Array)> =
48 Closure::wrap(Box::new(move |entries: Array| {
49 for entry in entries.iter() {
50 let Ok(entry) = entry.dyn_into::<IntersectionObserverEntry>() else {
51 continue;
52 };
53 visible.set(entry.is_intersecting());
54 ratio.set(entry.intersection_ratio());
55 }
56 }));
57 let Ok(observer) = IntersectionObserver::new(closure.as_ref().unchecked_ref()) else {
58 return;
59 };
60 let target: NodeRef<Element> = self.get_target().clone();
61 let observed: IntersectionObserver = observer.clone();
62 after_mount(move || {
63 if let Some(element) = target.get_cloned() {
64 observed.observe(&element);
65 }
66 });
67 let disconnect: Rc<RefCell<Option<IntersectionObserver>>> =
68 Rc::new(RefCell::new(Some(observer)));
69 *self.get_teardown().borrow_mut() = Some(Box::new(move || {
70 if let Some(observer) = disconnect.borrow_mut().take() {
71 observer.disconnect();
72 }
73 }));
74 }
75 }
76
77 pub(crate) fn detach(&self) {
79 let taken: Option<Box<dyn Fn()>> = self.get_teardown().borrow_mut().take();
80 if let Some(teardown) = taken {
81 teardown();
82 }
83 }
84}