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}