Skip to content

Add example demonstrating how to zoom orthographic cameras #2580

@alice-i-cecile

Description

@alice-i-cecile

How can Bevy's documentation be improved?

Zooming an orthographic camera is surprisingly tricky; unlike ordinary cameras moving them further away from the object doesn't cause the size of the objects displayed to change as all their projection is parallel.

@TheRawMeatball provided this initial solution in #help:

fn zoom_system(
    mut whl: EventReader<MouseWheel>,
    mut cam: Query<(&mut Transform, &mut OrthographicProjection), With<MainCamera>>,
    windows: Res<Windows>,
) {
    let delta_zoom: f32 = whl.iter().map(|e| e.y).sum();
    if delta_zoom == 0. {
        return;
    }

    let (mut pos, mut cam) = cam.single_mut().unwrap();

    let window = windows.get_primary().unwrap();
    let window_size = Vec2::new(window.width(), window.height());
    let mouse_normalized_screen_pos =
        (window.cursor_position().unwrap() / window_size) * 2. - Vec2::ONE;
    let mouse_world_pos = pos.translation.truncate()
        + mouse_normalized_screen_pos * Vec2::new(cam.right, cam.top) * cam.scale;

    cam.scale -= ZOOM_SPEED * delta_zoom * cam.scale;
    cam.scale = cam.scale.clamp(MIN_ZOOM, MAX_ZOOM);

    pos.translation = (mouse_world_pos
        - mouse_normalized_screen_pos * Vec2::new(cam.right, cam.top) * cam.scale)
        .extend(pos.translation.z);
}

This should be straightforward to verify and clean up. Adding panning or rotation might also be worth including in the same example.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-RenderingDrawing game state to the screenC-DocsAn addition or correction to our documentationD-TrivialNice and easy! A great choice to get started with Bevy

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions