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}