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}