Skip to content

Instantly share code, notes, and snippets.

@laundmo
Created May 9, 2025 13:16
Show Gist options
  • Save laundmo/8e7a5d622b81eb9943ce022e953b6346 to your computer and use it in GitHub Desktop.
Save laundmo/8e7a5d622b81eb9943ce022e953b6346 to your computer and use it in GitHub Desktop.
bevy camera 2d drag/zoom with picking observers
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands, window: Single<Entity, With<Window>>) {
commands.spawn(Camera2d);
commands.entity(*window).observe(camera_drag).observe(zoom);
commands.spawn(Sprite::from_color(Color::WHITE, Vec2::splat(15.)));
}
fn camera_drag(
drag: Trigger<Pointer<Drag>>,
mut cam: Single<(&Camera, &GlobalTransform, &mut Transform)>,
) -> Result {
let mut cam_viewport = cam.0.world_to_viewport(cam.1, cam.2.translation)?;
cam_viewport += drag.delta * -1.; // inverted feels more natural
cam.2.translation = cam.0.viewport_to_world_2d(cam.1, cam_viewport)?.extend(0.0);
Ok(())
}
fn zoom(scroll: Trigger<Pointer<Scroll>>, proj: Single<&mut Projection, With<Camera>>) {
if let Projection::Orthographic(ref mut proj) = *proj.into_inner() {
proj.scale *= 1. - (scroll.y / 5.);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment