relative_cursor_position/
relative_cursor_position.rs1use bevy::{camera::Viewport, prelude::*, ui::RelativeCursorPosition};
4
5fn main() {
6 App::new()
7 .add_plugins(DefaultPlugins)
8 .add_systems(Startup, setup)
9 .add_systems(Update, relative_cursor_position_system)
10 .run();
11}
12
13fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
14 commands.spawn((
15 Camera2d,
16 Camera {
17 viewport: Some(Viewport {
19 physical_position: [200, 100].into(),
20 physical_size: [600, 600].into(),
21 ..default()
22 }),
23 ..default()
24 },
25 ));
26
27 commands
28 .spawn(Node {
29 width: percent(100),
30 height: percent(100),
31 align_items: AlignItems::Center,
32 justify_content: JustifyContent::Center,
33 flex_direction: FlexDirection::Column,
34 ..default()
35 })
36 .with_children(|parent| {
37 parent
38 .spawn((
39 Node {
40 width: px(250),
41 height: px(250),
42 margin: UiRect::bottom(px(15)),
43 ..default()
44 },
45 BackgroundColor(Color::srgb(0.92, 0.14, 0.05)),
46 ))
47 .insert(RelativeCursorPosition::default());
48
49 parent.spawn((
50 Text::new("(0.0, 0.0)"),
51 TextFont {
52 font: asset_server.load("fonts/FiraSans-Bold.ttf"),
53 font_size: 33.0,
54 ..default()
55 },
56 TextColor(Color::srgb(0.9, 0.9, 0.9)),
57 ));
58 });
59}
60
61fn relative_cursor_position_system(
63 relative_cursor_position: Single<&RelativeCursorPosition>,
64 output_query: Single<(&mut Text, &mut TextColor)>,
65) {
66 let (mut output, mut text_color) = output_query.into_inner();
67
68 **output = if let Some(relative_cursor_position) = relative_cursor_position.normalized {
69 format!(
70 "({:.1}, {:.1})",
71 relative_cursor_position.x, relative_cursor_position.y
72 )
73 } else {
74 "unknown".to_string()
75 };
76
77 text_color.0 = if relative_cursor_position.cursor_over() {
78 Color::srgb(0.1, 0.9, 0.1)
79 } else {
80 Color::srgb(0.9, 0.1, 0.1)
81 };
82}