diff --git a/index.html b/index.html
index 3d01131..a099958 100644
--- a/index.html
+++ b/index.html
@@ -19,6 +19,9 @@
left: 0;
width: 100%;
height: 100%;
+ /* Hand touch gestures (pinch/drag) to the app instead of letting
+ the browser treat them as page zoom/scroll. */
+ touch-action: none;
}
#loading_text {
position: absolute;
diff --git a/src/app.rs b/src/app.rs
index ff5dadb..07e269a 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -547,15 +547,31 @@ impl FractalApp {
let aspect = (rect.width() / rect.height()) as f64;
self.last_size_px = rect.size();
- // Pan by dragging.
- if response.dragged() {
+ // Touch: pinch to zoom (toward the gesture center) and two-finger pan.
+ // Takes precedence over single-finger drag while two fingers are down.
+ let multi_touch = ui.input(|i| i.multi_touch());
+ if let Some(mt) = multi_touch {
+ let t = mt.translation_delta;
+ if t.x != 0.0 || t.y != 0.0 {
+ self.view.pan_pixels(t.x as f64, t.y as f64, height_px);
+ }
+ if mt.zoom_delta != 1.0 {
+ let off = mt.center_pos - rect.center();
+ // zoom_delta > 1 = fingers spreading = zoom in (smaller span).
+ let factor = 1.0 / mt.zoom_delta as f64;
+ self.view
+ .zoom_at_pixel(off.x as f64, off.y as f64, height_px, factor);
+ }
+ ui.ctx().request_repaint();
+ } else if response.dragged() {
+ // Single-finger / mouse drag pans.
let d = response.drag_delta();
if d.x != 0.0 || d.y != 0.0 {
self.view.pan_pixels(d.x as f64, d.y as f64, height_px);
}
}
- // Zoom toward the cursor on scroll.
+ // Mouse wheel / trackpad: zoom toward the cursor.
let (scroll_y, hover) = ui.input(|i| (i.smooth_scroll_delta.y, i.pointer.hover_pos()));
if scroll_y != 0.0
&& let Some(pos) = hover