animations/
animations.rs

1#![feature(type_alias_impl_trait, impl_trait_in_assoc_type)]
2
3use std::time::Duration;
4
5use nuit::{clone, Alignment, Animation, Bind, Button, Circle, ForEach, Frame, HStack, Rectangle, State, Text, VStack, Vec2, View, ViewExt, ZStack};
6
7#[derive(Bind)]
8struct AnimationsView<const COUNT: usize> {
9    animations: [Animation; COUNT],
10    flips: State<[bool; COUNT]>,
11}
12
13impl<const COUNT: usize> AnimationsView<COUNT> {
14    pub fn new(animations: [Animation; COUNT]) -> Self {
15        Self {
16            animations,
17            flips: State::new(animations.map(|_| false)),
18        }
19    }
20}
21
22impl<const COUNT: usize> View for AnimationsView<COUNT> {
23    type Body = impl View;
24
25    fn body(&self) -> Self::Body {
26        let animations = self.animations;
27        let flips = self.flips.clone();
28        let width = 200.0;
29        let radius = 10.0;
30        let inner_width = width - 2.0 * radius;
31
32        VStack::new((
33            VStack::new(
34                ForEach::with_index_id(animations, |i, animation| {
35                    let factor = if flips.get()[i] { 1.0 } else { -1.0 };
36                    HStack::new((
37                        Text::new(format!("{}", animation))
38                            .frame_with(Alignment::Trailing, Frame::with_width(100)),
39                        ZStack::new((
40                            Rectangle::new()
41                                .frame(Frame::exact(inner_width, 2)),
42                            Circle::new()
43                                .frame(2.0 * radius)
44                                .offset(Vec2::with_x(factor * inner_width / 2.0))
45                        ))
46                        .frame(Frame::with_width(width)),
47                        Button::with_text("Flip", clone!(flips => move || {
48                            let mut value = flips.get();
49                            value[i] = !value[i];
50                            flips.set_with(animation, value);
51                        })),
52                    ))
53                })
54            ),
55        ))
56    }
57}
58
59fn main() {
60    let duration = Duration::from_secs(4);
61    nuit::run_app(AnimationsView::new([
62        Animation::linear(duration),
63        Animation::ease_in(duration),
64        Animation::ease_out(duration),
65        Animation::ease_in_out(duration),
66    ]));
67}