mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-24 21:32:03 +00:00
chore(eckhart): improve HTC animation
This commit is contained in:
parent
e1cfb7a20b
commit
edea4c1fbf
@ -5,12 +5,14 @@ use crate::{
|
|||||||
component::{Component, Event, EventCtx, Never},
|
component::{Component, Event, EventCtx, Never},
|
||||||
display::Color,
|
display::Color,
|
||||||
geometry::{Offset, Rect},
|
geometry::{Offset, Rect},
|
||||||
layout_eckhart::{cshape::ScreenBorder, fonts},
|
|
||||||
shape::{self, Renderer},
|
shape::{self, Renderer},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{constant, theme, Header};
|
use super::{
|
||||||
|
super::{component::Header, cshape::ScreenBorder, fonts, theme},
|
||||||
|
constant::SCREEN,
|
||||||
|
};
|
||||||
|
|
||||||
/// A component that displays a border that grows from the bottom of the screen
|
/// A component that displays a border that grows from the bottom of the screen
|
||||||
/// to the top. The animation is parametrizable by color and duration.
|
/// to the top. The animation is parametrizable by color and duration.
|
||||||
@ -67,17 +69,57 @@ impl HoldToConfirmAnim {
|
|||||||
self.timer.is_running_within(self.duration)
|
self.timer.is_running_within(self.duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_clip(&self) -> Rect {
|
fn get_clips(&self) -> (Rect, Option<Rect>) {
|
||||||
// TODO:
|
|
||||||
// 1) there will be some easer function
|
|
||||||
// 2) the growth of the top bar cannot be done with just one clip
|
|
||||||
let screen = constant::screen();
|
|
||||||
let ratio = self.timer.elapsed() / self.duration;
|
let ratio = self.timer.elapsed() / self.duration;
|
||||||
let clip_height = ((ratio * screen.height() as f32) as i16).clamp(0, screen.height());
|
|
||||||
Rect::from_bottom_left_and_size(
|
let bottom_width = self.border.bottom_width();
|
||||||
screen.bottom_left(),
|
let total_height = SCREEN.height();
|
||||||
Offset::new(screen.width(), clip_height),
|
let total_width = SCREEN.width();
|
||||||
|
|
||||||
|
let circumference = 2 * total_height + total_width + bottom_width;
|
||||||
|
let bottom_ratio = bottom_width as f32 / circumference as f32;
|
||||||
|
let vertical_ratio = (2 * total_height) as f32 / circumference as f32;
|
||||||
|
let upper_ratio = total_width as f32 / circumference as f32;
|
||||||
|
|
||||||
|
let vertical_cut = bottom_ratio + vertical_ratio;
|
||||||
|
|
||||||
|
if ratio < bottom_ratio {
|
||||||
|
// Animate the bottom border growing horizontally.
|
||||||
|
let clip_width = ((ratio / bottom_ratio) * bottom_width as f32) as i16;
|
||||||
|
let clip_width = clip_width.clamp(0, bottom_width);
|
||||||
|
(
|
||||||
|
Rect::from_center_and_size(
|
||||||
|
SCREEN
|
||||||
|
.bottom_center()
|
||||||
|
.ofs(Offset::y(-ScreenBorder::WIDTH / 2)),
|
||||||
|
Offset::new(clip_width, ScreenBorder::WIDTH),
|
||||||
|
),
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
|
} else if ratio < vertical_cut {
|
||||||
|
// Animate the vertical border growing from the bottom up.
|
||||||
|
let progress = (ratio - bottom_ratio) / vertical_ratio;
|
||||||
|
let clip_height = (progress * total_height as f32) as i16;
|
||||||
|
let clip_height = clip_height.clamp(0, total_height - ScreenBorder::WIDTH);
|
||||||
|
(
|
||||||
|
Rect::from_bottom_left_and_size(
|
||||||
|
SCREEN.bottom_left(),
|
||||||
|
Offset::new(total_width, clip_height),
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// Animate the top border growing horizontally towards center.
|
||||||
|
let progress = (ratio - vertical_cut) / upper_ratio;
|
||||||
|
let clip_width = total_width - ((progress * total_width as f32) as i16);
|
||||||
|
(
|
||||||
|
SCREEN,
|
||||||
|
Some(Rect::from_center_and_size(
|
||||||
|
SCREEN.top_center().ofs(Offset::y(ScreenBorder::WIDTH / 2)),
|
||||||
|
Offset::new(clip_width, ScreenBorder::WIDTH),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,8 +146,8 @@ impl Component for HoldToConfirmAnim {
|
|||||||
if let Some(text) = self.header_overlay {
|
if let Some(text) = self.header_overlay {
|
||||||
let font = fonts::FONT_SATOSHI_REGULAR_22;
|
let font = fonts::FONT_SATOSHI_REGULAR_22;
|
||||||
let header_pad = Rect::from_top_left_and_size(
|
let header_pad = Rect::from_top_left_and_size(
|
||||||
constant::screen().top_left(),
|
SCREEN.top_left(),
|
||||||
Offset::new(constant::screen().width(), Header::HEADER_HEIGHT),
|
Offset::new(SCREEN.width(), Header::HEADER_HEIGHT),
|
||||||
);
|
);
|
||||||
shape::Bar::new(header_pad)
|
shape::Bar::new(header_pad)
|
||||||
.with_bg(theme::BG)
|
.with_bg(theme::BG)
|
||||||
@ -119,10 +161,17 @@ impl Component for HoldToConfirmAnim {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// growing border
|
// growing border
|
||||||
let clip = self.get_clip();
|
let (in_clip, out_clip_opt) = self.get_clips();
|
||||||
target.in_clip(clip, &|target| {
|
target.in_clip(in_clip, &|target| {
|
||||||
self.border.render(target);
|
self.border.render(target);
|
||||||
});
|
});
|
||||||
|
// optional out clip for upper line rendering
|
||||||
|
if let Some(out_clip) = out_clip_opt {
|
||||||
|
shape::Bar::new(out_clip)
|
||||||
|
.with_bg(theme::BG)
|
||||||
|
.with_fg(theme::BG)
|
||||||
|
.render(target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ pub struct ScreenBorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenBorder {
|
impl ScreenBorder {
|
||||||
|
pub const WIDTH: i16 = 2;
|
||||||
pub fn new(color: Color) -> Self {
|
pub fn new(color: Color) -> Self {
|
||||||
let screen = constant::screen();
|
let screen = constant::screen();
|
||||||
|
|
||||||
@ -59,6 +60,10 @@ impl ScreenBorder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bottom_width(&self) -> i16 {
|
||||||
|
self.side_bars[0].width()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
pub fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||||
let screen = constant::screen();
|
let screen = constant::screen();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user