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}