On Web, cache commonly used values (#2947)
This commit is contained in:
parent
c4d70d75c1
commit
af26f01b95
7 changed files with 131 additions and 126 deletions
|
|
@ -21,7 +21,9 @@ use smol_str::SmolStr;
|
|||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
use wasm_bindgen::{closure::Closure, JsCast, JsValue};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, WheelEvent};
|
||||
use web_sys::{
|
||||
CssStyleDeclaration, Document, Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, WheelEvent,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct Canvas {
|
||||
|
|
@ -44,8 +46,10 @@ pub struct Canvas {
|
|||
|
||||
pub struct Common {
|
||||
pub window: web_sys::Window,
|
||||
pub document: Document,
|
||||
/// Note: resizing the HTMLCanvasElement should go through `backend::set_canvas_size` to ensure the DPI factor is maintained.
|
||||
pub raw: HtmlCanvasElement,
|
||||
style: CssStyleDeclaration,
|
||||
old_size: Rc<Cell<PhysicalSize<u32>>>,
|
||||
current_size: Rc<Cell<PhysicalSize<u32>>>,
|
||||
wants_fullscreen: Rc<RefCell<bool>>,
|
||||
|
|
@ -55,21 +59,16 @@ impl Canvas {
|
|||
pub fn create(
|
||||
id: WindowId,
|
||||
window: web_sys::Window,
|
||||
document: Document,
|
||||
attr: &WindowAttributes,
|
||||
platform_attr: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<Self, RootOE> {
|
||||
let canvas = match platform_attr.canvas {
|
||||
Some(canvas) => canvas,
|
||||
None => {
|
||||
let document = window
|
||||
.document()
|
||||
.ok_or_else(|| os_error!(OsError("Failed to obtain document".to_owned())))?;
|
||||
|
||||
document
|
||||
.create_element("canvas")
|
||||
.map_err(|_| os_error!(OsError("Failed to create canvas element".to_owned())))?
|
||||
.unchecked_into()
|
||||
}
|
||||
None => document
|
||||
.create_element("canvas")
|
||||
.map_err(|_| os_error!(OsError("Failed to create canvas element".to_owned())))?
|
||||
.unchecked_into(),
|
||||
};
|
||||
|
||||
// A tabindex is needed in order to capture local keyboard events.
|
||||
|
|
@ -83,15 +82,24 @@ impl Canvas {
|
|||
.map_err(|_| os_error!(OsError("Failed to set a tabindex".to_owned())))?;
|
||||
}
|
||||
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let style = window
|
||||
.get_computed_style(&canvas)
|
||||
.expect("Failed to obtain computed style")
|
||||
// this can't fail: we aren't using a pseudo-element
|
||||
.expect("Invalid pseudo-element");
|
||||
|
||||
if let Some(size) = attr.inner_size {
|
||||
let size = size.to_logical(super::scale_factor(&window));
|
||||
super::set_canvas_size(&window, &canvas, size);
|
||||
super::set_canvas_size(&document, &canvas, &style, size);
|
||||
}
|
||||
|
||||
Ok(Canvas {
|
||||
common: Common {
|
||||
window,
|
||||
document,
|
||||
raw: canvas,
|
||||
style,
|
||||
old_size: Rc::default(),
|
||||
current_size: Rc::default(),
|
||||
wants_fullscreen: Rc::new(RefCell::new(false)),
|
||||
|
|
@ -117,12 +125,7 @@ impl Canvas {
|
|||
if lock {
|
||||
self.raw().request_pointer_lock();
|
||||
} else {
|
||||
let document = self
|
||||
.common
|
||||
.window
|
||||
.document()
|
||||
.ok_or_else(|| os_error!(OsError("Failed to obtain document".to_owned())))?;
|
||||
document.exit_pointer_lock();
|
||||
self.common.document.exit_pointer_lock();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -141,50 +144,58 @@ impl Canvas {
|
|||
y: bounds.y(),
|
||||
};
|
||||
|
||||
let document = self.window().document().expect("Failed to obtain document");
|
||||
|
||||
if document.contains(Some(self.raw())) {
|
||||
let style = self
|
||||
.window()
|
||||
.get_computed_style(self.raw())
|
||||
.expect("Failed to obtain computed style")
|
||||
// this can't fail: we aren't using a pseudo-element
|
||||
.expect("Invalid pseudo-element");
|
||||
if style.get_property_value("display").unwrap() != "none" {
|
||||
position.x += super::style_size_property(&style, "border-left-width")
|
||||
+ super::style_size_property(&style, "padding-left");
|
||||
position.y += super::style_size_property(&style, "border-top-width")
|
||||
+ super::style_size_property(&style, "padding-top");
|
||||
}
|
||||
if self.document().contains(Some(self.raw()))
|
||||
&& self.style().get_property_value("display").unwrap() != "none"
|
||||
{
|
||||
position.x += super::style_size_property(self.style(), "border-left-width")
|
||||
+ super::style_size_property(self.style(), "padding-left");
|
||||
position.y += super::style_size_property(self.style(), "border-top-width")
|
||||
+ super::style_size_property(self.style(), "padding-top");
|
||||
}
|
||||
|
||||
position
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn old_size(&self) -> PhysicalSize<u32> {
|
||||
self.common.old_size.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
self.common.current_size.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_old_size(&self, size: PhysicalSize<u32>) {
|
||||
self.common.old_size.set(size)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_current_size(&self, size: PhysicalSize<u32>) {
|
||||
self.common.current_size.set(size)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn window(&self) -> &web_sys::Window {
|
||||
&self.common.window
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn document(&self) -> &Document {
|
||||
&self.common.document
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn raw(&self) -> &HtmlCanvasElement {
|
||||
&self.common.raw
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn style(&self) -> &CssStyleDeclaration {
|
||||
&self.common.style
|
||||
}
|
||||
|
||||
pub fn on_touch_start(&mut self, prevent_default: bool) {
|
||||
self.on_touch_start = Some(self.common.add_event("touchstart", move |event: Event| {
|
||||
if prevent_default {
|
||||
|
|
@ -382,7 +393,9 @@ impl Canvas {
|
|||
{
|
||||
self.on_resize_scale = Some(ResizeScaleHandle::new(
|
||||
self.window().clone(),
|
||||
self.document().clone(),
|
||||
self.raw().clone(),
|
||||
self.style().clone(),
|
||||
scale_handler,
|
||||
size_handler,
|
||||
));
|
||||
|
|
@ -425,7 +438,7 @@ impl Canvas {
|
|||
// Then we resize the canvas to the new size, a new
|
||||
// `Resized` event will be sent by the `ResizeObserver`:
|
||||
let new_size = new_size.to_logical(scale);
|
||||
super::set_canvas_size(self.window(), self.raw(), new_size);
|
||||
super::set_canvas_size(self.document(), self.raw(), self.style(), new_size);
|
||||
|
||||
// Set the size might not trigger the event because the calculation is inaccurate.
|
||||
self.on_resize_scale
|
||||
|
|
@ -527,6 +540,6 @@ impl Common {
|
|||
}
|
||||
|
||||
pub fn is_fullscreen(&self) -> bool {
|
||||
super::is_fullscreen(&self.window, &self.raw)
|
||||
super::is_fullscreen(&self.document, &self.raw)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue