Skip to content

Bounds

Bounds example showing a simple button row

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");
    }
});

Bounds example showing a simple button row