pittore 0.2.4

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 config = &ctx.render_state.surface_config;
        let window_size = vec2(config.width as f32, config.height as f32);
        let viewport_size = ctx.render_state.resolution();
        let render_size = self.camera.scaling_mode.render_size(viewport_size);
        let scale = window_size / render_size * self.camera.scale;

        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.as_vec2() - window_size / 2.0;
                    let d = vec2(d.x, -d.y) / 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.as_vec2() / scale;
            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);
    }
}