fix(h5): prevent native scrolling from stealing diagonal image swipes
This commit is contained in:
@@ -1522,6 +1522,7 @@
|
||||
}
|
||||
var swipe = SwipeTrack.create(viewport, track, { count: panels.length, gestureTarget: card,
|
||||
gestureSelector: '.viz-frame', startThreshold: 12, directionRatio: 2 / 3, maxOverscroll: 16,
|
||||
preventNativeHorizontalPan: true,
|
||||
onStart: function () { viewport.style.height = viewport.getBoundingClientRect().height + 'px'; },
|
||||
onCancel: height, onSelect: function (i) { setDetailTab(card, String(i)); } });
|
||||
detailSwipes.set(card, { swipe: swipe, height: height });
|
||||
|
||||
+26
-11
@@ -18,6 +18,20 @@ window.SwipeTrack = (function () {
|
||||
if (instant) { void track.offsetWidth; track.style.transition = ''; }
|
||||
}
|
||||
function cancel() { go(index, true); if (options.onCancel) options.onCancel(index); }
|
||||
function lockDirection(dx, dy) {
|
||||
if (drag.vertical) return false;
|
||||
if (drag.horizontal) return true;
|
||||
var threshold = options.startThreshold || 8, ratio = options.directionRatio || 1;
|
||||
if (Math.max(Math.abs(dx), Math.abs(dy)) <= threshold) return false;
|
||||
// Touch and pointer events must share the same decision, regardless of
|
||||
// which event stream the browser dispatches first.
|
||||
if (Math.abs(dy) * ratio >= Math.abs(dx)) { drag.vertical = true; return false; }
|
||||
drag.horizontal = true;
|
||||
if (options.onStart) options.onStart(index);
|
||||
viewport.classList.add('dragging'); track.classList.add('dragging');
|
||||
try { target.setPointerCapture(drag.id); } catch (_) {}
|
||||
return true;
|
||||
}
|
||||
target.addEventListener('pointerdown', function (e) {
|
||||
if (drag.id != null || e.isPrimary === false || e.button !== 0 || !viewport.clientWidth) return;
|
||||
suppressUntil = 0; // A fresh tap is intentional, not the preceding drag's click.
|
||||
@@ -31,17 +45,7 @@ window.SwipeTrack = (function () {
|
||||
target.addEventListener('pointermove', function (e) {
|
||||
if (e.pointerId !== drag.id || drag.vertical) return;
|
||||
var dx = e.clientX - drag.startX, dy = e.clientY - drag.startY;
|
||||
if (!drag.horizontal) {
|
||||
var threshold = options.startThreshold || 8, ratio = options.directionRatio || 1;
|
||||
if (Math.max(Math.abs(dx), Math.abs(dy)) <= threshold) return;
|
||||
// Each caller chooses its diagonal bias. Once locked, neither direction
|
||||
// can steal this gesture before the finger lifts.
|
||||
if (Math.abs(dy) * ratio >= Math.abs(dx)) { drag.vertical = true; return; }
|
||||
drag.horizontal = true;
|
||||
if (options.onStart) options.onStart(index);
|
||||
viewport.classList.add('dragging'); track.classList.add('dragging');
|
||||
try { target.setPointerCapture(e.pointerId); } catch (_) {}
|
||||
}
|
||||
if (!lockDirection(dx, dy)) return;
|
||||
if (e.cancelable) e.preventDefault();
|
||||
var elapsed = e.timeStamp - drag.lastAt;
|
||||
if (elapsed > 0) drag.velocity = (e.clientX - drag.lastX) / elapsed;
|
||||
@@ -53,6 +57,17 @@ window.SwipeTrack = (function () {
|
||||
track.style.transform = 'translate3d(' + offset + 'px,0,0)';
|
||||
if (options.onMove) options.onMove(Math.max(0, Math.min(options.count - 1, -offset / drag.width)));
|
||||
});
|
||||
if (options.preventNativeHorizontalPan) {
|
||||
// preventDefault on pointermove does not stop native viewport panning.
|
||||
// Cancel only the single-touch horizontal gesture before the browser
|
||||
// starts scrolling and sends pointercancel. Vertical/text/multi-touch
|
||||
// gestures keep their native behavior; taps still open image zoom.
|
||||
target.addEventListener('touchmove', function (e) {
|
||||
if (drag.id == null || e.touches.length !== 1) return;
|
||||
var touch = e.touches[0];
|
||||
if (lockDirection(touch.clientX - drag.startX, touch.clientY - drag.startY) && e.cancelable) e.preventDefault();
|
||||
}, { passive: false });
|
||||
}
|
||||
window.addEventListener('pointerup', function (e) {
|
||||
if (e.pointerId !== drag.id) return;
|
||||
var horizontal = drag.horizontal, dx = e.clientX - drag.startX, next = index;
|
||||
|
||||
Reference in New Issue
Block a user