dioxus_html/events/
animation.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use dioxus_core::Event;

pub type AnimationEvent = Event<AnimationData>;

pub struct AnimationData {
    inner: Box<dyn HasAnimationData>,
}

impl AnimationData {
    /// Create a new AnimationData
    pub fn new(inner: impl HasAnimationData + 'static) -> Self {
        Self {
            inner: Box::new(inner),
        }
    }

    /// The name of the animation
    pub fn animation_name(&self) -> String {
        self.inner.animation_name()
    }

    /// The name of the pseudo-element the animation runs on
    pub fn pseudo_element(&self) -> String {
        self.inner.pseudo_element()
    }

    /// The amount of time the animation has been running
    pub fn elapsed_time(&self) -> f32 {
        self.inner.elapsed_time()
    }

    /// Downcast this event to a concrete event type
    #[inline(always)]
    pub fn downcast<T: 'static>(&self) -> Option<&T> {
        self.inner.as_ref().as_any().downcast_ref::<T>()
    }
}

impl<E: HasAnimationData> From<E> for AnimationData {
    fn from(e: E) -> Self {
        Self { inner: Box::new(e) }
    }
}

impl std::fmt::Debug for AnimationData {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("AnimationData")
            .field("animation_name", &self.animation_name())
            .field("pseudo_element", &self.pseudo_element())
            .field("elapsed_time", &self.elapsed_time())
            .finish()
    }
}

impl PartialEq for AnimationData {
    fn eq(&self, other: &Self) -> bool {
        self.animation_name() == other.animation_name()
            && self.pseudo_element() == other.pseudo_element()
            && self.elapsed_time() == other.elapsed_time()
    }
}

#[cfg(feature = "serialize")]
/// A serialized version of AnimationData
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
pub struct SerializedAnimationData {
    animation_name: String,
    pseudo_element: String,
    elapsed_time: f32,
}

#[cfg(feature = "serialize")]
impl From<&AnimationData> for SerializedAnimationData {
    fn from(data: &AnimationData) -> Self {
        Self {
            animation_name: data.animation_name(),
            pseudo_element: data.pseudo_element(),
            elapsed_time: data.elapsed_time(),
        }
    }
}

#[cfg(feature = "serialize")]
impl HasAnimationData for SerializedAnimationData {
    fn animation_name(&self) -> String {
        self.animation_name.clone()
    }

    fn pseudo_element(&self) -> String {
        self.pseudo_element.clone()
    }

    fn elapsed_time(&self) -> f32 {
        self.elapsed_time
    }

    fn as_any(&self) -> &dyn std::any::Any {
        self
    }
}

#[cfg(feature = "serialize")]
impl serde::Serialize for AnimationData {
    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        SerializedAnimationData::from(self).serialize(serializer)
    }
}

#[cfg(feature = "serialize")]
impl<'de> serde::Deserialize<'de> for AnimationData {
    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        let data = SerializedAnimationData::deserialize(deserializer)?;
        Ok(Self {
            inner: Box::new(data),
        })
    }
}

/// A trait for any object that has the data for an animation event
pub trait HasAnimationData: std::any::Any {
    /// The name of the animation
    fn animation_name(&self) -> String;

    /// The name of the pseudo-element the animation runs on
    fn pseudo_element(&self) -> String;

    /// The amount of time the animation has been running
    fn elapsed_time(&self) -> f32;

    /// return self as Any
    fn as_any(&self) -> &dyn std::any::Any;
}

impl_event! [
    AnimationData;

    /// onanimationstart
    onanimationstart

    /// onanimationend
    onanimationend

    /// onanimationiteration
    onanimationiteration
];