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, bounce, div, ease_in_out, percentage,
  7    prelude::*, px, 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()
 41            .flex()
 42            .flex_col()
 43            .size_full()
 44            .bg(gpui::white())
 45            .text_color(gpui::black())
 46            .justify_around()
 47            .child(
 48                div()
 49                    .flex()
 50                    .flex_col()
 51                    .size_full()
 52                    .justify_around()
 53                    .child(
 54                        div()
 55                            .id("content")
 56                            .flex()
 57                            .flex_col()
 58                            .h(px(150.))
 59                            .overflow_y_scroll()
 60                            .w_full()
 61                            .flex_1()
 62                            .justify_center()
 63                            .items_center()
 64                            .text_xl()
 65                            .gap_4()
 66                            .child("Hello Animation")
 67                            .child(
 68                                svg()
 69                                    .size_20()
 70                                    .overflow_hidden()
 71                                    .path(ARROW_CIRCLE_SVG)
 72                                    .text_color(gpui::black())
 73                                    .with_animation(
 74                                        "image_circle",
 75                                        Animation::new(Duration::from_secs(2))
 76                                            .repeat()
 77                                            .with_easing(bounce(ease_in_out)),
 78                                        |svg, delta| {
 79                                            svg.with_transformation(Transformation::rotate(
 80                                                percentage(delta),
 81                                            ))
 82                                        },
 83                                    ),
 84                            ),
 85                    )
 86                    .child(
 87                        div()
 88                            .flex()
 89                            .h(px(64.))
 90                            .w_full()
 91                            .p_2()
 92                            .justify_center()
 93                            .items_center()
 94                            .border_t_1()
 95                            .border_color(gpui::black().opacity(0.1))
 96                            .bg(gpui::black().opacity(0.05))
 97                            .child("Other Panel"),
 98                    ),
 99            )
100    }
101}
102
103fn main() {
104    Application::new()
105        .with_assets(Assets {})
106        .run(|cx: &mut App| {
107            let options = WindowOptions {
108                window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
109                    None,
110                    size(px(300.), px(300.)),
111                    cx,
112                ))),
113                ..Default::default()
114            };
115            cx.open_window(options, |_, cx| {
116                cx.activate(false);
117                cx.new(|_| AnimationExample {})
118            })
119            .unwrap();
120        });
121}