update
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user