feat(ui): Navbar entry animation + cards only animate on home page entry
This commit is contained in:
parent
08fe999691
commit
ddda1d66ba
4 changed files with 47 additions and 15 deletions
|
|
@ -1,4 +1,5 @@
|
|||
use freya::{
|
||||
animation::*,
|
||||
prelude::*,
|
||||
router::{RouterContext, use_route},
|
||||
};
|
||||
|
|
@ -10,11 +11,23 @@ use crate::{
|
|||
theme,
|
||||
};
|
||||
|
||||
const NAVBAR_INTRO_MS: u64 = 460;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub struct Navbar;
|
||||
|
||||
impl Component for Navbar {
|
||||
fn render(&self) -> impl IntoElement {
|
||||
let intro = use_animation(|conf| {
|
||||
conf.on_creation(OnCreation::Run);
|
||||
AnimNum::new(0., 1.)
|
||||
.time(NAVBAR_INTRO_MS)
|
||||
.ease(Ease::Out)
|
||||
.function(Function::Cubic)
|
||||
});
|
||||
let eased = intro.get().value();
|
||||
let slide = (1.0 - eased) * -theme::NAVBAR_HEIGHT_PX;
|
||||
|
||||
rect()
|
||||
.width(Size::fill())
|
||||
.height(Size::px(theme::NAVBAR_HEIGHT_PX))
|
||||
|
|
@ -28,6 +41,8 @@ impl Component for Navbar {
|
|||
.content(Content::Flex)
|
||||
.cross_align(Alignment::Center)
|
||||
.padding(Gaps::new_symmetric(0.0, 40.0))
|
||||
.offset_y(slide)
|
||||
.opacity(eased)
|
||||
.child(navbar_left())
|
||||
.child(navbar_center())
|
||||
.child(NavbarRight),
|
||||
|
|
|
|||
|
|
@ -44,11 +44,12 @@ impl Component for RecentsRow {
|
|||
let display = sorted.into_iter().take(slots).collect::<Vec<_>>();
|
||||
let count = display.len();
|
||||
|
||||
let dep = (*use_active_cluster_id().read(), count);
|
||||
let intro = use_animation_with_dependencies(&dep, |conf, (_, count)| {
|
||||
let items = count + 1;
|
||||
|
||||
let intro = use_animation_with_dependencies(&items, |conf, items| {
|
||||
conf.on_creation(OnCreation::Run);
|
||||
conf.on_change(OnChange::Rerun);
|
||||
let total = CARD_MS + (count.saturating_sub(1) as u64) * STAGGER_MS;
|
||||
let total = CARD_MS + (items.saturating_sub(1) as u64) * STAGGER_MS;
|
||||
AnimNum::new(0., 1.)
|
||||
.time(total.max(1))
|
||||
.function(Function::Linear)
|
||||
|
|
@ -72,19 +73,30 @@ impl Component for RecentsRow {
|
|||
ClusterCard {
|
||||
cluster: cluster.clone(),
|
||||
index,
|
||||
count,
|
||||
items,
|
||||
progress,
|
||||
}
|
||||
.into_element()
|
||||
}))
|
||||
.child(OtherVersionsTile)
|
||||
.child(OtherVersionsTile {
|
||||
index: count,
|
||||
items,
|
||||
progress,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn stagger_eased(progress: f32, index: usize, items: usize) -> f32 {
|
||||
let total = CARD_MS as f32 + (items.saturating_sub(1) as f32) * STAGGER_MS as f32;
|
||||
let elapsed = progress * total;
|
||||
let local = ((elapsed - index as f32 * STAGGER_MS as f32) / CARD_MS as f32).clamp(0., 1.);
|
||||
1.0 - (1.0 - local).powi(3)
|
||||
}
|
||||
|
||||
struct ClusterCard {
|
||||
cluster: Cluster,
|
||||
index: usize,
|
||||
count: usize,
|
||||
items: usize,
|
||||
progress: f32,
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +104,7 @@ impl PartialEq for ClusterCard {
|
|||
fn eq(&self, other: &Self) -> bool {
|
||||
self.cluster.id == other.cluster.id
|
||||
&& self.index == other.index
|
||||
&& self.count == other.count
|
||||
&& self.items == other.items
|
||||
&& self.progress == other.progress
|
||||
}
|
||||
}
|
||||
|
|
@ -107,11 +119,7 @@ impl Component for ClusterCard {
|
|||
let focus = use_focus(a11y_id);
|
||||
let focused = focus().is_focused();
|
||||
|
||||
let total = CARD_MS as f32 + (self.count.saturating_sub(1) as f32) * STAGGER_MS as f32;
|
||||
let elapsed = self.progress * total;
|
||||
let local =
|
||||
((elapsed - self.index as f32 * STAGGER_MS as f32) / CARD_MS as f32).clamp(0., 1.);
|
||||
let eased = 1.0 - (1.0 - local).powi(3);
|
||||
let eased = stagger_eased(self.progress, self.index, self.items);
|
||||
let rise = (1.0 - eased) * CARD_RISE_PX;
|
||||
|
||||
let title = format!("{} {}", self.cluster.mc_version, self.cluster.mc_loader);
|
||||
|
|
@ -219,7 +227,11 @@ impl Component for ClusterCard {
|
|||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
struct OtherVersionsTile;
|
||||
struct OtherVersionsTile {
|
||||
index: usize,
|
||||
items: usize,
|
||||
progress: f32,
|
||||
}
|
||||
|
||||
impl Component for OtherVersionsTile {
|
||||
fn render(&self) -> impl IntoElement {
|
||||
|
|
@ -229,9 +241,14 @@ impl Component for OtherVersionsTile {
|
|||
let focus = use_focus(a11y_id);
|
||||
let focused = focus().is_focused();
|
||||
|
||||
let eased = stagger_eased(self.progress, self.index, self.items);
|
||||
let rise = (1.0 - eased) * CARD_RISE_PX;
|
||||
|
||||
rect()
|
||||
.width(Size::px(MORE_TILE_WIDTH_PX))
|
||||
.height(Size::fill())
|
||||
.offset_y(rise)
|
||||
.opacity(eased)
|
||||
.corner_radius(CornerRadius::new_all(12.))
|
||||
.border(
|
||||
if focused {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ pub fn group_clusters_by_major(clusters: &[Cluster]) -> ClusterGroups {
|
|||
}
|
||||
|
||||
for list in groups.values_mut() {
|
||||
list.sort_by(|a, b| cluster_key(b).cmp(&cluster_key(a)));
|
||||
list.sort_by_key(|b| std::cmp::Reverse(cluster_key(b)));
|
||||
}
|
||||
|
||||
groups
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn selection_is_per_cluster() {
|
||||
let items = vec![
|
||||
let items = [
|
||||
ClusterBundles {
|
||||
cluster: cluster(1),
|
||||
archives: vec![archive("SkyBlock", false, vec![file("sb-a", true, false)])],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue