gradient.rs

  1#![cfg_attr(target_family = "wasm", no_main)]
  2
  3use gpui::{
  4    App, Bounds, ColorSpace, Context, Half, Render, Window, WindowOptions, canvas, div,
  5    linear_color_stop, linear_gradient, point, prelude::*, px, size,
  6};
  7use gpui_platform::application;
  8
  9struct GradientViewer {
 10    color_space: ColorSpace,
 11}
 12
 13impl GradientViewer {
 14    fn new() -> Self {
 15        Self {
 16            color_space: ColorSpace::default(),
 17        }
 18    }
 19}
 20
 21impl Render for GradientViewer {
 22    fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
 23        let color_space = self.color_space;
 24
 25        div()
 26            .bg(gpui::white())
 27            .size_full()
 28            .p_4()
 29            .flex()
 30            .flex_col()
 31            .gap_3()
 32            .child(
 33                div()
 34                    .flex()
 35                    .gap_2()
 36                    .justify_between()
 37                    .items_center()
 38                    .child("Gradient Examples")
 39                    .child(
 40                        div().flex().gap_2().items_center().child(
 41                            div()
 42                                .id("method")
 43                                .flex()
 44                                .px_3()
 45                                .py_1()
 46                                .text_sm()
 47                                .bg(gpui::black())
 48                                .text_color(gpui::white())
 49                                .child(format!("{}", color_space))
 50                                .active(|this| this.opacity(0.8))
 51                                .on_click(cx.listener(move |this, _, _, cx| {
 52                                    this.color_space = match this.color_space {
 53                                        ColorSpace::Oklab => ColorSpace::Srgb,
 54                                        ColorSpace::Srgb => ColorSpace::Oklab,
 55                                    };
 56                                    cx.notify();
 57                                })),
 58                        ),
 59                    ),
 60            )
 61            .child(
 62                div()
 63                    .flex()
 64                    .flex_1()
 65                    .gap_3()
 66                    .child(
 67                        div()
 68                            .size_full()
 69                            .rounded_xl()
 70                            .flex()
 71                            .items_center()
 72                            .justify_center()
 73                            .bg(gpui::red())
 74                            .text_color(gpui::white())
 75                            .child("Solid Color"),
 76                    )
 77                    .child(
 78                        div()
 79                            .size_full()
 80                            .rounded_xl()
 81                            .flex()
 82                            .items_center()
 83                            .justify_center()
 84                            .bg(gpui::blue())
 85                            .text_color(gpui::white())
 86                            .child("Solid Color"),
 87                    ),
 88            )
 89            .child(
 90                div()
 91                    .flex()
 92                    .flex_1()
 93                    .gap_3()
 94                    .h_24()
 95                    .text_color(gpui::white())
 96                    .child(
 97                        div().flex_1().rounded_xl().bg(linear_gradient(
 98                            45.,
 99                            linear_color_stop(gpui::red(), 0.),
100                            linear_color_stop(gpui::blue(), 1.),
101                        )
102                        .color_space(color_space)),
103                    )
104                    .child(
105                        div().flex_1().rounded_xl().bg(linear_gradient(
106                            135.,
107                            linear_color_stop(gpui::red(), 0.),
108                            linear_color_stop(gpui::green(), 1.),
109                        )
110                        .color_space(color_space)),
111                    )
112                    .child(
113                        div().flex_1().rounded_xl().bg(linear_gradient(
114                            225.,
115                            linear_color_stop(gpui::green(), 0.),
116                            linear_color_stop(gpui::blue(), 1.),
117                        )
118                        .color_space(color_space)),
119                    )
120                    .child(
121                        div().flex_1().rounded_xl().bg(linear_gradient(
122                            315.,
123                            linear_color_stop(gpui::green(), 0.),
124                            linear_color_stop(gpui::yellow(), 1.),
125                        )
126                        .color_space(color_space)),
127                    ),
128            )
129            .child(
130                div()
131                    .flex()
132                    .flex_1()
133                    .gap_3()
134                    .h_24()
135                    .text_color(gpui::white())
136                    .child(
137                        div().flex_1().rounded_xl().bg(linear_gradient(
138                            0.,
139                            linear_color_stop(gpui::red(), 0.),
140                            linear_color_stop(gpui::white(), 1.),
141                        )
142                        .color_space(color_space)),
143                    )
144                    .child(
145                        div().flex_1().rounded_xl().bg(linear_gradient(
146                            90.,
147                            linear_color_stop(gpui::blue(), 0.),
148                            linear_color_stop(gpui::white(), 1.),
149                        )
150                        .color_space(color_space)),
151                    )
152                    .child(
153                        div().flex_1().rounded_xl().bg(linear_gradient(
154                            180.,
155                            linear_color_stop(gpui::green(), 0.),
156                            linear_color_stop(gpui::white(), 1.),
157                        )
158                        .color_space(color_space)),
159                    )
160                    .child(
161                        div().flex_1().rounded_xl().bg(linear_gradient(
162                            360.,
163                            linear_color_stop(gpui::yellow(), 0.),
164                            linear_color_stop(gpui::white(), 1.),
165                        )
166                        .color_space(color_space)),
167                    ),
168            )
169            .child(
170                div().flex_1().rounded_xl().bg(linear_gradient(
171                    0.,
172                    linear_color_stop(gpui::green(), 0.05),
173                    linear_color_stop(gpui::yellow(), 0.95),
174                )
175                .color_space(color_space)),
176            )
177            .child(
178                div().flex_1().rounded_xl().bg(linear_gradient(
179                    90.,
180                    linear_color_stop(gpui::blue(), 0.05),
181                    linear_color_stop(gpui::red(), 0.95),
182                )
183                .color_space(color_space)),
184            )
185            .child(
186                div()
187                    .flex()
188                    .flex_1()
189                    .gap_3()
190                    .child(
191                        div().flex().flex_1().gap_3().child(
192                            div().flex_1().rounded_xl().bg(linear_gradient(
193                                90.,
194                                linear_color_stop(gpui::blue(), 0.5),
195                                linear_color_stop(gpui::red(), 0.5),
196                            )
197                            .color_space(color_space)),
198                        ),
199                    )
200                    .child(
201                        div().flex_1().rounded_xl().bg(linear_gradient(
202                            180.,
203                            linear_color_stop(gpui::green(), 0.),
204                            linear_color_stop(gpui::blue(), 0.5),
205                        )
206                        .color_space(color_space)),
207                    ),
208            )
209            .child(div().h_24().child(canvas(
210                move |_, _, _| {},
211                move |bounds, _, window, _| {
212                    let size = size(bounds.size.width * 0.8, px(80.));
213                    let square_bounds = Bounds {
214                        origin: point(
215                            bounds.size.width.half() - size.width.half(),
216                            bounds.origin.y,
217                        ),
218                        size,
219                    };
220                    let height = square_bounds.size.height;
221                    let horizontal_offset = height;
222                    let vertical_offset = px(30.);
223                    let mut builder = gpui::PathBuilder::fill();
224                    builder.move_to(square_bounds.bottom_left());
225                    builder
226                        .line_to(square_bounds.origin + point(horizontal_offset, vertical_offset));
227                    builder.line_to(
228                        square_bounds.top_right() + point(-horizontal_offset, vertical_offset),
229                    );
230
231                    builder.line_to(square_bounds.bottom_right());
232                    builder.line_to(square_bounds.bottom_left());
233                    let path = builder.build().unwrap();
234                    window.paint_path(
235                        path,
236                        linear_gradient(
237                            180.,
238                            linear_color_stop(gpui::red(), 0.),
239                            linear_color_stop(gpui::blue(), 1.),
240                        )
241                        .color_space(color_space),
242                    );
243                },
244            )))
245    }
246}
247
248fn run_example() {
249    application().run(|cx: &mut App| {
250        cx.open_window(
251            WindowOptions {
252                focus: true,
253                ..Default::default()
254            },
255            |_, cx| cx.new(|_| GradientViewer::new()),
256        )
257        .unwrap();
258        cx.activate(true);
259    });
260}
261
262#[cfg(not(target_family = "wasm"))]
263fn main() {
264    run_example();
265}
266
267#[cfg(target_family = "wasm")]
268#[wasm_bindgen::prelude::wasm_bindgen(start)]
269pub fn start() {
270    gpui_platform::web_init();
271    run_example();
272}