use js_sys::wasm_bindgen::JsCast;
use wasm_bindgen_futures::spawn_local;
use web_sys::{Document, HtmlCanvasElement, console};
use crate::error::Error;
pub(crate) fn document() -> Result<Document, Error> {
web_sys::window()
.ok_or(Error::window_not_found())
.and_then(|w| w.document().ok_or(Error::document_not_found()))
}
pub(crate) fn get_canvas_by_id(canvas_id: &str) -> Result<HtmlCanvasElement, Error> {
let document = document()?;
document
.query_selector(canvas_id)
.map_err(|_| Error::canvas_not_found())?
.ok_or(Error::canvas_not_found())?
.dyn_into::<web_sys::HtmlCanvasElement>()
.map_err(|_| Error::canvas_not_found())
}
#[cfg(target_arch = "wasm32")]
pub(crate) fn get_webgl2_context(
canvas: &HtmlCanvasElement,
) -> Result<web_sys::WebGl2RenderingContext, Error> {
canvas
.get_context("webgl2")
.map_err(|_| Error::canvas_context_failed())?
.ok_or(Error::webgl_context_failed())?
.dyn_into::<web_sys::WebGl2RenderingContext>()
.map_err(|_| Error::webgl_context_failed())
}
#[cfg(target_arch = "wasm32")]
pub(crate) fn create_glow_context(
canvas: &HtmlCanvasElement,
) -> Result<(glow::Context, web_sys::WebGl2RenderingContext), Error> {
let webgl2_ctx = get_webgl2_context(canvas)?;
let gl = glow::Context::from_webgl2_context(webgl2_ctx.clone());
Ok((gl, webgl2_ctx))
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn create_glow_context(
_canvas: &HtmlCanvasElement,
) -> Result<(glow::Context, web_sys::WebGl2RenderingContext), Error> {
unimplemented!("create_glow_context is only available on wasm32")
}
pub(crate) fn device_pixel_ratio() -> f32 {
web_sys::window()
.map(|w| w.device_pixel_ratio() as f32)
.unwrap_or(1.0)
}
pub(crate) fn copy_to_clipboard(text: impl Into<String>) {
let text = text.into();
spawn_local(async move {
if let Some(window) = web_sys::window() {
let clipboard = window.navigator().clipboard();
if let Err(err) =
wasm_bindgen_futures::JsFuture::from(clipboard.write_text(&text)).await
{
console::error_1(&format!("Failed to copy to clipboard: {err:?}").into());
}
}
});
}