-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2411 from finos/intersection-observer
Add `setAutoPause()` method
- Loading branch information
Showing
9 changed files
with
276 additions
and
76 deletions.
There are no files selected for viewing
Binary file not shown.
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
32 changes: 32 additions & 0 deletions
32
rust/perspective-viewer/src/rust/js/intersection_observer.rs
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,32 @@ | ||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ | ||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃ | ||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃ | ||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃ | ||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃ | ||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ | ||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃ | ||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃ | ||
// ┃ This file is part of the Perspective library, distributed under the terms ┃ | ||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ | ||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ | ||
|
||
use wasm_bindgen::prelude::*; | ||
|
||
#[wasm_bindgen(inline_js = "export const IntersectionObserver = window.IntersectionObserver")] | ||
extern "C" { | ||
pub type IntersectionObserver; | ||
|
||
#[wasm_bindgen(constructor, js_class = "IntersectionObserver")] | ||
pub fn new(callback: &js_sys::Function) -> IntersectionObserver; | ||
|
||
#[wasm_bindgen(method)] | ||
pub fn observe(this: &IntersectionObserver, elem: &web_sys::HtmlElement); | ||
|
||
#[wasm_bindgen(method)] | ||
pub fn unobserve(this: &IntersectionObserver, elem: &web_sys::HtmlElement); | ||
|
||
pub type IntersectionObserverEntry; | ||
|
||
#[wasm_bindgen(method, getter, js_name = "isIntersecting")] | ||
pub fn is_intersecting(this: &IntersectionObserverEntry) -> bool; | ||
} |
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
83 changes: 83 additions & 0 deletions
83
rust/perspective-viewer/src/rust/model/intersection_observer.rs
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,83 @@ | ||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ | ||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃ | ||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃ | ||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃ | ||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃ | ||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ | ||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃ | ||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃ | ||
// ┃ This file is part of the Perspective library, distributed under the terms ┃ | ||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ | ||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ | ||
|
||
use wasm_bindgen::prelude::*; | ||
use wasm_bindgen::JsCast; | ||
use web_sys::*; | ||
|
||
use crate::config::*; | ||
use crate::js::*; | ||
use crate::model::*; | ||
use crate::renderer::*; | ||
use crate::session::Session; | ||
use crate::utils::*; | ||
use crate::*; | ||
|
||
pub struct IntersectionObserverHandle { | ||
elem: HtmlElement, | ||
observer: IntersectionObserver, | ||
_callback: Closure<dyn FnMut(js_sys::Array)>, | ||
} | ||
|
||
impl IntersectionObserverHandle { | ||
pub fn new(elem: &HtmlElement, session: &Session, renderer: &Renderer) -> Self { | ||
clone!(session, renderer); | ||
let _callback = (move |xs: js_sys::Array| { | ||
let intersect = xs | ||
.get(0) | ||
.unchecked_into::<IntersectionObserverEntry>() | ||
.is_intersecting(); | ||
|
||
clone!(session, renderer); | ||
let state = IntersectionObserverState { session, renderer }; | ||
ApiFuture::spawn(state.set_pause(intersect)); | ||
}) | ||
.into_closure_mut(); | ||
|
||
let func = _callback.as_ref().unchecked_ref::<js_sys::Function>(); | ||
let observer = IntersectionObserver::new(func); | ||
observer.observe(elem); | ||
Self { | ||
elem: elem.clone(), | ||
_callback, | ||
observer, | ||
} | ||
} | ||
} | ||
|
||
impl Drop for IntersectionObserverHandle { | ||
fn drop(&mut self) { | ||
self.observer.unobserve(&self.elem); | ||
} | ||
} | ||
|
||
struct IntersectionObserverState { | ||
session: Session, | ||
renderer: Renderer, | ||
} | ||
|
||
impl IntersectionObserverState { | ||
async fn set_pause(self, intersect: bool) -> ApiResult<()> { | ||
if intersect { | ||
if self.session.set_pause(false) { | ||
tracing::error!("Shellac-ed"); | ||
self.update_and_render(ViewConfigUpdate::default()).await?; | ||
} | ||
} else { | ||
self.session.set_pause(true); | ||
}; | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
derive_model!(Renderer, Session for IntersectionObserverState); |
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 |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ | ||
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃ | ||
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃ | ||
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃ | ||
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃ | ||
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ | ||
// ┃ Copyright (c) 2017, the Perspective Authors. ┃ | ||
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃ | ||
// ┃ This file is part of the Perspective library, distributed under the terms ┃ | ||
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ | ||
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ | ||
|
||
use wasm_bindgen::prelude::*; | ||
use wasm_bindgen::JsCast; | ||
use web_sys::*; | ||
use yew::prelude::*; | ||
|
||
use crate::components::viewer::{PerspectiveViewer, PerspectiveViewerMsg}; | ||
use crate::js::*; | ||
use crate::renderer::*; | ||
use crate::utils::*; | ||
use crate::*; | ||
|
||
pub struct ResizeObserverHandle { | ||
elem: HtmlElement, | ||
observer: ResizeObserver, | ||
_callback: Closure<dyn FnMut(js_sys::Array)>, | ||
} | ||
|
||
impl ResizeObserverHandle { | ||
pub fn new( | ||
elem: &HtmlElement, | ||
renderer: &Renderer, | ||
root: &AppHandle<PerspectiveViewer>, | ||
) -> Self { | ||
let on_resize = root.callback(|()| PerspectiveViewerMsg::Resize); | ||
let mut state = ResizeObserverState { | ||
elem: elem.clone(), | ||
renderer: renderer.clone(), | ||
width: elem.offset_width(), | ||
height: elem.offset_height(), | ||
on_resize, | ||
}; | ||
|
||
let _callback = (move |xs| state.on_resize(&xs)).into_closure_mut(); | ||
let func = _callback.as_ref().unchecked_ref::<js_sys::Function>(); | ||
let observer = ResizeObserver::new(func); | ||
observer.observe(elem); | ||
Self { | ||
elem: elem.clone(), | ||
_callback, | ||
observer, | ||
} | ||
} | ||
} | ||
|
||
impl Drop for ResizeObserverHandle { | ||
fn drop(&mut self) { | ||
self.observer.unobserve(&self.elem); | ||
} | ||
} | ||
|
||
struct ResizeObserverState { | ||
elem: HtmlElement, | ||
renderer: Renderer, | ||
width: i32, | ||
height: i32, | ||
on_resize: Callback<()>, | ||
} | ||
|
||
impl ResizeObserverState { | ||
fn on_resize(&mut self, entries: &js_sys::Array) { | ||
let is_visible = self | ||
.elem | ||
.offset_parent() | ||
.map(|x| !x.is_null()) | ||
.unwrap_or(false); | ||
|
||
for y in entries.iter() { | ||
let entry: ResizeObserverEntry = y.unchecked_into(); | ||
let content = entry.content_rect(); | ||
let content_width = content.width().floor() as i32; | ||
let content_height = content.height().floor() as i32; | ||
let resized = self.width != content_width || self.height != content_height; | ||
if resized && is_visible { | ||
clone!(self.on_resize, self.renderer); | ||
ApiFuture::spawn(async move { | ||
renderer.resize().await?; | ||
on_resize.emit(()); | ||
Ok(()) | ||
}); | ||
} | ||
|
||
self.width = content_width; | ||
self.height = content_height; | ||
} | ||
} | ||
} |
Oops, something went wrong.