animated-number
Builds AnimatedNumber Button


The code that drew it
A still frame holds a repeating animation at its first frame and a one-shot at its last, because a still of a moving thing is not reproducible. Run the gallery to review motion.
fn animated_number(_window: &mut Window, cx: &mut App) -> AnyElement {
if !cx.has_global::<SceneCounts>() {
cx.set_global(SceneCounts {
runs: 1204.0,
seconds: 18.4,
});
}
let counts = cx.global::<SceneCounts>();
let (runs, seconds) = (counts.runs, counts.seconds);
let theme = cx.theme().clone();
let readout = |label: &'static str, number: AnimatedNumber| {
div()
.column()
.gap(px(theme.spacing.xs))
.child(
div()
.text_size(px(theme.typography.caption.size))
.text_color(theme.colors.text_muted)
.child(label),
)
.child(number)
};
stack(&theme)
.child(
row(&theme)
.gap(px(theme.spacing.xl))
.items_start()
.child(readout(
"Runs this week",
AnimatedNumber::new("scene.number.runs", runs).format(grouped),
))
.child(readout(
"Median duration",
AnimatedNumber::new("scene.number.seconds", seconds)
.format(|value| format!("{value:.1}s")),
)),
)
.child(
row(&theme).child(
Button::new("scene.number.recount")
.label("Recount")
.secondary()
.on_click(|_, cx| {
cx.update_global::<SceneCounts, ()>(|counts, _| {
counts.runs += 318.0;
counts.seconds += 4.7;
});
cx.refresh_windows();
}),
),
)
.child(
div()
.text_size(px(theme.typography.caption.size))
.text_color(theme.colors.text_muted)
.child("The published value is the target, from the frame it changes."),
)
.into_any_element()
}