use std::ops::Mul;
use web_sys::{DomMatrix, DomPoint, DomPointInit};
use crate::{geometry::FRect, matrix::MatrixBackend, Float};
#[derive(Clone, Debug, PartialEq)]
pub struct WebMatrix {
pub matrix: DomMatrix,
}
impl Mul for WebMatrix {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self {
matrix: self.matrix.multiply(&rhs.matrix),
}
}
}
impl MatrixBackend for WebMatrix {
fn identity() -> Self {
Self {
matrix: DomMatrix::new().unwrap(),
}
}
fn from_row(scx: Float, sky: Float, skx: Float, scy: Float, tx: Float, ty: Float) -> Self {
let matrix = DomMatrix::new().unwrap();
matrix.set_a(scx);
matrix.set_b(sky);
matrix.set_c(skx);
matrix.set_d(scy);
matrix.set_e(tx);
matrix.set_f(ty);
Self {
matrix,
}
}
fn from_translate(x: Float, y: Float) -> Self {
let matrix = DomMatrix::new().unwrap();
matrix.set_e(x);
matrix.set_f(y);
Self {
matrix,
}
}
fn from_scale(x: Float, y: Float) -> Self {
let matrix = DomMatrix::new().unwrap();
matrix.set_a(x);
matrix.set_d(y);
Self {
matrix,
}
}
fn from_rotate(angle: Float) -> Self {
let matrix = DomMatrix::new().unwrap();
matrix.rotate(angle.to_degrees());
Self {
matrix,
}
}
fn pre_rotate(&mut self, angle: Float) {
let matrix = DomMatrix::new().unwrap();
matrix.rotate(angle.to_degrees());
self.matrix.pre_multiply_self(&matrix);
}
fn pre_translate(&mut self, x: Float, y: Float) {
let matrix = DomMatrix::new().unwrap();
matrix.set_e(x);
matrix.set_f(y);
self.matrix.pre_multiply_self(&matrix);
}
fn pre_scale(&mut self, x: Float, y: Float) {
let matrix = DomMatrix::new().unwrap();
matrix.set_a(x);
matrix.set_d(y);
self.matrix.pre_multiply_self(&matrix);
}
fn post_rotate(&mut self, angle: Float) {
let matrix = DomMatrix::new().unwrap();
matrix.rotate(angle.to_degrees());
self.matrix.multiply_self(&matrix);
}
fn post_scale(&mut self, x: Float, y: Float) {
let matrix = DomMatrix::new().unwrap();
matrix.set_a(x);
matrix.set_d(y);
self.matrix.multiply_self(&matrix);
}
fn post_translate(&mut self, x: Float, y: Float) {
let matrix = DomMatrix::new().unwrap();
matrix.set_e(x);
matrix.set_f(y);
self.matrix.multiply_self(&matrix);
}
fn map_rect(&self, rect: FRect) -> FRect {
let point1 = self.map_point(rect.point.x, rect.point.y);
let point2 = self.map_point(rect.point.x + rect.size.width, rect.point.y);
let point3 = self.map_point(rect.point.x, rect.point.y + rect.size.height);
let point4 = self.map_point(rect.point.x + rect.size.width, rect.point.y + rect.size.height);
let min_x = point1.x().min(point2.x()).min(point3.x()).min(point4.x());
let min_y = point1.y().min(point2.y()).min(point3.y()).min(point4.y());
let max_x = point1.x().max(point2.x()).max(point3.x()).max(point4.x());
let max_y = point1.y().max(point2.y()).max(point3.y()).max(point4.y());
FRect::new(min_x, min_y, max_x - min_x, max_y - min_y)
}
}
impl WebMatrix {
pub(super) fn matrix(&self) -> &DomMatrix {
&self.matrix
}
fn map_point(&self, x: Float, y: Float) -> DomPoint {
let point = DomPointInit::new();
point.set_x(x);
point.set_y(y);
self.matrix.transform_point_with_point(&point)
}
}
impl From<DomMatrix> for WebMatrix {
fn from(matrix: DomMatrix) -> Self {
Self {
matrix,
}
}
}