tasks: ui: use const animators

This commit is contained in:
2026-03-24 12:37:53 +01:00
parent 38f49513f3
commit e18425e0ca

View File

@@ -7,6 +7,19 @@ use log::*;
use crate::{animation::{AnimatedSurface, Animation}, ego::engine::MotionState, events::{Personality, Prediction, Scene, SensorSource, SensorState}, graphics::{display::{SegmentSpace, Uniforms}, shaders::*}}; use crate::{animation::{AnimatedSurface, Animation}, ego::engine::MotionState, events::{Personality, Prediction, Scene, SensorSource, SensorState}, graphics::{display::{SegmentSpace, Uniforms}, shaders::*}};
const NOTIFY_FADE_IN: Animation<Fract8> = Animation::new().duration(Duration::from_millis(30)) .from(Fract8::MIN).to(Fract8::MAX);
const NOTIFY_PULSE_OUT: Animation<Fract8> = Animation::new().duration(Duration::from_millis(100)).from(Fract8::MAX).to(Fract8::from_raw(60));
const NOTIFY_PULSE_IN: Animation<Fract8> = Animation::new().duration(Duration::from_millis(100)).from(Fract8::MIN).to(Fract8::MAX);
const NOTIFY_FADE_OUT: Animation<Fract8> = Animation::new().duration(Duration::from_secs(2)) .from(Fract8::MAX).to(Fract8::MIN);
const FG_FADE_OUT: Animation<Fract8> = Animation::new().duration(Duration::from_millis(300)).to(Fract8::MIN);
const BG_FADE_IN: Animation<Fract8> = Animation::new().duration(Duration::from_millis(300)).to(Fract8::from_raw(128));
const TAIL: Animation<Fract8> = Animation::new().duration(Duration::from_millis(300)).to(Fract8::from_raw(96));
const PANELS: Animation<Fract8> = Animation::new().duration(Duration::from_millis(300)).to(Fract8::from_raw(128));
const BG: Animation<Fract8> = Animation::new().duration(Duration::from_millis(300)).to(Fract8::from_raw(32));
const MOTION: Animation<Fract8> = Animation::new().duration(Duration::from_secs(1)) .to(Fract8::MIN);
pub struct Ui<S: Surface> { pub struct Ui<S: Surface> {
// Background layer provides an always-running background for everything to draw on // Background layer provides an always-running background for everything to draw on
background: AnimatedSurface<S>, background: AnimatedSurface<S>,
@@ -53,25 +66,21 @@ impl<S: Debug + Surface<Uniforms = Uniforms, CoordinateSpace = SegmentSpace, Pix
} }
pub async fn flash_notification_color(&mut self, color: Rgb<u8>) { pub async fn flash_notification_color(&mut self, color: Rgb<u8>) {
let fade_in = Animation::default().from(Fract8::MIN).to(Fract8::MAX).duration(Duration::from_millis(30));
let pulse_out = Animation::default().from(Fract8::MAX).to(Fract8::from_raw(60)).duration(Duration::from_millis(100));
let pulse_in = Animation::default().from(Fract8::MIN).to(Fract8::MAX).duration(Duration::from_millis(100));
let fade_out = Animation::default().from(Fract8::MAX).to(Fract8::MIN).duration(Duration::from_secs(2));
info!("Flashing notification {color}"); info!("Flashing notification {color}");
self.notification.set_visible(true); self.notification.set_visible(true);
self.notification.set_shader(Background::from_color(color)); self.notification.set_shader(Background::from_color(color));
fade_in.apply([&mut self.notification]).await; NOTIFY_FADE_IN.apply([&mut self.notification]).await;
// Pulse quickly 5 times // Pulse quickly 5 times
for _ in 0..5 { for _ in 0..5 {
pulse_out.apply([&mut self.notification]).await; NOTIFY_PULSE_OUT.apply([&mut self.notification]).await;
pulse_in.apply([&mut self.notification]).await; NOTIFY_PULSE_IN.apply([&mut self.notification]).await;
} }
fade_out.apply([&mut self.notification]).await; NOTIFY_FADE_OUT.apply([&mut self.notification]).await;
self.notification.set_visible(false); self.notification.set_visible(false);
} }
@@ -93,26 +102,20 @@ impl<S: Debug + Surface<Uniforms = Uniforms, CoordinateSpace = SegmentSpace, Pix
info!("Activating scene {next_scene:?}"); info!("Activating scene {next_scene:?}");
match next_scene { match next_scene {
Scene::Ready => { Scene::Ready => {
let tail = Animation::default().duration(Duration::from_millis(300)).to(Fract8::from_raw(96));
let panels = Animation::default().duration(Duration::from_millis(300)).to(Fract8::from_raw(128));
let bg = Animation::default().duration(Duration::from_millis(300)).to(Fract8::from_raw(32));
let motion = Animation::default().duration(Duration::from_secs(1)).to(Fract8::MIN);
embassy_futures::join::join4( embassy_futures::join::join4(
tail.apply([&mut self.tail]), TAIL.apply([&mut self.tail]),
panels.apply([&mut self.panels]), PANELS.apply([&mut self.panels]),
bg.apply([&mut self.background]), BG.apply([&mut self.background]),
motion.apply([&mut self.motion]) MOTION.apply([&mut self.motion])
).await; ).await;
self.background.set_shader(Background::default()); self.background.set_shader(Background::default());
}, },
Scene::Idle => { Scene::Idle => {
self.background.set_shader(Thinking::default()); self.background.set_shader(Thinking::default());
let fg_fade = Animation::default().duration(Duration::from_millis(300)).to(Fract8::MIN);
let bg_fade = Animation::default().duration(Duration::from_millis(300)).to(Fract8::from_raw(128));
embassy_futures::join::join( embassy_futures::join::join(
fg_fade.apply([&mut self.tail, &mut self.panels, &mut self.motion]), FG_FADE_OUT.apply([&mut self.tail, &mut self.panels, &mut self.motion]),
bg_fade.apply([&mut self.background]) BG_FADE_IN.apply([&mut self.background])
).await; ).await;
}, },
Scene::Accelerating => { Scene::Accelerating => {