Extract animations into a subcrate
This commit is contained in:
parent
911bc97b69
commit
288cecc92f
|
@ -0,0 +1,121 @@
|
||||||
|
use fixed::types::U16F0;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
calculate_frames, Animation, BodyPattern, DashboardPattern, Fade, FadeDirection, Instant, BLINKER_FRAMES, LEFT_BLINKER_BODY, LEFT_BLINKER_DASHBOARD, OFF_BODY, OFF_DASHBOARD, RIGHT_BLINKER_BODY, RIGHT_BLINKER_DASHBOARD
|
||||||
|
};
|
||||||
|
|
||||||
|
pub enum BlinkerDirection {
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Blinker {
|
||||||
|
transition: Fade,
|
||||||
|
fade_in: Fade,
|
||||||
|
fade_out: Fade,
|
||||||
|
direction: FadeDirection,
|
||||||
|
|
||||||
|
start_time: Instant,
|
||||||
|
frames: U16F0,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Blinker {
|
||||||
|
pub fn new(
|
||||||
|
starting_dashboard: DashboardPattern,
|
||||||
|
starting_body: BodyPattern,
|
||||||
|
direction: BlinkerDirection,
|
||||||
|
time: Instant,
|
||||||
|
) -> Self {
|
||||||
|
let mut ending_dashboard = OFF_DASHBOARD.clone();
|
||||||
|
|
||||||
|
match direction {
|
||||||
|
BlinkerDirection::Left => {
|
||||||
|
ending_dashboard[0].r = LEFT_BLINKER_DASHBOARD[0].r;
|
||||||
|
ending_dashboard[0].g = LEFT_BLINKER_DASHBOARD[0].g;
|
||||||
|
ending_dashboard[0].b = LEFT_BLINKER_DASHBOARD[0].b;
|
||||||
|
}
|
||||||
|
BlinkerDirection::Right => {
|
||||||
|
ending_dashboard[2].r = RIGHT_BLINKER_DASHBOARD[2].r;
|
||||||
|
ending_dashboard[2].g = RIGHT_BLINKER_DASHBOARD[2].g;
|
||||||
|
ending_dashboard[2].b = RIGHT_BLINKER_DASHBOARD[2].b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ending_body = OFF_BODY.clone();
|
||||||
|
match direction {
|
||||||
|
BlinkerDirection::Left => {
|
||||||
|
for i in 0..30 {
|
||||||
|
ending_body[i].r = LEFT_BLINKER_BODY[i].r;
|
||||||
|
ending_body[i].g = LEFT_BLINKER_BODY[i].g;
|
||||||
|
ending_body[i].b = LEFT_BLINKER_BODY[i].b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BlinkerDirection::Right => {
|
||||||
|
for i in 30..60 {
|
||||||
|
ending_body[i].r = RIGHT_BLINKER_BODY[i].r;
|
||||||
|
ending_body[i].g = RIGHT_BLINKER_BODY[i].g;
|
||||||
|
ending_body[i].b = RIGHT_BLINKER_BODY[i].b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Blinker {
|
||||||
|
transition: Fade::new(
|
||||||
|
starting_dashboard.clone(),
|
||||||
|
starting_body.clone(),
|
||||||
|
ending_dashboard.clone(),
|
||||||
|
ending_body.clone(),
|
||||||
|
BLINKER_FRAMES,
|
||||||
|
time,
|
||||||
|
),
|
||||||
|
fade_in: Fade::new(
|
||||||
|
OFF_DASHBOARD.clone(),
|
||||||
|
OFF_BODY.clone(),
|
||||||
|
ending_dashboard.clone(),
|
||||||
|
ending_body.clone(),
|
||||||
|
BLINKER_FRAMES,
|
||||||
|
time,
|
||||||
|
),
|
||||||
|
fade_out: Fade::new(
|
||||||
|
ending_dashboard.clone(),
|
||||||
|
ending_body.clone(),
|
||||||
|
OFF_DASHBOARD.clone(),
|
||||||
|
OFF_BODY.clone(),
|
||||||
|
BLINKER_FRAMES,
|
||||||
|
time,
|
||||||
|
),
|
||||||
|
direction: FadeDirection::Transition,
|
||||||
|
start_time: time,
|
||||||
|
frames: BLINKER_FRAMES,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animation for Blinker {
|
||||||
|
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern) {
|
||||||
|
let frames = calculate_frames(self.start_time.0, time.0);
|
||||||
|
if frames > self.frames {
|
||||||
|
match self.direction {
|
||||||
|
FadeDirection::Transition => {
|
||||||
|
self.direction = FadeDirection::FadeOut;
|
||||||
|
self.fade_out.start_time = time;
|
||||||
|
}
|
||||||
|
FadeDirection::FadeIn => {
|
||||||
|
self.direction = FadeDirection::FadeOut;
|
||||||
|
self.fade_out.start_time = time;
|
||||||
|
}
|
||||||
|
FadeDirection::FadeOut => {
|
||||||
|
self.direction = FadeDirection::FadeIn;
|
||||||
|
self.fade_in.start_time = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.start_time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.direction {
|
||||||
|
FadeDirection::Transition => self.transition.tick(time),
|
||||||
|
FadeDirection::FadeIn => self.fade_in.tick(time),
|
||||||
|
FadeDirection::FadeOut => self.fade_out.tick(time),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
use fixed::types::{I8F8, U16F0};
|
||||||
|
|
||||||
|
use crate::{calculate_frames, calculate_slope, linear_ease, Animation, BodyPattern, DashboardPattern, Instant, OFF_BODY, OFF_DASHBOARD, RGB};
|
||||||
|
|
||||||
|
pub struct Fade {
|
||||||
|
starting_dashboard: DashboardPattern,
|
||||||
|
starting_lights: BodyPattern,
|
||||||
|
|
||||||
|
pub start_time: Instant,
|
||||||
|
dashboard_slope: [RGB<I8F8>; 3],
|
||||||
|
body_slope: [RGB<I8F8>; 60],
|
||||||
|
frames: U16F0,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Fade {
|
||||||
|
pub fn new(
|
||||||
|
dashboard: DashboardPattern,
|
||||||
|
lights: BodyPattern,
|
||||||
|
ending_dashboard: DashboardPattern,
|
||||||
|
ending_lights: BodyPattern,
|
||||||
|
frames: U16F0,
|
||||||
|
time: Instant,
|
||||||
|
) -> Self {
|
||||||
|
let mut dashboard_slope = [Default::default(); 3];
|
||||||
|
let mut body_slope = [Default::default(); 60];
|
||||||
|
for i in 0..3 {
|
||||||
|
let slope = RGB {
|
||||||
|
r: calculate_slope(dashboard[i].r, ending_dashboard[i].r, frames),
|
||||||
|
g: calculate_slope(dashboard[i].g, ending_dashboard[i].g, frames),
|
||||||
|
b: calculate_slope(dashboard[i].b, ending_dashboard[i].b, frames),
|
||||||
|
};
|
||||||
|
dashboard_slope[i] = slope;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..60 {
|
||||||
|
let slope = RGB {
|
||||||
|
r: calculate_slope(lights[i].r, ending_lights[i].r, frames),
|
||||||
|
g: calculate_slope(lights[i].g, ending_lights[i].g, frames),
|
||||||
|
b: calculate_slope(lights[i].b, ending_lights[i].b, frames),
|
||||||
|
};
|
||||||
|
body_slope[i] = slope;
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
starting_dashboard: dashboard,
|
||||||
|
starting_lights: lights,
|
||||||
|
start_time: time,
|
||||||
|
dashboard_slope,
|
||||||
|
body_slope,
|
||||||
|
frames,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animation for Fade {
|
||||||
|
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern) {
|
||||||
|
let mut frames = calculate_frames(self.start_time.0, time.0);
|
||||||
|
if frames > self.frames {
|
||||||
|
frames = self.frames
|
||||||
|
}
|
||||||
|
let mut dashboard_pattern: DashboardPattern = OFF_DASHBOARD;
|
||||||
|
let mut body_pattern: BodyPattern = OFF_BODY;
|
||||||
|
|
||||||
|
for i in 0..3 {
|
||||||
|
dashboard_pattern[i].r = linear_ease(
|
||||||
|
self.starting_dashboard[i].r,
|
||||||
|
frames,
|
||||||
|
self.dashboard_slope[i].r,
|
||||||
|
);
|
||||||
|
dashboard_pattern[i].g = linear_ease(
|
||||||
|
self.starting_dashboard[i].g,
|
||||||
|
frames,
|
||||||
|
self.dashboard_slope[i].g,
|
||||||
|
);
|
||||||
|
dashboard_pattern[i].b = linear_ease(
|
||||||
|
self.starting_dashboard[i].b,
|
||||||
|
frames,
|
||||||
|
self.dashboard_slope[i].b,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..60 {
|
||||||
|
body_pattern[i].r =
|
||||||
|
linear_ease(self.starting_lights[i].r, frames, self.body_slope[i].r);
|
||||||
|
body_pattern[i].g =
|
||||||
|
linear_ease(self.starting_lights[i].g, frames, self.body_slope[i].g);
|
||||||
|
body_pattern[i].b =
|
||||||
|
linear_ease(self.starting_lights[i].b, frames, self.body_slope[i].b);
|
||||||
|
}
|
||||||
|
|
||||||
|
(dashboard_pattern, body_pattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum FadeDirection {
|
||||||
|
Transition,
|
||||||
|
FadeIn,
|
||||||
|
FadeOut,
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
use crate::{Animation, BodyPattern, DashboardPattern, Instant};
|
||||||
|
|
||||||
|
pub struct FlagRipple {
|
||||||
|
dashboard: DashboardPattern,
|
||||||
|
body: BodyPattern,
|
||||||
|
|
||||||
|
centers: [usize; 12],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlagRipple {
|
||||||
|
fn new(dashboard: DashboardPattern, body: BodyPattern) -> Self {
|
||||||
|
Self {
|
||||||
|
dashboard,
|
||||||
|
body,
|
||||||
|
centers: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animation for FlagRipple {
|
||||||
|
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern, Option<Animation>) {
|
||||||
|
// How does a flag ripple work? I think have some center points that are darker and have a
|
||||||
|
// bit of a darker pattern around them.
|
||||||
|
|
||||||
|
let mut body_pattern = self.body.clone();
|
||||||
|
|
||||||
|
for i in 0..60 {
|
||||||
|
if self.centers.contains(&i) {
|
||||||
|
body_pattern[i].r = self.body[i].r / 2;
|
||||||
|
body_pattern[i].g = self.body[i].g / 2;
|
||||||
|
body_pattern[i].b = self.body[i].b / 2;
|
||||||
|
} else {
|
||||||
|
body_pattern[i].r = self.body[i].r;
|
||||||
|
body_pattern[i].g = self.body[i].g;
|
||||||
|
body_pattern[i].b = self.body[i].b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(self.dashboard, body_pattern, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
use fixed::types::{I48F16, I8F8, U128F0, U16F0};
|
||||||
|
use az::*;
|
||||||
|
|
||||||
|
use crate::{BodyPattern, DashboardPattern, Instant, FPS};
|
||||||
|
|
||||||
|
mod blinker;
|
||||||
|
pub use blinker::*;
|
||||||
|
|
||||||
|
mod fade;
|
||||||
|
pub use fade::*;
|
||||||
|
|
||||||
|
pub trait Animation {
|
||||||
|
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn linear_ease(value: I8F8, frames: U16F0, slope: I8F8) -> I8F8 {
|
||||||
|
let value_i16f16 = I48F16::from(value) + I48F16::from(frames) * I48F16::from(slope);
|
||||||
|
value_i16f16.saturating_as()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calculate_frames(starting_time: U128F0, now: U128F0) -> U16F0 {
|
||||||
|
let frames_128 = (now - starting_time) / U128F0::from(FPS);
|
||||||
|
(frames_128 % U128F0::from(U16F0::MAX)).cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calculate_slope(start: I8F8, end: I8F8, frames: U16F0) -> I8F8 {
|
||||||
|
let slope_i16f16 = (I48F16::from(end) - I48F16::from(start)) / I48F16::from(frames);
|
||||||
|
slope_i16f16.saturating_as()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,27 +12,15 @@ use core::{
|
||||||
};
|
};
|
||||||
use fixed::types::{I48F16, I8F8, U128F0, U16F0};
|
use fixed::types::{I48F16, I8F8, U128F0, U16F0};
|
||||||
|
|
||||||
|
mod animations;
|
||||||
|
pub use animations::*;
|
||||||
|
|
||||||
mod patterns;
|
mod patterns;
|
||||||
pub use patterns::*;
|
pub use patterns::*;
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
pub use types::{BodyPattern, DashboardPattern, RGB};
|
pub use types::{BodyPattern, DashboardPattern, RGB};
|
||||||
|
|
||||||
fn calculate_frames(starting_time: U128F0, now: U128F0) -> U16F0 {
|
|
||||||
let frames_128 = (now - starting_time) / U128F0::from(FPS);
|
|
||||||
(frames_128 % U128F0::from(U16F0::MAX)).cast()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn calculate_slope(start: I8F8, end: I8F8, frames: U16F0) -> I8F8 {
|
|
||||||
let slope_i16f16 = (I48F16::from(end) - I48F16::from(start)) / I48F16::from(frames);
|
|
||||||
slope_i16f16.saturating_as()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn linear_ease(value: I8F8, frames: U16F0, slope: I8F8) -> I8F8 {
|
|
||||||
let value_i16f16 = I48F16::from(value) + I48F16::from(frames) * I48F16::from(slope);
|
|
||||||
value_i16f16.saturating_as()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
|
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
|
||||||
pub struct Instant(pub U128F0);
|
pub struct Instant(pub U128F0);
|
||||||
|
|
||||||
|
@ -65,233 +53,6 @@ pub trait UI {
|
||||||
fn update_lights(&self, dashboard_lights: DashboardPattern, body_lights: BodyPattern);
|
fn update_lights(&self, dashboard_lights: DashboardPattern, body_lights: BodyPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Animation {
|
|
||||||
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
pub struct DefaultAnimation {}
|
|
||||||
|
|
||||||
impl Animation for DefaultAnimation {
|
|
||||||
fn tick(&mut self, _: Instant) -> (DashboardPattern, BodyPattern) {
|
|
||||||
(WATER_DASHBOARD, WATER_BODY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub struct Fade {
|
|
||||||
starting_dashboard: DashboardPattern,
|
|
||||||
starting_lights: BodyPattern,
|
|
||||||
|
|
||||||
start_time: Instant,
|
|
||||||
dashboard_slope: [RGB<I8F8>; 3],
|
|
||||||
body_slope: [RGB<I8F8>; 60],
|
|
||||||
frames: U16F0,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Fade {
|
|
||||||
fn new(
|
|
||||||
dashboard: DashboardPattern,
|
|
||||||
lights: BodyPattern,
|
|
||||||
ending_dashboard: DashboardPattern,
|
|
||||||
ending_lights: BodyPattern,
|
|
||||||
frames: U16F0,
|
|
||||||
time: Instant,
|
|
||||||
) -> Self {
|
|
||||||
let mut dashboard_slope = [Default::default(); 3];
|
|
||||||
let mut body_slope = [Default::default(); 60];
|
|
||||||
for i in 0..3 {
|
|
||||||
let slope = RGB {
|
|
||||||
r: calculate_slope(dashboard[i].r, ending_dashboard[i].r, frames),
|
|
||||||
g: calculate_slope(dashboard[i].g, ending_dashboard[i].g, frames),
|
|
||||||
b: calculate_slope(dashboard[i].b, ending_dashboard[i].b, frames),
|
|
||||||
};
|
|
||||||
dashboard_slope[i] = slope;
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in 0..60 {
|
|
||||||
let slope = RGB {
|
|
||||||
r: calculate_slope(lights[i].r, ending_lights[i].r, frames),
|
|
||||||
g: calculate_slope(lights[i].g, ending_lights[i].g, frames),
|
|
||||||
b: calculate_slope(lights[i].b, ending_lights[i].b, frames),
|
|
||||||
};
|
|
||||||
body_slope[i] = slope;
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
starting_dashboard: dashboard,
|
|
||||||
starting_lights: lights,
|
|
||||||
start_time: time,
|
|
||||||
dashboard_slope,
|
|
||||||
body_slope,
|
|
||||||
frames,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Animation for Fade {
|
|
||||||
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern) {
|
|
||||||
let mut frames = calculate_frames(self.start_time.0, time.0);
|
|
||||||
if frames > self.frames {
|
|
||||||
frames = self.frames
|
|
||||||
}
|
|
||||||
let mut dashboard_pattern: DashboardPattern = OFF_DASHBOARD;
|
|
||||||
let mut body_pattern: BodyPattern = OFF_BODY;
|
|
||||||
|
|
||||||
for i in 0..3 {
|
|
||||||
dashboard_pattern[i].r = linear_ease(
|
|
||||||
self.starting_dashboard[i].r,
|
|
||||||
frames,
|
|
||||||
self.dashboard_slope[i].r,
|
|
||||||
);
|
|
||||||
dashboard_pattern[i].g = linear_ease(
|
|
||||||
self.starting_dashboard[i].g,
|
|
||||||
frames,
|
|
||||||
self.dashboard_slope[i].g,
|
|
||||||
);
|
|
||||||
dashboard_pattern[i].b = linear_ease(
|
|
||||||
self.starting_dashboard[i].b,
|
|
||||||
frames,
|
|
||||||
self.dashboard_slope[i].b,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in 0..60 {
|
|
||||||
body_pattern[i].r =
|
|
||||||
linear_ease(self.starting_lights[i].r, frames, self.body_slope[i].r);
|
|
||||||
body_pattern[i].g =
|
|
||||||
linear_ease(self.starting_lights[i].g, frames, self.body_slope[i].g);
|
|
||||||
body_pattern[i].b =
|
|
||||||
linear_ease(self.starting_lights[i].b, frames, self.body_slope[i].b);
|
|
||||||
}
|
|
||||||
|
|
||||||
(dashboard_pattern, body_pattern)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum FadeDirection {
|
|
||||||
Transition,
|
|
||||||
FadeIn,
|
|
||||||
FadeOut,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum BlinkerDirection {
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Blinker {
|
|
||||||
transition: Fade,
|
|
||||||
fade_in: Fade,
|
|
||||||
fade_out: Fade,
|
|
||||||
direction: FadeDirection,
|
|
||||||
|
|
||||||
start_time: Instant,
|
|
||||||
frames: U16F0,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Blinker {
|
|
||||||
fn new(
|
|
||||||
starting_dashboard: DashboardPattern,
|
|
||||||
starting_body: BodyPattern,
|
|
||||||
direction: BlinkerDirection,
|
|
||||||
time: Instant,
|
|
||||||
) -> Self {
|
|
||||||
let mut ending_dashboard = OFF_DASHBOARD.clone();
|
|
||||||
|
|
||||||
match direction {
|
|
||||||
BlinkerDirection::Left => {
|
|
||||||
ending_dashboard[0].r = LEFT_BLINKER_DASHBOARD[0].r;
|
|
||||||
ending_dashboard[0].g = LEFT_BLINKER_DASHBOARD[0].g;
|
|
||||||
ending_dashboard[0].b = LEFT_BLINKER_DASHBOARD[0].b;
|
|
||||||
}
|
|
||||||
BlinkerDirection::Right => {
|
|
||||||
ending_dashboard[2].r = RIGHT_BLINKER_DASHBOARD[2].r;
|
|
||||||
ending_dashboard[2].g = RIGHT_BLINKER_DASHBOARD[2].g;
|
|
||||||
ending_dashboard[2].b = RIGHT_BLINKER_DASHBOARD[2].b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut ending_body = OFF_BODY.clone();
|
|
||||||
match direction {
|
|
||||||
BlinkerDirection::Left => {
|
|
||||||
for i in 0..30 {
|
|
||||||
ending_body[i].r = LEFT_BLINKER_BODY[i].r;
|
|
||||||
ending_body[i].g = LEFT_BLINKER_BODY[i].g;
|
|
||||||
ending_body[i].b = LEFT_BLINKER_BODY[i].b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlinkerDirection::Right => {
|
|
||||||
for i in 30..60 {
|
|
||||||
ending_body[i].r = RIGHT_BLINKER_BODY[i].r;
|
|
||||||
ending_body[i].g = RIGHT_BLINKER_BODY[i].g;
|
|
||||||
ending_body[i].b = RIGHT_BLINKER_BODY[i].b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Blinker {
|
|
||||||
transition: Fade::new(
|
|
||||||
starting_dashboard.clone(),
|
|
||||||
starting_body.clone(),
|
|
||||||
ending_dashboard.clone(),
|
|
||||||
ending_body.clone(),
|
|
||||||
BLINKER_FRAMES,
|
|
||||||
time,
|
|
||||||
),
|
|
||||||
fade_in: Fade::new(
|
|
||||||
OFF_DASHBOARD.clone(),
|
|
||||||
OFF_BODY.clone(),
|
|
||||||
ending_dashboard.clone(),
|
|
||||||
ending_body.clone(),
|
|
||||||
BLINKER_FRAMES,
|
|
||||||
time,
|
|
||||||
),
|
|
||||||
fade_out: Fade::new(
|
|
||||||
ending_dashboard.clone(),
|
|
||||||
ending_body.clone(),
|
|
||||||
OFF_DASHBOARD.clone(),
|
|
||||||
OFF_BODY.clone(),
|
|
||||||
BLINKER_FRAMES,
|
|
||||||
time,
|
|
||||||
),
|
|
||||||
direction: FadeDirection::Transition,
|
|
||||||
start_time: time,
|
|
||||||
frames: BLINKER_FRAMES,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Animation for Blinker {
|
|
||||||
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern) {
|
|
||||||
let frames = calculate_frames(self.start_time.0, time.0);
|
|
||||||
if frames > self.frames {
|
|
||||||
match self.direction {
|
|
||||||
FadeDirection::Transition => {
|
|
||||||
self.direction = FadeDirection::FadeOut;
|
|
||||||
self.fade_out.start_time = time;
|
|
||||||
}
|
|
||||||
FadeDirection::FadeIn => {
|
|
||||||
self.direction = FadeDirection::FadeOut;
|
|
||||||
self.fade_out.start_time = time;
|
|
||||||
}
|
|
||||||
FadeDirection::FadeOut => {
|
|
||||||
self.direction = FadeDirection::FadeIn;
|
|
||||||
self.fade_in.start_time = time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.start_time = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.direction {
|
|
||||||
FadeDirection::Transition => self.transition.tick(time),
|
|
||||||
FadeDirection::FadeIn => self.fade_in.tick(time),
|
|
||||||
FadeDirection::FadeOut => self.fade_out.tick(time),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
Brake,
|
Brake,
|
||||||
|
|
Loading…
Reference in New Issue