freya_animation/
anim_color.rs1use std::time::Duration;
2
3use freya_core::prelude::Color;
4
5use crate::{
6 easing::{
7 Function,
8 apply_value,
9 },
10 hook::{
11 AnimDirection,
12 AnimatedValue,
13 Ease,
14 ReadAnimatedValue,
15 },
16};
17
18#[derive(Clone, PartialEq, Default)]
20pub struct AnimColor {
21 origin: Color,
22 destination: Color,
23 time: Duration,
24 ease: Ease,
25 function: Function,
26
27 value: Color,
28}
29
30impl AnimColor {
31 pub fn new(origin: impl Into<Color>, destination: impl Into<Color>) -> Self {
32 let origin = origin.into();
33 Self {
34 origin,
35 destination: destination.into(),
36 time: Duration::default(),
37 ease: Ease::default(),
38 function: Function::default(),
39
40 value: origin,
41 }
42 }
43
44 pub fn time(mut self, time: u64) -> Self {
46 self.time = Duration::from_millis(time);
47 self
48 }
49
50 pub fn duration(mut self, duration: Duration) -> Self {
52 self.time = duration;
53 self
54 }
55
56 pub fn ease(mut self, ease: Ease) -> Self {
58 self.ease = ease;
59 self
60 }
61
62 pub fn function(mut self, function: Function) -> Self {
64 self.function = function;
65 self
66 }
67
68 pub fn value(&self) -> Color {
70 self.value
71 }
72}
73
74impl From<&AnimColor> for Color {
75 fn from(value: &AnimColor) -> Self {
76 value.value()
77 }
78}
79
80impl AnimatedValue for AnimColor {
81 fn prepare(&mut self, direction: AnimDirection) {
82 match direction {
83 AnimDirection::Forward => self.value = self.origin,
84 AnimDirection::Reverse => {
85 self.value = self.destination;
86 }
87 }
88 }
89
90 fn is_finished(&self, index: u128, direction: AnimDirection) -> bool {
91 match direction {
92 AnimDirection::Forward => {
93 index >= self.time.as_millis()
94 && self.value.r() == self.destination.r()
95 && self.value.g() == self.destination.g()
96 && self.value.b() == self.destination.b()
97 && self.value.a() == self.destination.a()
98 }
99 AnimDirection::Reverse => {
100 index >= self.time.as_millis()
101 && self.value.r() == self.origin.r()
102 && self.value.g() == self.origin.g()
103 && self.value.b() == self.origin.b()
104 && self.value.a() == self.origin.a()
105 }
106 }
107 }
108
109 fn advance(&mut self, index: u128, direction: AnimDirection) {
110 let (origin, destination) = match direction {
111 AnimDirection::Forward => (self.origin, self.destination),
112 AnimDirection::Reverse => (self.destination, self.origin),
113 };
114 let r = apply_value(
115 origin.r() as f32,
116 destination.r() as f32,
117 index.min(self.time.as_millis()),
118 self.time,
119 self.ease,
120 self.function,
121 );
122 let g = apply_value(
123 origin.g() as f32,
124 destination.g() as f32,
125 index.min(self.time.as_millis()),
126 self.time,
127 self.ease,
128 self.function,
129 );
130 let b = apply_value(
131 origin.b() as f32,
132 destination.b() as f32,
133 index.min(self.time.as_millis()),
134 self.time,
135 self.ease,
136 self.function,
137 );
138 let a = apply_value(
139 origin.a() as f32,
140 destination.a() as f32,
141 index.min(self.time.as_millis()),
142 self.time,
143 self.ease,
144 self.function,
145 );
146 self.value = Color::from_argb(a as u8, r as u8, g as u8, b as u8);
147 }
148
149 fn finish(&mut self, direction: AnimDirection) {
150 self.advance(self.time.as_millis(), direction);
151 }
152
153 fn into_reversed(self) -> Self {
155 Self {
156 origin: self.destination,
157 destination: self.origin,
158 ..self
159 }
160 }
161}
162
163impl ReadAnimatedValue for AnimColor {
164 type Output = Color;
165 fn value(&self) -> Self::Output {
166 self.value()
167 }
168}