Bounds
Overview
Use Bounds
to arrange your canvas into rectangular regions. It is a great way to set up your UI and create buttons and menus on your screen.
API
bounds::canvas
Returns the fixed canvas bounds without any camera position or zoom adjustments. This is typically useful for GUI elements that are fixed in size and position relative to the game's canvas.
bounds::canvas() -> Bounds
bounds::viewport
Returns the current viewport bounds with the current camera offset applied. This is typically used to get the canvas or screen boundaries.
bounds::viewport() -> Bounds
Bounds
pub struct Bounds {
x: i32,
y: i32,
w: u32,
h: u32,
}
Usage
Create a bounds for the full screen size
// create a new bounds that fills the full space of your screen
let canvas_bounds = bounds::canvas();
Create a bounds of a set size and center it
let canvas_bounds = bounds::canvas();
// create a new bounds that is 48 px wide and 14 px tall
let bounds = Bounds::with_size(48, 14)
// center it horizontally and vertically within the whole screen
.anchor_center(&canvas_bounds)
// move it up 16px
.translate_y(-16);
Adjusting your bounds
In most cases, you can adjust your bounds with set pixel amounts, or by fractions of another bounds.
let parent = Bounds::new(0, 0, 200, 100);
// create a new bounds, half as wide as the parent
let child = parent.adjust_width_by_fraction(0.5);
Use your bounds to draw a rectangle
Once you have your bounds in the correct position, you can access its values.
let canvas_bounds = bounds::canvas();
// create a new bounds that is 48 px wide and 14 px tall
let bounds = Bounds::with_size(48, 14)
// centers it horizontally and vertically within the whole screen
.anchor_center(&canvas_bounds)
// move it up 16px
.translate_y(-16);
// highlight-start
rect!(
color = 0xffffffff,
// Use the bounds position for x and y
xy = bounds.xy(),
// Use the bounds size for w and h
wh = bounds.wh(),
);
// highlight-end
Complete Example
Create a row of 3 buttons that use bounds
to recognize whenever they are hovered or clicked
turbo::go!({
let p = pointer();
let canvas_bounds = bounds::canvas();
let buttons = canvas_bounds
.height(32)
.inset_left(8)
.inset_right(8)
.anchor_center(&canvas_bounds)
.inset_bottom(12)
.columns_with_gap(3, 12); //create a vec of 3 buttons, equally separated, with 12 horizontal pixels between them
for (i, btn) in buttons.into_iter().enumerate() {
let label = match i {
0 => "One",
1 => "Two",
2 => "Three",
_ => "",
};
let (regular_color, hover_color, pressed_color) = match i {
0 => (0x8833AAff, 0xAA55CCff, 0x800080FF),
1 => (0xCC3333ff, 0xFF5555ff, 0xFF0000FF),
2 => (0x33CCFFff, 0x66DDFFFF, 0x00FFFFFF),
_ => (0x3333CCff, 0x5555FFff, 0x000000ff),
};
let is_btn_hovered = p.xy().intersects_bounds(btn);
rect!(
color = if p.pressed() && is_btn_hovered {
pressed_color
} else if is_btn_hovered {
hover_color
} else {
regular_color
},
w = btn.w(),
h = btn.h(),
x = btn.x(),
y = btn.y(),
border_radius = 2,
);
let btn_inner = btn.inset_left(4).inset_top(4);
text!(label, x = btn_inner.x(), y = btn_inner.y(), font = "medium");
}
});