hover_color/
hover_color.rs1use gpui::{
2 App, Application, Bounds, Context, Window, WindowBounds, WindowOptions, div, linear_color_stop,
3 linear_gradient, prelude::*, px, rgb, size,
4};
5use gpui_animation::{
6 animation::TransitionExt,
7 transition::{self},
8};
9
10struct Hover {
11 hovered: bool,
12}
13
14impl Render for Hover {
15 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
16 let linear = std::sync::Arc::new(transition::general::Linear);
17 let gradient1 = linear_gradient(
18 30.,
19 linear_color_stop(rgb(0xfccf31), 0.),
20 linear_color_stop(rgb(0xf55555), 1.),
21 );
22 let gradient2 = linear_gradient(
23 230.,
24 linear_color_stop(rgb(0xeead92), 0.),
25 linear_color_stop(rgb(0x6018dc), 1.),
26 );
27
28 div()
29 .id("Hoverable2")
30 .flex()
31 .flex_col()
32 .gap_3()
33 .size(px(500.0))
34 .justify_center()
35 .items_center()
36 .child(
37 div()
38 .id("Hoverable")
39 .child("Hover over rectangle")
40 .with_transition("Hoverable")
41 .bg(gpui::white())
42 .text_color(gpui::red())
43 .flex()
44 .text_xl()
45 .h_10()
46 .justify_center()
47 .items_center()
48 .transition_on_hover(
49 std::time::Duration::from_millis(250),
50 linear.clone(),
51 |hovered, state| {
52 if *hovered {
53 state
54 .text_bg(gpui::blue())
55 .text_color(gpui::yellow())
56 .text_lg()
57 } else {
58 state
59 .text_bg(gpui::white())
60 .text_color(gpui::black())
61 .text_xl()
62 }
63 },
64 ),
65 )
66 .child(
67 div().flex().gap_2().child(
68 div()
69 .id("Hoverable1")
70 .size_16()
71 .with_transition("Hoverable1")
72 .transition_on_hover(
73 std::time::Duration::from_millis(250),
74 linear.clone(),
75 |hovered, state| {
76 if *hovered {
77 state.bg(gpui::yellow()).opacity(0.)
78 } else {
79 state.bg(gpui::red()).opacity(1.)
80 }
81 },
82 )
83 .opacity(1.)
84 .bg(gpui::red()),
85 ),
86 )
87 .with_transition("Hoverable2")
88 .on_hover(cx.listener(|this, hovered, _, cx| {
89 this.hovered = *hovered;
90
91 cx.notify();
95 }))
96 .transition_when(
97 self.hovered,
98 std::time::Duration::from_millis(500),
99 transition::general::EaseInExpo,
100 move |this| this.bg(gradient2),
101 )
102 .transition_on_click(
103 std::time::Duration::from_millis(500),
104 transition::general::EaseInExpo,
105 |_, state| state.bg(gpui::blue()),
106 )
107 .transition_on_hover(
108 std::time::Duration::from_millis(500),
109 transition::general::EaseInExpo,
110 move |hovered, state| {
111 if *hovered {
112 state.bg(gradient2)
113 } else {
114 state.origin()
115 }
116 },
117 )
118 .bg(gradient1)
119 }
120}
121
122fn main() {
123 Application::new().run(|cx: &mut App| {
124 let bounds = Bounds::centered(None, size(px(500.), px(500.0)), cx);
125 cx.open_window(
126 WindowOptions {
127 window_bounds: Some(WindowBounds::Windowed(bounds)),
128 ..Default::default()
129 },
130 |_, cx| cx.new(|_| Hover { hovered: false }),
131 )
132 .unwrap();
133 });
134}