This commit is contained in:
2025-11-27 13:56:41 +01:00
parent a69daad6ef
commit cf88a953f2
9 changed files with 99 additions and 16 deletions

View File

@@ -363,24 +363,70 @@ pub async fn run() {
user_location: None,
}));
// Zoom constants
const MIN_ZOOM: f32 = 20.0;
const MAX_ZOOM: f32 = 50000.0;
// Helper to convert slider (0-100) to zoom (logarithmic)
let slider_to_zoom = |val: f64| -> f32 {
let t = val / 100.0;
let log_min = MIN_ZOOM.ln();
let log_max = 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)
let zoom_to_slider = |zoom: f32| -> f64 {
let log_min = MIN_ZOOM.ln();
let log_max = MAX_ZOOM.ln();
let log_zoom = zoom.ln();
let t = (log_zoom - log_min) / (log_max - log_min);
(t * 100.0) as f64
};
let window_doc = web_sys::window().unwrap().document().unwrap();
// Slider
let camera_clone = camera.clone();
let window_clone = window.clone();
let slider = window_doc.get_element_by_id("zoom-slider")
.and_then(|e| e.dyn_into::<web_sys::HtmlInputElement>().ok());
if let Some(slider) = slider {
let closure = wasm_bindgen::closure::Closure::<dyn FnMut(web_sys::Event)>::new(move |event: web_sys::Event| {
let target = event.target().unwrap();
let input = target.dyn_into::<web_sys::HtmlInputElement>().unwrap();
let val = input.value().parse::<f64>().unwrap_or(50.0);
let new_zoom = slider_to_zoom(val);
let mut cam = camera_clone.lock().unwrap();
cam.zoom = new_zoom;
window_clone.request_redraw();
});
slider.add_event_listener_with_callback("input", closure.as_ref().unchecked_ref()).unwrap();
closure.forget();
}
// Zoom In Button
let camera_clone = camera.clone();
let window_clone = window.clone();
let btn_zoom_in = window_doc.get_element_by_id("btn-zoom-in")
.and_then(|e| e.dyn_into::<web_sys::HtmlButtonElement>().ok());
if let Some(btn) = btn_zoom_in {
let closure = wasm_bindgen::closure::Closure::<dyn FnMut()>::new(move || {
let mut cam = camera_clone.lock().unwrap();
cam.zoom *= 1.5;
cam.zoom = cam.zoom.max(20.0).min(50000.0);
let current_slider = zoom_to_slider(cam.zoom);
let new_slider = (current_slider + 5.0).min(100.0); // +5% step
cam.zoom = slider_to_zoom(new_slider);
window_clone.request_redraw();
});
btn.set_onclick(Some(closure.as_ref().unchecked_ref()));
closure.forget();
}
// Zoom Out Button
let camera_clone = camera.clone();
let window_clone = window.clone();
let btn_zoom_out = window_doc.get_element_by_id("btn-zoom-out")
@@ -389,8 +435,9 @@ pub async fn run() {
if let Some(btn) = btn_zoom_out {
let closure = wasm_bindgen::closure::Closure::<dyn FnMut()>::new(move || {
let mut cam = camera_clone.lock().unwrap();
cam.zoom /= 1.5;
cam.zoom = cam.zoom.max(20.0).min(50000.0);
let current_slider = zoom_to_slider(cam.zoom);
let new_slider = (current_slider - 5.0).max(0.0); // -5% step
cam.zoom = slider_to_zoom(new_slider);
window_clone.request_redraw();
});
btn.set_onclick(Some(closure.as_ref().unchecked_ref()));
@@ -538,6 +585,23 @@ pub async fn run() {
if let Some(el) = window_doc.get_element_by_id("debug-zoom") {
el.set_inner_html(&format!("{:.1}", cam.zoom));
}
// Sync slider
if let Some(slider) = window_doc.get_element_by_id("zoom-slider").and_then(|e| e.dyn_into::<web_sys::HtmlInputElement>().ok()) {
let min_zoom: f32 = 20.0;
let max_zoom: f32 = 50000.0;
let log_min = min_zoom.ln();
let log_max = max_zoom.ln();
let log_zoom = cam.zoom.ln();
let t = (log_zoom - log_min) / (log_max - log_min);
let val = (t * 100.0) as f64;
// Only update if not dragging (optional, but good for UX? actually input event handles drag)
// But if we update while dragging it might fight.
// However, for scroll wheel we need this.
// Let's just update it. The browser handles the active state.
slider.set_value(&val.to_string());
}
if let Some(el) = window_doc.get_element_by_id("debug-pos") {
el.set_inner_html(&format!("{:.4}, {:.4}", cam.y, cam.x)); // Lat, Lon approx
}