use crate::animation::{Easing, Spring, Decay};
use super::ModalAnimation;
pub fn material_dialog() -> ModalAnimation {
ModalAnimation::FadeScale {
duration_ms: 225,
easing: Easing::CubicBezier(0.0, 0.0, 0.2, 1.0), scale_from: 0.95,
scale_to: 1.0,
opacity_from: 0.0,
opacity_to: 1.0,
}
}
pub fn material_dialog_exit() -> ModalAnimation {
ModalAnimation::FadeScale {
duration_ms: 195,
easing: Easing::CubicBezier(0.4, 0.0, 1.0, 1.0), scale_from: 1.0,
scale_to: 0.95,
opacity_from: 1.0,
opacity_to: 0.0,
}
}
pub fn material_bottom_sheet() -> ModalAnimation {
ModalAnimation::SlideUp {
duration_ms: 450,
easing: Easing::CubicBezier(0.32, 1.0, 0.23, 1.0), translate_from: 100.0,
translate_to: 0.0,
opacity_from: 0.0,
opacity_to: 1.0,
delay_ms: 100,
}
}
pub fn ios_alert() -> ModalAnimation {
let spring = Spring::new()
.stiffness(350.0)
.damping(28.0)
.mass(1.0);
ModalAnimation::SpringScale {
spring,
scale_from: 0.0,
scale_to: 1.0,
opacity_from: 0.0,
opacity_to: 1.0,
}
}
pub fn ios_sheet() -> ModalAnimation {
ModalAnimation::SlideUp {
duration_ms: 500,
easing: Easing::CubicBezier(0.32, 0.72, 0.0, 1.0), translate_from: 100.0,
translate_to: 0.0,
opacity_from: 0.0,
opacity_to: 1.0,
delay_ms: 0,
}
}
pub fn vaul_drawer() -> ModalAnimation {
let spring = Spring::new()
.stiffness(300.0)
.damping(30.0)
.mass(1.0);
let decay = Some(Decay::new(0.0).friction(0.998));
ModalAnimation::DrawerSnap {
spring,
decay,
snap_points: vec![0.0, 40.0, 100.0], translate_from: 100.0,
translate_to: 0.0,
background_scale_from: 1.0,
background_scale_to: 0.95,
}
}
pub fn fade_backdrop() -> ModalAnimation {
ModalAnimation::Backdrop {
duration_ms: 200,
easing: Easing::Linear,
opacity_from: 0.0,
opacity_to: 0.5,
blur_from: 0.0,
blur_to: 0.0,
}
}
pub fn blur_backdrop() -> ModalAnimation {
ModalAnimation::Backdrop {
duration_ms: 300,
easing: Easing::EASE_OUT,
opacity_from: 0.0,
opacity_to: 0.4,
blur_from: 0.0,
blur_to: 8.0,
}
}
pub fn slide_panel_right() -> ModalAnimation {
ModalAnimation::SlideRight {
duration_ms: 300,
easing: Easing::EaseOutCubic,
translate_from: 100.0,
translate_to: 0.0,
opacity_from: 0.0,
opacity_to: 1.0,
}
}
pub fn drop_bounce() -> ModalAnimation {
ModalAnimation::DropIn {
duration_ms: 500,
easing: Easing::EaseOutBounce,
translate_from: -100.0,
translate_to: 0.0,
scale_from: 0.1,
scale_to: 1.0,
opacity_from: 0.0,
opacity_to: 1.0,
}
}
pub fn zoom_from_origin(origin_x: f64, origin_y: f64, scale_factor: f64) -> ModalAnimation {
let translate_x = origin_x * scale_factor;
let translate_y = origin_y * scale_factor;
ModalAnimation::ZoomFromOrigin {
duration_ms: 300,
easing: Easing::CubicBezier(0.4, 0.0, 0.2, 1.0), origin_x,
origin_y,
scale_from: scale_factor,
scale_to: 1.0,
translate_x_from: translate_x,
translate_x_to: 0.0,
translate_y_from: translate_y,
translate_y_to: 0.0,
opacity_from: 0.0,
opacity_to: 1.0,
}
}
pub fn curtain_reveal() -> ModalAnimation {
ModalAnimation::Curtain {
duration_ms: 400,
easing: Easing::EASE_IN_OUT,
clip_from: 0.0,
clip_to: 1.0,
opacity_from: 0.0,
opacity_to: 1.0,
}
}
pub fn framer_spring_modal() -> ModalAnimation {
let spring = Spring::new()
.stiffness(300.0)
.damping(25.0)
.mass(1.0);
ModalAnimation::SpringScale {
spring,
scale_from: 0.9,
scale_to: 1.0,
opacity_from: 0.0,
opacity_to: 1.0,
}
}
pub fn radix_fade() -> ModalAnimation {
ModalAnimation::FadeScale {
duration_ms: 300,
easing: Easing::EASE_OUT,
scale_from: 1.0,
scale_to: 1.0,
opacity_from: 0.0,
opacity_to: 1.0,
}
}
pub fn radix_fade_exit() -> ModalAnimation {
ModalAnimation::FadeScale {
duration_ms: 300,
easing: Easing::EASE_IN,
scale_from: 1.0,
scale_to: 1.0,
opacity_from: 1.0,
opacity_to: 0.0,
}
}
pub fn ios_slide_down() -> ModalAnimation {
ModalAnimation::SlideDown {
duration_ms: 400,
easing: Easing::CubicBezier(0.32, 0.72, 0.0, 1.0), translate_from: -100.0,
translate_to: 0.0,
opacity_from: 0.0,
opacity_to: 1.0,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_material_dialog_params() {
let anim = material_dialog();
assert_eq!(anim.duration_ms(), 225);
match anim {
ModalAnimation::FadeScale {
scale_from,
scale_to,
opacity_from,
opacity_to,
..
} => {
assert!((scale_from - 0.95).abs() < 0.01);
assert!((scale_to - 1.0).abs() < 0.01);
assert!((opacity_from - 0.0).abs() < 0.01);
assert!((opacity_to - 1.0).abs() < 0.01);
}
_ => panic!("Expected FadeScale"),
}
}
#[test]
fn test_ios_alert_spring() {
let anim = ios_alert();
assert!(anim.duration_ms() > 0);
match anim {
ModalAnimation::SpringScale { spring, .. } => {
assert!((spring.stiffness - 350.0).abs() < 0.1);
assert!((spring.damping - 28.0).abs() < 0.1);
}
_ => panic!("Expected SpringScale"),
}
}
#[test]
fn test_vaul_drawer_snap_points() {
let anim = vaul_drawer();
match anim {
ModalAnimation::DrawerSnap { snap_points, .. } => {
assert_eq!(snap_points.len(), 3);
assert!((snap_points[0] - 0.0).abs() < 0.01);
assert!((snap_points[1] - 40.0).abs() < 0.01);
assert!((snap_points[2] - 100.0).abs() < 0.01);
}
_ => panic!("Expected DrawerSnap"),
}
}
#[test]
fn test_blur_backdrop() {
let anim = blur_backdrop();
match anim {
ModalAnimation::Backdrop {
blur_from, blur_to, ..
} => {
assert!((blur_from - 0.0).abs() < 0.01);
assert!((blur_to - 8.0).abs() < 0.01);
}
_ => panic!("Expected Backdrop"),
}
}
#[test]
fn test_zoom_from_origin() {
let anim = zoom_from_origin(50.0, 100.0, 0.2);
match anim {
ModalAnimation::ZoomFromOrigin {
scale_from,
scale_to,
translate_x_from,
translate_y_from,
..
} => {
assert!((scale_from - 0.2).abs() < 0.01);
assert!((scale_to - 1.0).abs() < 0.01);
assert!((translate_x_from - 10.0).abs() < 0.01); assert!((translate_y_from - 20.0).abs() < 0.01); }
_ => panic!("Expected ZoomFromOrigin"),
}
}
#[test]
fn test_all_presets_compile() {
let _ = material_dialog();
let _ = material_dialog_exit();
let _ = material_bottom_sheet();
let _ = ios_alert();
let _ = ios_sheet();
let _ = vaul_drawer();
let _ = fade_backdrop();
let _ = blur_backdrop();
let _ = slide_panel_right();
let _ = drop_bounce();
let _ = zoom_from_origin(0.0, 0.0, 0.5);
let _ = curtain_reveal();
let _ = framer_spring_modal();
let _ = radix_fade();
let _ = radix_fade_exit();
let _ = ios_slide_down();
}
}