bevy_lagrange 0.0.3

Bevy camera controller with pan, orbit, zoom-to-fit, queued animations, and trackpad support
Documentation

Crates.io docs.rs Bevy tracking

bevy_lagrange

Work in progress. This crate is in active development and not subject to semver stability guarantees. APIs will change without notice between commits. Do not depend on this in production code yet.

A camera controller for Bevy that combines smooth orbit controls with event-driven camera operations — zoom-to-fit, queued animations, and a debug overlay for fit targets.

A screen recording showing camera movement

Features

  • Smooth orbit, pan, and zoom with configurable limits
  • Zoom-to-fit, look-at, and queued camera animations with easing
  • Event-driven control with full lifecycle events for sequencing
  • Orthographic and perspective projection, multi-viewport, render-to-texture
  • Touch, trackpad, and bevy_egui support
  • Debug overlay for fit targets (optional fit_overlay feature)

Quick Start

Add the plugin and spawn a camera:

use bevy::prelude::*;
use bevy_lagrange::LagrangePlugin;
use bevy_lagrange::OrbitCam;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(LagrangePlugin)
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn((
        Transform::from_translation(Vec3::new(0.0, 1.5, 5.0)),
        OrbitCam::default(),
    ));
}

OrbitCam automatically requires Camera3d. Out of the box you get orbit, pan, and zoom with smoothing. For perspective cameras, the default near clip plane scales with orbit radius so close-up zooming does not clip away the target.

Controls

Default mouse controls:

Input Action
Left Mouse Orbit
Right Mouse Pan
Scroll Wheel Zoom

Default touch controls:

Input Action
One finger Orbit
Two fingers Pan
Pinch Zoom

All controls are configurable via OrbitCam fields — buttons, modifiers, sensitivity, smoothness, and limits.

Event-Driven Camera Control

Enable the fit_overlay feature:

bevy_lagrange = { version = "...", features = ["fit_overlay"] }

Zoom-to-fit

Frame a target entity in the camera view:

commands.trigger(
    ZoomToFit::new(camera, target)
        .margin(0.15)
        .duration(Duration::from_millis(800))
        .easing(EaseFunction::CubicOut),
);

Look at

Rotate the camera in place to face a target:

commands.trigger(
    LookAt::new(camera, target)
        .duration(Duration::from_millis(600)),
);

Animate to a specific orientation

Animate to a chosen yaw/pitch while framing the target:

commands.trigger(
    AnimateToFit::new(camera, target)
        .yaw(PI / 4.0)
        .pitch(PI / 6.0)
        .duration(Duration::from_millis(1200)),
);

Queued animations

Chain multiple movements into a sequence:

commands.trigger(PlayAnimation::new(camera, [
    CameraMove::ToOrbit {
        focus: Vec3::ZERO,
        yaw: 0.0,
        pitch: 0.5,
        radius: 5.0,
        duration: Duration::from_millis(800),
        easing: EaseFunction::CubicOut,
    },
]));

All operations support instant (Duration::ZERO) and animated paths with full lifecycle events for sequencing.

Cargo Features

Feature Default Description
fit_overlay no Zoom-to-fit, camera animations, event-driven control, and debug overlay
bevy_egui no Prevents camera movement when interacting with egui windows

Version Compatibility

bevy_lagrange Bevy
0.0.3 0.18

Credits

License

All code in this repository is dual-licensed under either:

at your option.