yew_hooks/hooks/
use_raf.rs1use std::cmp::min_by;
2
3use gloo::render::request_animation_frame;
4use gloo::timers::callback::Timeout;
5use yew::prelude::*;
6
7#[hook]
30pub fn use_raf(millis: u32, delay: u32) -> f64 {
31 let elapsed = use_state(|| 0f64);
32 let start = use_mut_ref(|| 0f64);
33 let raf = use_mut_ref(|| None);
34 let on_frame = use_mut_ref(|| None);
35 let on_frame_clone = on_frame.clone();
36 let timer_stop = use_mut_ref(|| None);
37 let timer_delay = use_mut_ref(|| None);
38
39 {
40 let elapsed = elapsed.clone();
41 use_effect_with((millis, delay), move |(millis, delay)| {
42 let millis = *millis;
43 let delay = *delay;
44 *start.borrow_mut() = 0f64;
45
46 {
47 let raf = raf.clone();
48 let elapsed = elapsed.clone();
49 *on_frame_clone.borrow_mut() = Some(Box::new(move |time: f64| {
50 let on_frame = on_frame.clone();
51 if *start.borrow() <= 0f64 {
52 *start.borrow_mut() = time;
53 }
54 let time = min_by(
55 1f64,
56 (time - *start.borrow()) / f64::from(millis),
57 |x, y| x.partial_cmp(y).unwrap(),
58 );
59 elapsed.set(time);
60
61 *raf.borrow_mut() = Some(request_animation_frame(move |time| {
64 let on_frame = on_frame.borrow();
65 #[allow(clippy::borrowed_box)]
66 let on_frame: &Box<dyn Fn(f64)> = on_frame.as_ref().unwrap();
67 on_frame(time);
68 }));
69 }) as Box<dyn Fn(f64)>);
70 }
71
72 {
73 let raf = raf.clone();
74 let timer_stop = timer_stop.clone();
75 *timer_delay.borrow_mut() = Some(Timeout::new(delay, move || {
76 {
77 let raf = raf.clone();
78 *timer_stop.borrow_mut() = Some(Timeout::new(millis, move || {
79 *raf.borrow_mut() = None;
80 elapsed.set(1f64);
81 }));
82 }
83
84 *raf.borrow_mut() = Some(request_animation_frame(move |time| {
85 let on_frame_clone = on_frame_clone.borrow();
86 #[allow(clippy::borrowed_box)]
87 let on_frame_clone: &Box<dyn Fn(f64)> = on_frame_clone.as_ref().unwrap();
88 on_frame_clone(time);
89 }));
90 }));
91 }
92
93 move || {
94 *raf.borrow_mut() = None;
95 *timer_stop.borrow_mut() = None;
96 *timer_delay.borrow_mut() = None;
97 }
98 });
99 }
100
101 *elapsed
102}