feat: add request_animation_frame_with_handle and request_idle_callback_with_handle (#698)

This commit is contained in:
Elliot Waite 2023-03-18 16:09:36 -07:00 committed by GitHub
parent 309f0bf826
commit e1ba26b62c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -80,10 +80,33 @@ pub fn event_target_checked(ev: &web_sys::Event) -> bool {
.checked()
}
/// Runs the given function between the next repaint
/// using [`Window.requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame).
/// Handle that is generated by [request_animation_frame_with_handle] and can
/// be used to cancel the animation frame request.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct AnimationFrameRequestHandle(i32);
impl AnimationFrameRequestHandle {
/// Cancels the animation frame request to which this refers.
/// See [`cancelAnimationFrame()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame)
pub fn cancel(&self) {
_ = window().cancel_animation_frame(self.0);
}
}
/// Runs the given function between the next repaint using
/// [`Window.requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame).
#[cfg_attr(debug_assertions, instrument(level = "trace", skip_all))]
pub fn request_animation_frame(cb: impl FnOnce() + 'static) {
_ = request_animation_frame_with_handle(cb);
}
/// Runs the given function between the next repaint using
/// [`Window.requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame),
/// returning a cancelable handle.
#[cfg_attr(debug_assertions, instrument(level = "trace", skip_all))]
pub fn request_animation_frame_with_handle(
cb: impl FnOnce() + 'static,
) -> Result<AnimationFrameRequestHandle, JsValue> {
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
@ -95,13 +118,38 @@ pub fn request_animation_frame(cb: impl FnOnce() + 'static) {
}
let cb = Closure::once_into_js(cb);
_ = window().request_animation_frame(cb.as_ref().unchecked_ref());
window()
.request_animation_frame(cb.as_ref().unchecked_ref())
.map(AnimationFrameRequestHandle)
}
/// Queues the given function during an idle period
/// using [`Window.requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestIdleCallback).
/// Handle that is generated by [request_idle_callback_with_handle] and can be
/// used to cancel the idle callback.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct IdleCallbackHandle(u32);
impl IdleCallbackHandle {
/// Cancels the idle callback to which this refers.
/// See [`cancelAnimationFrame()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelIdleCallback)
pub fn cancel(&self) {
window().cancel_idle_callback(self.0);
}
}
/// Queues the given function during an idle period using
/// [`Window.requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestIdleCallback).
#[cfg_attr(debug_assertions, instrument(level = "trace", skip_all))]
pub fn request_idle_callback(cb: impl Fn() + 'static) {
_ = request_idle_callback_with_handle(cb);
}
/// Queues the given function during an idle period using
/// [`Window.requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestIdleCallback),
/// returning a cancelable handle.
#[cfg_attr(debug_assertions, instrument(level = "trace", skip_all))]
pub fn request_idle_callback_with_handle(
cb: impl Fn() + 'static,
) -> Result<IdleCallbackHandle, JsValue> {
cfg_if::cfg_if! {
if #[cfg(debug_assertions)] {
let span = ::tracing::Span::current();
@ -113,7 +161,9 @@ pub fn request_idle_callback(cb: impl Fn() + 'static) {
}
let cb = Closure::wrap(Box::new(cb) as Box<dyn Fn()>).into_js_value();
_ = window().request_idle_callback(cb.as_ref().unchecked_ref());
window()
.request_idle_callback(cb.as_ref().unchecked_ref())
.map(IdleCallbackHandle)
}
/// Executes the given function after the given duration of time has passed.