pittore 0.2.2

Simple toolkit for 2D visualization based on wgpu.
Documentation
use glam::{vec2, vec3, Vec3};

use crate::{render::Camera, Context};

/// Camera controller for 2D viewport.
///
/// This reacts to mouse input events and changes parameters of the camera automatically.
pub struct CameraController2d {
    pub camera: Camera,
    pub scroll_sensitivity: f32,
}

impl Default for CameraController2d {
    fn default() -> Self {
        CameraController2d {
            camera: Camera::default_2d(),
            scroll_sensitivity: 0.1,
        }
    }
}

impl CameraController2d {
    /// Update camera with input.
    pub fn update(&mut self, ctx: &mut Context) {
        let viewport_size = ctx.render_state.resolution();

        if let Some(delta) = ctx.mouse_wheel_delta() {
            if let Some(cursor_pos) = ctx.cursor_position() {
                if delta.y != 0.0 {
                    let d = cursor_pos - viewport_size / 2.0;
                    let d = vec2(d.x, -d.y) / self.camera.scale;
                    let scale_mul = 2.0_f32.powf(delta.y * self.scroll_sensitivity);
                    self.camera.scale *= scale_mul;
                    self.camera.position += Vec3::from((d * (1.0 - scale_mul.recip()), 0.0));
                }
            }
        }

        if let Some(delta) = ctx.mouse_drage_delta() {
            let d = delta / self.camera.scale * 2.0; // double it to follow wgpu's coordinate system
            self.camera.position += vec3(-d.x, d.y, 0.0);
        }
    }

    /// Apply camera.
    pub fn apply(&self, ctx: &mut Context) {
        ctx.set_camera(self.camera.clone());
    }

    /// Update camera with input and apply camera.
    pub fn update_and_apply(&mut self, ctx: &mut Context) {
        self.update(ctx);
        self.apply(ctx);
    }
}