Files
maps/frontend/src/services/camera_service.rs
Dongho Kim 1dcdce3ef1 update
2025-12-18 07:36:51 +09:00

78 lines
2.6 KiB
Rust

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
}
}