Skip to main content

miracle_plugin/
animation.rs

1use crate::bindings;
2use crate::core::{Rect, mat4_from_f32_array, mat4_to_f32_array};
3use glam::Mat4;
4
5/// Raw C-layout struct for the `custom_animate` WASM export's input.
6///
7/// This matches the `CustomAnimationFrameData` struct written by the host.
8#[repr(C)]
9pub struct RawCustomAnimationData {
10    pub animation_id: u32,
11    pub dt: f32,
12    pub elapsed_seconds: f32,
13}
14
15pub struct AnimationFrameData {
16    pub runtime_seconds: f32,
17    pub duration_seconds: f32,
18    pub origin: Rect,
19    pub destination: Rect,
20    pub opacity_start: f32,
21    pub opacity_end: f32,
22}
23
24impl From<bindings::miracle_plugin_animation_frame_data_t> for AnimationFrameData {
25    fn from(value: bindings::miracle_plugin_animation_frame_data_t) -> Self {
26        Self {
27            runtime_seconds: value.runtime_seconds,
28            duration_seconds: value.duration_seconds,
29            origin: Rect::from_array(value.origin),
30            destination: Rect::from_array(value.destination),
31            opacity_start: value.opacity_start,
32            opacity_end: value.opacity_end,
33        }
34    }
35}
36
37pub struct AnimationFrameResult {
38    pub completed: bool,
39    pub area: Option<Rect>,
40    pub transform: Option<Mat4>,
41    pub opacity: Option<f32>,
42}
43
44impl From<AnimationFrameResult> for bindings::miracle_plugin_animation_frame_result_t {
45    fn from(value: AnimationFrameResult) -> Self {
46        Self {
47            completed: value.completed as i32,
48            has_area: value.area.is_some() as i32,
49            area: value.area.map(|r| r.to_array()).unwrap_or_default(),
50            has_transform: value.transform.is_some() as i32,
51            transform: value.transform.map(mat4_to_f32_array).unwrap_or_default(),
52            has_opacity: value.opacity.is_some() as i32,
53            opacity: value.opacity.unwrap_or_default(),
54        }
55    }
56}
57
58impl From<bindings::miracle_plugin_animation_frame_result_t> for AnimationFrameResult {
59    fn from(value: bindings::miracle_plugin_animation_frame_result_t) -> Self {
60        Self {
61            completed: value.completed != 0,
62            area: if value.has_area != 0 {
63                Some(Rect::from_array(value.area))
64            } else {
65                None
66            },
67            transform: if value.has_transform != 0 {
68                Some(mat4_from_f32_array(value.transform))
69            } else {
70                None
71            },
72            opacity: if value.has_opacity != 0 {
73                Some(value.opacity)
74            } else {
75                None
76            },
77        }
78    }
79}