use std::collections::BTreeMap;
use serde::Deserialize;
pub type SharedId = u32;
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum Driver {
Timing {
to: f32,
#[serde(default = "default_duration")]
duration: f32,
#[serde(default)]
easing: Easing,
},
Spring {
to: f32,
#[serde(default = "default_stiffness")]
stiffness: f32,
#[serde(default = "default_damping")]
damping: f32,
#[serde(default = "default_mass")]
mass: f32,
},
Repeat {
animation: Box<Driver>,
#[serde(default = "default_count")]
count: i32,
#[serde(default)]
reverse: bool,
},
Sequence { steps: Vec<Driver> },
Delay { delay: f32, animation: Box<Driver> },
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum Easing {
#[default]
Linear,
EaseIn,
EaseOut,
EaseInOut,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "kind", rename_all = "camelCase")]
pub enum AnimationCommand {
Declare { id: SharedId, initial: f32 },
Set { id: SharedId, value: f32 },
Animate {
id: SharedId,
driver: Driver,
#[serde(default)]
token: Option<u64>,
},
Cancel { id: SharedId },
Clear,
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum Binding {
Shared { id: SharedId },
Interpolate {
id: SharedId,
input: Vec<f32>,
output: Vec<f32>,
},
InterpolateColor {
id: SharedId,
input: Vec<f32>,
output: Vec<[f32; 4]>,
},
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum AnimatableProperty {
TranslateX,
TranslateY,
Scale,
ScaleX,
ScaleY,
Rotate,
Opacity,
BackgroundColor,
BorderColor,
Color,
BackgroundImageTint,
Width,
Height,
MinWidth,
MinHeight,
MaxWidth,
MaxHeight,
Left,
Right,
Top,
Bottom,
FlexBasis,
Gap,
RowGap,
ColumnGap,
AspectRatio,
FilterParam {
index: u8,
name: String,
},
BackdropParam {
index: u8,
name: String,
},
MorphParam {
name: String,
},
ShapeAttr {
name: String,
},
Transform3d(Transform3dField),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Transform3dField {
Perspective,
TranslateX,
TranslateY,
TranslateZ,
RotateX,
RotateY,
RotateZ,
Scale,
ScaleX,
ScaleY,
OriginX,
OriginY,
}
impl AnimatableProperty {
#[allow(unused_parens)]
pub fn value_kind(&self) -> ValueKind {
use AnimatableProperty as P;
use Transform3dField as F;
macro_rules! kind_arms {
($(($prop:tt, $kind:ident, $acc:tt, $write:tt, $stage:ident, $park:ident),)*) => {
match self {
$($prop => ValueKind::$kind,)*
Self::FilterParam { .. }
| Self::BackdropParam { .. }
| Self::MorphParam { .. } => ValueKind::Scalar,
Self::ShapeAttr { .. } => ValueKind::Scalar,
}
};
}
crate::animations::props::with_animatable_props!(kind_arms)
}
pub fn is_transform(&self) -> bool {
self.stage() == crate::animations::props::PropStage::Transform
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValueKind {
Scalar,
Length,
Color,
Angle,
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct AnimatedBindings(pub BTreeMap<AnimatableProperty, Binding>);
impl AnimatedBindings {
pub fn get(&self, property: AnimatableProperty) -> Option<&Binding> {
self.0.get(&property)
}
pub fn contains(&self, property: AnimatableProperty) -> bool {
self.0.contains_key(&property)
}
fn has_stage(&self, stage: crate::animations::props::PropStage) -> bool {
self.0.keys().any(|p| p.stage() == stage)
}
pub fn has_transform(&self) -> bool {
self.has_stage(crate::animations::props::PropStage::Transform)
}
pub fn has_filter_params(&self) -> bool {
self.has_stage(crate::animations::props::PropStage::Filter)
}
pub fn has_backdrop_params(&self) -> bool {
self.has_stage(crate::animations::props::PropStage::Backdrop)
}
pub fn has_morph_params(&self) -> bool {
self.has_stage(crate::animations::props::PropStage::Morph)
}
pub fn has_shape_attrs(&self) -> bool {
self.has_stage(crate::animations::props::PropStage::Shape)
}
pub fn has_transform3d(&self) -> bool {
self.has_stage(crate::animations::props::PropStage::Transform3d)
}
pub fn iter(&self) -> impl Iterator<Item = (&AnimatableProperty, &Binding)> {
self.0.iter()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
fn default_duration() -> f32 {
0.3
}
fn default_stiffness() -> f32 {
100.0
}
fn default_damping() -> f32 {
10.0
}
fn default_mass() -> f32 {
1.0
}
fn default_count() -> i32 {
1
}