animation.rs

  1use std::time::Duration;
  2
  3use anyhow::Result;
  4use gpui::{
  5    Animation, AnimationExt as _, App, AssetSource, Bounds, Context, SharedString, Transformation,
  6    Window, WindowBounds, WindowOptions, bounce, div, ease_in_out, percentage, prelude::*, px,
  7    size, svg,
  8};
  9use gpui_platform::application;
 10
 11struct Assets {}
 12
 13impl AssetSource for Assets {
 14    fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
 15        std::fs::read(path)
 16            .map(Into::into)
 17            .map_err(Into::into)
 18            .map(Some)
 19    }
 20
 21    fn list(&self, path: &str) -> Result<Vec<SharedString>> {
 22        Ok(std::fs::read_dir(path)?
 23            .filter_map(|entry| {
 24                Some(SharedString::from(
 25                    entry.ok()?.path().to_string_lossy().into_owned(),
 26                ))
 27            })
 28            .collect::<Vec<_>>())
 29    }
 30}
 31
 32const ARROW_CIRCLE_SVG: &str = concat!(
 33    env!("CARGO_MANIFEST_DIR"),
 34    "/examples/image/arrow_circle.svg"
 35);
 36
 37struct AnimationExample {}
 38
 39impl Render for AnimationExample {
 40    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
 41        div()
 42            .flex()
 43            .flex_col()
 44            .size_full()
 45            .bg(gpui::white())
 46            .text_color(gpui::black())
 47            .justify_around()
 48            .child(
 49                div()
 50                    .flex()
 51                    .flex_col()
 52                    .size_full()
 53                    .justify_around()
 54                    .child(
 55                        div()
 56                            .id("content")
 57                            .flex()
 58                            .flex_col()
 59                            .h(px(150.))
 60                            .overflow_y_scroll()
 61                            .w_full()
 62                            .flex_1()
 63                            .justify_center()
 64                            .items_center()
 65                            .text_xl()
 66                            .gap_4()
 67                            .child("Hello Animation")
 68                            .child(
 69                                svg()
 70                                    .size_20()
 71                                    .overflow_hidden()
 72                                    .path(ARROW_CIRCLE_SVG)
 73                                    .text_color(gpui::black())
 74                                    .with_animation(
 75                                        "image_circle",
 76                                        Animation::new(Duration::from_secs(2))
 77                                            .repeat()
 78                                            .with_easing(bounce(ease_in_out)),
 79                                        |svg, delta| {
 80                                            svg.with_transformation(Transformation::rotate(
 81                                                percentage(delta),
 82                                            ))
 83                                        },
 84                                    ),
 85                            ),
 86                    )
 87                    .child(
 88                        div()
 89                            .flex()
 90                            .h(px(64.))
 91                            .w_full()
 92                            .p_2()
 93                            .justify_center()
 94                            .items_center()
 95                            .border_t_1()
 96                            .border_color(gpui::black().opacity(0.1))
 97                            .bg(gpui::black().opacity(0.05))
 98                            .child("Other Panel"),
 99                    ),
100            )
101    }
102}
103
104fn main() {
105    application().with_assets(Assets {}).run(|cx: &mut App| {
106        let options = WindowOptions {
107            window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
108                None,
109                size(px(300.), px(300.)),
110                cx,
111            ))),
112            ..Default::default()
113        };
114        cx.open_window(options, |_, cx| {
115            cx.activate(false);
116            cx.new(|_| AnimationExample {})
117        })
118        .unwrap();
119    });
120}