animation.rs

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