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