animation.rs

 1use std::time::Duration;
 2
 3use anyhow::Result;
 4use gpui::{
 5    Animation, AnimationExt as _, App, Application, AssetSource, Bounds, Context, SharedString,
 6    Transformation, Window, WindowBounds, WindowOptions, black, bounce, div, ease_in_out,
 7    percentage, prelude::*, px, rgb, size, svg,
 8};
 9
10struct Assets {}
11
12impl AssetSource for Assets {
13    fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
14        std::fs::read(path)
15            .map(Into::into)
16            .map_err(Into::into)
17            .map(Some)
18    }
19
20    fn list(&self, path: &str) -> Result<Vec<SharedString>> {
21        Ok(std::fs::read_dir(path)?
22            .filter_map(|entry| {
23                Some(SharedString::from(
24                    entry.ok()?.path().to_string_lossy().into_owned(),
25                ))
26            })
27            .collect::<Vec<_>>())
28    }
29}
30
31const ARROW_CIRCLE_SVG: &str = concat!(
32    env!("CARGO_MANIFEST_DIR"),
33    "/examples/image/arrow_circle.svg"
34);
35
36struct AnimationExample {}
37
38impl Render for AnimationExample {
39    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
40        div().flex().flex_col().size_full().justify_around().child(
41            div().flex().flex_row().w_full().justify_around().child(
42                div()
43                    .flex()
44                    .bg(rgb(0x2e7d32))
45                    .size(px(300.0))
46                    .justify_center()
47                    .items_center()
48                    .shadow_lg()
49                    .text_xl()
50                    .text_color(black())
51                    .child("hello")
52                    .child(
53                        svg()
54                            .size_8()
55                            .path(ARROW_CIRCLE_SVG)
56                            .text_color(black())
57                            .with_animation(
58                                "image_circle",
59                                Animation::new(Duration::from_secs(2))
60                                    .repeat()
61                                    .with_easing(bounce(ease_in_out)),
62                                |svg, delta| {
63                                    svg.with_transformation(Transformation::rotate(percentage(
64                                        delta,
65                                    )))
66                                },
67                            ),
68                    ),
69            ),
70        )
71    }
72}
73
74fn main() {
75    Application::new()
76        .with_assets(Assets {})
77        .run(|cx: &mut App| {
78            let options = WindowOptions {
79                window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
80                    None,
81                    size(px(300.), px(300.)),
82                    cx,
83                ))),
84                ..Default::default()
85            };
86            cx.open_window(options, |_, cx| {
87                cx.activate(false);
88                cx.new(|_| AnimationExample {})
89            })
90            .unwrap();
91        });
92}