vizia_core/systems/
animation.rs
1use morphorm::Node;
2
3use crate::{layout::node::SubLayout, prelude::*};
4
5macro_rules! process_auto_animations {
6 ($cx:expr, $property:expr, $height:expr) => {
7 if let Some(animations) = $property.get_active_animations() {
8 let mut entities = vec![];
9
10 for animation in animations {
11 if animation.keyframes.iter().any(|keyframe| keyframe.value == Units::Auto) {
12 for entity in animation.entities.iter() {
13 entities.push((*entity, animation.clone()));
14 }
15 }
16 }
17
18 for (entity, mut animation) in entities {
19 $property.stop_animation(entity, animation.id);
20 $property.insert(entity, Units::Auto);
21
22 let size = entity.layout(
23 &mut $cx.cache,
24 &$cx.tree,
25 &$cx.style,
26 &mut SubLayout {
27 text_context: &mut $cx.text_context,
28 resource_manager: &$cx.resource_manager,
29 },
30 );
31
32 $property.remove(entity);
33 animation.keyframes.iter_mut().for_each(|keyframe| {
34 if keyframe.value == Units::Auto {
35 let parent = $cx.tree.get_parent(entity).unwrap_or(Entity::root());
36 let parent_layout_type =
37 $cx.style.layout_type.get(parent).copied().unwrap_or_default();
38 let value = if (parent_layout_type == LayoutType::Row) == $height {
39 size.cross
40 } else {
41 size.main
42 };
43 keyframe.value = Units::Pixels(value);
44 }
45 });
46
47 let id = $cx.style.animation_manager.create();
48 $property.insert_animation(id, animation.clone());
49 $property.play_animation(
50 entity,
51 id,
52 animation.start_time,
53 animation.duration,
54 animation.delay,
55 );
56 }
57 }
58 };
59}
60
61pub(crate) fn animation_system(cx: &mut Context) -> bool {
62 cx.style.play_pending_animations();
63
64 process_auto_animations!(cx, cx.style.max_height, true);
65 process_auto_animations!(cx, cx.style.max_width, false);
66 process_auto_animations!(cx, cx.style.height, true);
67 process_auto_animations!(cx, cx.style.width, false);
68
69 let time = Instant::now();
116
117 let mut redraw_entities = Vec::new();
118 let mut reflow_entities = Vec::new();
119 let mut relayout_entities = Vec::new();
120
121 redraw_entities.extend(cx.style.opacity.tick(time));
124 redraw_entities.extend(cx.style.border_color.tick(time));
126 redraw_entities.extend(cx.style.corner_top_left_radius.tick(time));
128 redraw_entities.extend(cx.style.corner_top_right_radius.tick(time));
129 redraw_entities.extend(cx.style.corner_bottom_left_radius.tick(time));
130 redraw_entities.extend(cx.style.corner_bottom_right_radius.tick(time));
131 redraw_entities.extend(cx.style.background_color.tick(time));
133 redraw_entities.extend(cx.style.background_image.tick(time));
134 redraw_entities.extend(cx.style.background_size.tick(time));
135 redraw_entities.extend(cx.style.shadow.tick(time));
137 redraw_entities.extend(cx.style.transform.tick(time));
139 redraw_entities.extend(cx.style.transform_origin.tick(time));
140 redraw_entities.extend(cx.style.translate.tick(time));
141 redraw_entities.extend(cx.style.rotate.tick(time));
142 redraw_entities.extend(cx.style.scale.tick(time));
143 redraw_entities.extend(cx.style.outline_color.tick(time));
145 redraw_entities.extend(cx.style.outline_offset.tick(time));
146 redraw_entities.extend(cx.style.outline_width.tick(time));
147 redraw_entities.extend(cx.style.clip_path.tick(time));
149
150 redraw_entities.extend(cx.style.fill.tick(time));
151
152 reflow_entities.extend(cx.style.font_color.tick(time));
154 reflow_entities.extend(cx.style.font_size.tick(time));
156
157 relayout_entities.extend(cx.style.display.tick(time));
159 relayout_entities.extend(cx.style.border_width.tick(time));
161 relayout_entities.extend(cx.style.left.tick(time));
163 relayout_entities.extend(cx.style.right.tick(time));
164 relayout_entities.extend(cx.style.top.tick(time));
165 relayout_entities.extend(cx.style.bottom.tick(time));
166 relayout_entities.extend(cx.style.width.tick(time));
168 relayout_entities.extend(cx.style.height.tick(time));
169 relayout_entities.extend(cx.style.max_width.tick(time));
171 relayout_entities.extend(cx.style.max_height.tick(time));
172 relayout_entities.extend(cx.style.min_width.tick(time));
173 relayout_entities.extend(cx.style.min_height.tick(time));
174 relayout_entities.extend(cx.style.max_horizontal_gap.tick(time));
176 relayout_entities.extend(cx.style.max_vertical_gap.tick(time));
177 relayout_entities.extend(cx.style.min_horizontal_gap.tick(time));
178 relayout_entities.extend(cx.style.min_vertical_gap.tick(time));
179 relayout_entities.extend(cx.style.vertical_gap.tick(time));
181 relayout_entities.extend(cx.style.horizontal_gap.tick(time));
182 relayout_entities.extend(cx.style.padding_left.tick(time));
184 relayout_entities.extend(cx.style.padding_right.tick(time));
185 relayout_entities.extend(cx.style.padding_top.tick(time));
186 relayout_entities.extend(cx.style.padding_bottom.tick(time));
187
188 if !relayout_entities.is_empty() {
189 cx.style.system_flags.set(SystemFlags::RELAYOUT, true);
190 }
191
192 for entity in redraw_entities.iter() {
193 cx.needs_redraw(*entity);
194 }
195
196 for entity in reflow_entities.iter() {
197 cx.style.text_construction.insert(*entity).unwrap();
198 }
199
200 !redraw_entities.is_empty() | !relayout_entities.is_empty() | !reflow_entities.is_empty()
201}