update
This commit is contained in:
77
frontend/src/services/camera_service.rs
Normal file
77
frontend/src/services/camera_service.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
use winit::event::{ElementState, MouseButton, MouseScrollDelta};
|
||||
use crate::domain::camera::Camera;
|
||||
use crate::domain::state::InputState;
|
||||
|
||||
pub struct CameraService;
|
||||
|
||||
impl CameraService {
|
||||
// Zoom constants
|
||||
const MIN_ZOOM: f32 = 20.0;
|
||||
const MAX_ZOOM: f32 = 50000.0;
|
||||
|
||||
pub fn handle_resize(camera: &Arc<Mutex<Camera>>, width: u32, height: u32) {
|
||||
let mut cam = camera.lock().unwrap();
|
||||
cam.aspect = width as f32 / height as f32;
|
||||
}
|
||||
|
||||
pub fn handle_mouse_input(input: &mut InputState, state: ElementState, button: MouseButton) {
|
||||
if button == MouseButton::Left {
|
||||
input.is_dragging = state == ElementState::Pressed;
|
||||
input.last_cursor = None;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_cursor_move(
|
||||
camera: &Arc<Mutex<Camera>>,
|
||||
input: &mut InputState,
|
||||
position_x: f64,
|
||||
position_y: f64,
|
||||
screen_height: f32
|
||||
) {
|
||||
if input.is_dragging {
|
||||
if let Some((lx, ly)) = input.last_cursor {
|
||||
let dx = position_x - lx;
|
||||
let dy = position_y - ly;
|
||||
|
||||
let mut cam = camera.lock().unwrap();
|
||||
|
||||
// Use IDENTICAL formula for both X and Y
|
||||
// Since Y works correctly with 2/(zoom*height), use the same for X
|
||||
let scale = 2.0 / (cam.zoom * screen_height);
|
||||
|
||||
cam.x -= (dx as f32) * scale;
|
||||
cam.y -= (dy as f32) * scale;
|
||||
}
|
||||
input.last_cursor = Some((position_x, position_y));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_wheel(camera: &Arc<Mutex<Camera>>, delta: MouseScrollDelta) {
|
||||
let scroll = match delta {
|
||||
MouseScrollDelta::LineDelta(_, y) => y as f64,
|
||||
MouseScrollDelta::PixelDelta(pos) => pos.y / 50.0,
|
||||
};
|
||||
let mut cam = camera.lock().unwrap();
|
||||
let factor = if scroll > 0.0 { 1.1f32 } else { 0.9f32 };
|
||||
cam.zoom = (cam.zoom * factor).clamp(Self::MIN_ZOOM, Self::MAX_ZOOM);
|
||||
}
|
||||
|
||||
// Helper to convert slider (0-100) to zoom (logarithmic)
|
||||
pub fn slider_to_zoom(val: f64) -> f32 {
|
||||
let t = val / 100.0;
|
||||
let log_min = Self::MIN_ZOOM.ln();
|
||||
let log_max = Self::MAX_ZOOM.ln();
|
||||
let log_zoom = log_min + (log_max - log_min) * t as f32;
|
||||
log_zoom.exp()
|
||||
}
|
||||
|
||||
// Helper to convert zoom to slider (0-100)
|
||||
pub fn zoom_to_slider(zoom: f32) -> f64 {
|
||||
let log_min = Self::MIN_ZOOM.ln();
|
||||
let log_max = Self::MAX_ZOOM.ln();
|
||||
let log_zoom = zoom.ln();
|
||||
let t = (log_zoom - log_min) / (log_max - log_min);
|
||||
(t * 100.0) as f64
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user