use wasm_bindgen::JsCast;
use web_sys::{OffscreenCanvas, OffscreenCanvasRenderingContext2d};
use super::{canvas::WebCanvas, device::WebDeviceContext};
use crate::{
base::Dimension,
canvas::CanvasBackend,
error::GraphicsError,
geometry::{FSize, ISize},
layer::LayerBackend,
Float,
};
#[derive(Clone, Debug)]
pub struct WebLayer {
layer: OffscreenCanvas,
}
impl Dimension for WebLayer {
fn size(&self) -> FSize {
FSize::new(self.layer.width() as Float, self.layer.height() as Float)
}
fn pixel_size(&self) -> ISize {
ISize::new(self.layer.width() as i32, self.layer.height() as i32)
}
}
impl LayerBackend for WebLayer {
type DeviceContextType = WebDeviceContext;
type CanvasType = WebCanvas;
fn new(_context: Option<&Self::DeviceContextType>, width: usize, height: usize, canvas: &Self::CanvasType) -> Result<Self, GraphicsError> {
let matrix = canvas.get_matrix().matrix;
let scale_x = matrix.m11();
let scale_y = matrix.m22();
let width = (width as f64 * scale_x).ceil() as u32;
let height = (height as f64 * scale_y).ceil() as u32;
OffscreenCanvas::new(width, height)
.map(|layer| {
let context = layer.get_context("2d").unwrap().unwrap().dyn_into::<OffscreenCanvasRenderingContext2d>().unwrap();
context.scale(scale_x, scale_y).ok();
Self {
layer,
}
})
.map_err(|err| GraphicsError::CreationFailed(err.as_string().unwrap_or(stringify!(OffscreenCanvas).to_string())))
}
}
impl WebLayer {
pub(super) fn layer(&self) -> &OffscreenCanvas {
&self.layer
}
}