pub struct Animation { /* private fields */ }Expand description
Small time-based animation helper.
Implementations§
Source§impl Animation
impl Animation
Sourcepub const fn new(duration_ms: u32, curve: Curve) -> Self
pub const fn new(duration_ms: u32, curve: Curve) -> Self
Creates a new animation with a duration and easing curve.
Examples found in repository?
src/modal.rs (line 34)
31 pub fn show(&mut self, modal: M) {
32 self.state = ModalState::Showing {
33 modal,
34 animation: Animation::new(MODAL_ANIMATION_MS, Curve::EaseInOut),
35 };
36 }
37
38 /// Starts dismissing the current modal, if any.
39 pub fn dismiss(&mut self) {
40 let modal = match self.state {
41 ModalState::Showing { modal, .. } | ModalState::Visible { modal } => Some(modal),
42 ModalState::Hiding { modal, .. } => Some(modal),
43 ModalState::Hidden => None,
44 };
45
46 if let Some(modal) = modal {
47 self.state = ModalState::Hiding {
48 modal,
49 animation: Animation::new(MODAL_ANIMATION_MS, Curve::EaseInOut),
50 };
51 }
52 }More examples
src/stack.rs (line 123)
113 pub fn push(&mut self, key: K) -> Result<(), StackError> {
114 if self.transition.is_some() {
115 return Err(StackError::Busy);
116 }
117
118 let from = self.top();
119 self.stack.push(key).map_err(|_| StackError::Full)?;
120 self.transition = Some(Transition::Push {
121 from,
122 to: key,
123 animation: Animation::new(STACK_ANIMATION_MS, Curve::EaseInOut),
124 });
125 Ok(())
126 }
127
128 /// Pops the current view and starts a transition.
129 pub fn pop(&mut self) -> Result<K, StackError> {
130 if self.transition.is_some() {
131 return Err(StackError::Busy);
132 }
133 if self.stack.len() <= 1 {
134 return Err(StackError::RootLocked);
135 }
136
137 let from = self.stack.pop().ok_or(StackError::RootLocked)?;
138 let to = self.top();
139 self.transition = Some(Transition::Pop {
140 from,
141 to,
142 animation: Animation::new(STACK_ANIMATION_MS, Curve::EaseInOut),
143 });
144 Ok(from)
145 }Sourcepub const fn is_running(&self) -> bool
pub const fn is_running(&self) -> bool
Returns true while the animation is still progressing.
Examples found in repository?
More examples
src/stack.rs (line 155)
148 pub fn advance(&mut self, dt_ms: u32) -> bool {
149 let Some(mut transition) = self.transition.take() else {
150 return false;
151 };
152
153 let was_running = match &transition {
154 Transition::Push { animation, .. } | Transition::Pop { animation, .. } => {
155 animation.is_running()
156 }
157 };
158 let is_running = match &mut transition {
159 Transition::Push { animation, .. } | Transition::Pop { animation, .. } => {
160 animation.advance(dt_ms)
161 }
162 };
163
164 if is_running {
165 self.transition = Some(transition);
166 }
167
168 was_running
169 }src/modal.rs (line 72)
68 pub fn advance(&mut self, dt_ms: u32) -> bool {
69 match &mut self.state {
70 ModalState::Hidden | ModalState::Visible { .. } => false,
71 ModalState::Showing { modal, animation } => {
72 let was_running = animation.is_running();
73 let is_running = animation.advance(dt_ms);
74 if is_running {
75 true
76 } else {
77 self.state = ModalState::Visible { modal: *modal };
78 was_running
79 }
80 }
81 ModalState::Hiding { animation, .. } => {
82 let was_running = animation.is_running();
83 let is_running = animation.advance(dt_ms);
84 if is_running {
85 true
86 } else {
87 self.state = ModalState::Hidden;
88 was_running
89 }
90 }
91 }
92 }Sourcepub const fn is_finished(&self) -> bool
pub const fn is_finished(&self) -> bool
Returns true once the animation has completed.
Sourcepub fn advance(&mut self, dt_ms: u32) -> bool
pub fn advance(&mut self, dt_ms: u32) -> bool
Advances the animation by dt_ms.
Examples found in repository?
src/stack.rs (line 160)
148 pub fn advance(&mut self, dt_ms: u32) -> bool {
149 let Some(mut transition) = self.transition.take() else {
150 return false;
151 };
152
153 let was_running = match &transition {
154 Transition::Push { animation, .. } | Transition::Pop { animation, .. } => {
155 animation.is_running()
156 }
157 };
158 let is_running = match &mut transition {
159 Transition::Push { animation, .. } | Transition::Pop { animation, .. } => {
160 animation.advance(dt_ms)
161 }
162 };
163
164 if is_running {
165 self.transition = Some(transition);
166 }
167
168 was_running
169 }More examples
src/modal.rs (line 73)
68 pub fn advance(&mut self, dt_ms: u32) -> bool {
69 match &mut self.state {
70 ModalState::Hidden | ModalState::Visible { .. } => false,
71 ModalState::Showing { modal, animation } => {
72 let was_running = animation.is_running();
73 let is_running = animation.advance(dt_ms);
74 if is_running {
75 true
76 } else {
77 self.state = ModalState::Visible { modal: *modal };
78 was_running
79 }
80 }
81 ModalState::Hiding { animation, .. } => {
82 let was_running = animation.is_running();
83 let is_running = animation.advance(dt_ms);
84 if is_running {
85 true
86 } else {
87 self.state = ModalState::Hidden;
88 was_running
89 }
90 }
91 }
92 }Sourcepub fn progress_permille(&self) -> u16
pub fn progress_permille(&self) -> u16
Returns eased progress in the 0..=1000 permille range.
Examples found in repository?
src/stack.rs (line 98)
88 pub(crate) fn header_transition(&self) -> Option<HeaderTransition<K>> {
89 match self.transition {
90 None => None,
91 Some(Transition::Push {
92 from,
93 to,
94 animation,
95 }) => Some(HeaderTransition::Push {
96 from,
97 to,
98 progress: animation.progress_permille(),
99 }),
100 Some(Transition::Pop {
101 from,
102 to,
103 animation,
104 }) => Some(HeaderTransition::Pop {
105 from,
106 to,
107 progress: animation.progress_permille(),
108 }),
109 }
110 }
111
112 /// Pushes `key` and starts a transition.
113 pub fn push(&mut self, key: K) -> Result<(), StackError> {
114 if self.transition.is_some() {
115 return Err(StackError::Busy);
116 }
117
118 let from = self.top();
119 self.stack.push(key).map_err(|_| StackError::Full)?;
120 self.transition = Some(Transition::Push {
121 from,
122 to: key,
123 animation: Animation::new(STACK_ANIMATION_MS, Curve::EaseInOut),
124 });
125 Ok(())
126 }
127
128 /// Pops the current view and starts a transition.
129 pub fn pop(&mut self) -> Result<K, StackError> {
130 if self.transition.is_some() {
131 return Err(StackError::Busy);
132 }
133 if self.stack.len() <= 1 {
134 return Err(StackError::RootLocked);
135 }
136
137 let from = self.stack.pop().ok_or(StackError::RootLocked)?;
138 let to = self.top();
139 self.transition = Some(Transition::Pop {
140 from,
141 to,
142 animation: Animation::new(STACK_ANIMATION_MS, Curve::EaseInOut),
143 });
144 Ok(from)
145 }
146
147 /// Advances the active transition, if any.
148 pub fn advance(&mut self, dt_ms: u32) -> bool {
149 let Some(mut transition) = self.transition.take() else {
150 return false;
151 };
152
153 let was_running = match &transition {
154 Transition::Push { animation, .. } | Transition::Pop { animation, .. } => {
155 animation.is_running()
156 }
157 };
158 let is_running = match &mut transition {
159 Transition::Push { animation, .. } | Transition::Pop { animation, .. } => {
160 animation.advance(dt_ms)
161 }
162 };
163
164 if is_running {
165 self.transition = Some(transition);
166 }
167
168 was_running
169 }
170
171 /// Returns the base and overlay layers for a frame.
172 pub fn layers(&self, frame: Rectangle) -> StackLayers<K> {
173 let width = frame.size.width as i32;
174 let idle = Layer::new(self.top(), frame, Point::zero());
175
176 match self.transition {
177 None => StackLayers {
178 base: idle,
179 overlay: None,
180 },
181 Some(Transition::Push {
182 from,
183 to,
184 animation,
185 }) => {
186 let progress = animation.progress_permille();
187 let base = Layer::new(from, frame, Point::zero());
188 let overlay = Layer::new(to, frame, Point::new(lerp_i32(width, 0, progress), 0));
189 StackLayers {
190 base,
191 overlay: Some(overlay),
192 }
193 }
194 Some(Transition::Pop {
195 from,
196 to,
197 animation,
198 }) => {
199 let progress = animation.progress_permille();
200 let base = Layer::new(to, frame, Point::zero());
201 let overlay = Layer::new(from, frame, Point::new(lerp_i32(0, width, progress), 0));
202 StackLayers {
203 base,
204 overlay: Some(overlay),
205 }
206 }
207 }
208 }More examples
src/modal.rs (line 107)
100 pub fn current_with_panel(&self, bounds: Rectangle, panel: Rectangle) -> Option<ModalLayer<M>> {
101 let offscreen = offscreen_offset(bounds, panel);
102
103 match self.state {
104 ModalState::Hidden => None,
105 ModalState::Visible { modal } => Some(ModalLayer::new(modal, panel, 0, DIM_ALPHA_MAX)),
106 ModalState::Showing { modal, animation } => {
107 let progress = animation.progress_permille();
108 Some(ModalLayer::new(
109 modal,
110 panel,
111 lerp_i32(offscreen, 0, progress),
112 lerp_u8(0, DIM_ALPHA_MAX, progress),
113 ))
114 }
115 ModalState::Hiding { modal, animation } => {
116 let progress = animation.progress_permille();
117 Some(ModalLayer::new(
118 modal,
119 panel,
120 lerp_i32(0, offscreen, progress),
121 lerp_u8(DIM_ALPHA_MAX, 0, progress),
122 ))
123 }
124 }
125 }Trait Implementations§
impl Copy for Animation
impl Eq for Animation
impl StructuralPartialEq for Animation
Auto Trait Implementations§
impl Freeze for Animation
impl RefUnwindSafe for Animation
impl Send for Animation
impl Sync for Animation
impl Unpin for Animation
impl UnsafeUnpin for Animation
impl UnwindSafe for Animation
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CheckedAs for T
impl<T> CheckedAs for T
Source§fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
Casts the value.
Source§impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
Source§fn checked_cast_from(src: Src) -> Option<Dst>
fn checked_cast_from(src: Src) -> Option<Dst>
Casts the value.
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> OverflowingAs for T
impl<T> OverflowingAs for T
Source§fn overflowing_as<Dst>(self) -> (Dst, bool)where
T: OverflowingCast<Dst>,
fn overflowing_as<Dst>(self) -> (Dst, bool)where
T: OverflowingCast<Dst>,
Casts the value.
Source§impl<Src, Dst> OverflowingCastFrom<Src> for Dstwhere
Src: OverflowingCast<Dst>,
impl<Src, Dst> OverflowingCastFrom<Src> for Dstwhere
Src: OverflowingCast<Dst>,
Source§fn overflowing_cast_from(src: Src) -> (Dst, bool)
fn overflowing_cast_from(src: Src) -> (Dst, bool)
Casts the value.
Source§impl<T> SaturatingAs for T
impl<T> SaturatingAs for T
Source§fn saturating_as<Dst>(self) -> Dstwhere
T: SaturatingCast<Dst>,
fn saturating_as<Dst>(self) -> Dstwhere
T: SaturatingCast<Dst>,
Casts the value.
Source§impl<Src, Dst> SaturatingCastFrom<Src> for Dstwhere
Src: SaturatingCast<Dst>,
impl<Src, Dst> SaturatingCastFrom<Src> for Dstwhere
Src: SaturatingCast<Dst>,
Source§fn saturating_cast_from(src: Src) -> Dst
fn saturating_cast_from(src: Src) -> Dst
Casts the value.
Source§impl<T> UnwrappedAs for T
impl<T> UnwrappedAs for T
Source§fn unwrapped_as<Dst>(self) -> Dstwhere
T: UnwrappedCast<Dst>,
fn unwrapped_as<Dst>(self) -> Dstwhere
T: UnwrappedCast<Dst>,
Casts the value.
Source§impl<Src, Dst> UnwrappedCastFrom<Src> for Dstwhere
Src: UnwrappedCast<Dst>,
impl<Src, Dst> UnwrappedCastFrom<Src> for Dstwhere
Src: UnwrappedCast<Dst>,
Source§fn unwrapped_cast_from(src: Src) -> Dst
fn unwrapped_cast_from(src: Src) -> Dst
Casts the value.
Source§impl<T> WrappingAs for T
impl<T> WrappingAs for T
Source§fn wrapping_as<Dst>(self) -> Dstwhere
T: WrappingCast<Dst>,
fn wrapping_as<Dst>(self) -> Dstwhere
T: WrappingCast<Dst>,
Casts the value.
Source§impl<Src, Dst> WrappingCastFrom<Src> for Dstwhere
Src: WrappingCast<Dst>,
impl<Src, Dst> WrappingCastFrom<Src> for Dstwhere
Src: WrappingCast<Dst>,
Source§fn wrapping_cast_from(src: Src) -> Dst
fn wrapping_cast_from(src: Src) -> Dst
Casts the value.