victor HF Staff commited on
Commit
95e2b9b
·
1 Parent(s): 5367212

Refine mobile nav swipe gesture logic

Browse files

Improves swipe gesture handling by using the final movement direction for slow drags instead of a fixed position threshold. Adds tracking of the last touch X position to better determine user intent when ending a drag.

src/lib/components/MobileNav.svelte CHANGED
@@ -72,10 +72,10 @@
72
  // Swipe gesture support for opening/closing the nav with live feedback
73
  // Thresholds from vaul drawer library
74
  const VELOCITY_THRESHOLD = 0.4; // px/ms - if exceeded, snap in swipe direction
75
- const CLOSE_THRESHOLD = 0.25; // 25% position threshold
76
  const DIRECTION_LOCK_THRESHOLD = 10; // px - movement needed to lock direction
77
 
78
  let touchstart: Touch | null = null;
 
79
  let dragStartTime: number = 0;
80
  let isDragging = $state(false);
81
  let dragOffset = $state(-100); // percentage: -100 (closed) to 0 (open)
@@ -164,6 +164,8 @@
164
  } else {
165
  dragOffset = Math.max(-100, Math.min(0, -100 + (deltaX / drawerWidth) * 100));
166
  }
 
 
167
  }
168
 
169
  function onTouchEnd(e: TouchEvent) {
@@ -179,12 +181,13 @@
179
  const distMoved = touch.clientX - touchstart.clientX;
180
  const velocity = Math.abs(distMoved) / timeTaken;
181
 
182
- // Determine snap direction based on velocity first, then position
183
  if (velocity > VELOCITY_THRESHOLD) {
184
  isOpen = distMoved > 0;
185
  } else {
186
- const openThreshold = -100 + CLOSE_THRESHOLD * 100;
187
- isOpen = dragOffset > openThreshold;
 
188
  }
189
 
190
  resetDragState();
@@ -201,6 +204,7 @@
201
  isDragging = false;
202
  potentialDrag = false;
203
  touchstart = null;
 
204
  directionLock = null;
205
  }
206
 
 
72
  // Swipe gesture support for opening/closing the nav with live feedback
73
  // Thresholds from vaul drawer library
74
  const VELOCITY_THRESHOLD = 0.4; // px/ms - if exceeded, snap in swipe direction
 
75
  const DIRECTION_LOCK_THRESHOLD = 10; // px - movement needed to lock direction
76
 
77
  let touchstart: Touch | null = null;
78
+ let lastTouchX: number | null = null;
79
  let dragStartTime: number = 0;
80
  let isDragging = $state(false);
81
  let dragOffset = $state(-100); // percentage: -100 (closed) to 0 (open)
 
164
  } else {
165
  dragOffset = Math.max(-100, Math.min(0, -100 + (deltaX / drawerWidth) * 100));
166
  }
167
+
168
+ lastTouchX = touch.clientX;
169
  }
170
 
171
  function onTouchEnd(e: TouchEvent) {
 
181
  const distMoved = touch.clientX - touchstart.clientX;
182
  const velocity = Math.abs(distMoved) / timeTaken;
183
 
184
+ // Determine snap direction based on velocity first, then final movement direction
185
  if (velocity > VELOCITY_THRESHOLD) {
186
  isOpen = distMoved > 0;
187
  } else {
188
+ // For slow drags, use the final movement direction (allows "change of mind")
189
+ const finalDirection = lastTouchX !== null ? touch.clientX - lastTouchX : distMoved;
190
+ isOpen = finalDirection > 0;
191
  }
192
 
193
  resetDragState();
 
204
  isDragging = false;
205
  potentialDrag = false;
206
  touchstart = null;
207
+ lastTouchX = null;
208
  directionLock = null;
209
  }
210