use super::App;
use crate::{Pt, platform};
use wasm_bindgen::JsCast;
impl App {
pub(crate) fn init_audio_on_gesture(&mut self) {
if self.ctx.runtime.audio.is_some() {
return;
}
match crate::audio::AudioSystem::new() {
Ok(audio) => {
self.ctx.runtime.audio = Some(audio);
}
Err(e) => {
web_sys::console::warn_1(&format!("[spot][wasm] Audio unavailable: {e:?}").into());
}
}
}
pub(crate) fn sync_canvas_resize(&mut self) {
let Some(window) = self.platform.window.as_ref() else {
return;
};
let canvas = self.platform.canvas_id.as_deref().and_then(|id| {
web_sys::window()
.and_then(|w| w.document())
.and_then(|d| d.get_element_by_id(id))
.and_then(|e| e.dyn_into::<web_sys::HtmlCanvasElement>().ok())
});
let Some(canvas) = canvas else {
return;
};
let rect = canvas.get_bounding_client_rect();
let css_w = rect.width() as f64;
let css_h = rect.height() as f64;
if !(css_w.is_finite() && css_h.is_finite()) {
return;
}
let dpr = self.scale_factor;
let w = ((css_w * dpr).round() as i64).max(1) as u32;
let h = ((css_h * dpr).round() as i64).max(1) as u32;
let canvas_matches = canvas.width() == w && canvas.height() == h;
let graphics_matches = self
.ctx
.runtime
.graphics
.as_ref()
.map(|g| g.config.width == w && g.config.height == h)
.unwrap_or(false);
if self.platform.last_physical_size == Some((w, h)) && canvas_matches && graphics_matches {
return;
}
self.platform.last_physical_size = Some((w, h));
if !canvas_matches {
canvas.set_width(w);
canvas.set_height(h);
}
if !graphics_matches
&& let Some(surface) = self.surface.as_ref()
&& let Some(g) = self.ctx.runtime.graphics.as_mut()
{
g.resize(surface, w, h);
}
self.ctx.set_window_logical_size(
Pt::from_physical_px(w as f64, self.scale_factor),
Pt::from_physical_px(h as f64, self.scale_factor),
);
window.request_redraw();
}
}
pub(crate) unsafe fn handle_wasm_graphics_init_result(
app_ptr: *mut App,
graphics_r: anyhow::Result<crate::graphics::core::Graphics>,
) {
match graphics_r {
Ok(graphics) => unsafe {
(*app_ptr).init_state = platform::GraphicsInitState::Ready(Box::new(Some(graphics)));
},
Err(e) => {
web_sys::console::error_1(
&format!("[spot][wasm][init] Graphics::new failed: {:?}", e).into(),
);
unsafe {
(*app_ptr).init_state = platform::GraphicsInitState::Failed;
}
}
}
if let Some(_) = unsafe { (*app_ptr).platform.window.as_ref() } {
let closure = wasm_bindgen::prelude::Closure::once(move || {
if let Some(window) = unsafe { (*app_ptr).platform.window.as_ref() } {
window.request_redraw();
}
});
web_sys::window()
.and_then(|w| {
w.request_animation_frame(closure.as_ref().unchecked_ref())
.ok()
})
.expect("failed to request_animation_frame");
closure.forget();
}
}