use crate::easing::Easing;
use crate::traits::Update;
use crate::tween::Tween;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FlipState {
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
}
impl FlipState {
pub fn from_rect(x: f32, y: f32, width: f32, height: f32) -> Self {
Self { x, y, width, height }
}
pub fn capture(element: &web_sys::Element) -> Self {
let rect = element.get_bounding_client_rect();
Self {
x: rect.x() as f32,
y: rect.y() as f32,
width: rect.width() as f32,
height: rect.height() as f32,
}
}
pub fn diff(first: &FlipState, last: &FlipState) -> FlipAnimationBuilder {
let dx = first.x - last.x;
let dy = first.y - last.y;
let sx = if last.width > 0.0 { first.width / last.width } else { 1.0 };
let sy = if last.height > 0.0 { first.height / last.height } else { 1.0 };
FlipAnimationBuilder {
dx, dy, sx, sy,
duration: 0.3,
easing: Easing::EaseOutCubic,
}
}
}
#[derive(Debug)]
pub struct FlipAnimationBuilder {
dx: f32,
dy: f32,
sx: f32,
sy: f32,
duration: f32,
easing: Easing,
}
impl FlipAnimationBuilder {
pub fn duration(mut self, d: f32) -> Self {
self.duration = d;
self
}
pub fn easing(mut self, e: Easing) -> Self {
self.easing = e;
self
}
pub fn build(self) -> FlipAnimation {
FlipAnimation {
translate_x: Tween::new(self.dx, 0.0)
.duration(self.duration)
.easing(self.easing.clone())
.build(),
translate_y: Tween::new(self.dy, 0.0)
.duration(self.duration)
.easing(self.easing.clone())
.build(),
scale_x: Tween::new(self.sx, 1.0)
.duration(self.duration)
.easing(self.easing.clone())
.build(),
scale_y: Tween::new(self.sy, 1.0)
.duration(self.duration)
.easing(self.easing)
.build(),
}
}
}
#[derive(Debug)]
pub struct FlipAnimation {
pub translate_x: Tween<f32>,
pub translate_y: Tween<f32>,
pub scale_x: Tween<f32>,
pub scale_y: Tween<f32>,
}
impl FlipAnimation {
pub fn is_complete(&self) -> bool {
self.translate_x.is_complete()
&& self.translate_y.is_complete()
&& self.scale_x.is_complete()
&& self.scale_y.is_complete()
}
pub fn transform(&self) -> (f32, f32, f32, f32) {
(
self.translate_x.value(),
self.translate_y.value(),
self.scale_x.value(),
self.scale_y.value(),
)
}
pub fn css_transform(&self) -> String {
let (tx, ty, sx, sy) = self.transform();
format!("translate({tx}px, {ty}px) scale({sx}, {sy})")
}
}
impl Update for FlipAnimation {
fn update(&mut self, dt: f32) -> bool {
let a = self.translate_x.update(dt);
let b = self.translate_y.update(dt);
let c = self.scale_x.update(dt);
let d = self.scale_y.update(dt);
a || b || c || d
}
}