fix(h5): reduce report swipe conflicts and limit edge overscroll

This commit is contained in:
xsl
2026-10-13 00:24:52 +08:00
parent f1e64565b9
commit 3efa28b311
10 changed files with 858 additions and 757 deletions
+6 -1
View File
@@ -1513,12 +1513,17 @@
panels[i].setAttribute('role', 'tabpanel'); panels[i].setAttribute('aria-labelledby', tab.id);
});
function height(at) {
// Fonts/images may resize while dragging. Keep the current card height
// until release so the rest of the report does not move under the finger.
if (swipe && swipe.isDragging()) return;
position = at;
var lower = Math.floor(at), upper = Math.min(panels.length - 1, Math.ceil(at)), ratio = at - lower;
viewport.style.height = (panels[lower].offsetHeight * (1 - ratio) + panels[upper].offsetHeight * ratio) + 'px';
}
var swipe = SwipeTrack.create(viewport, track, { count: panels.length, gestureTarget: card,
onMove: height, onCancel: height, onSelect: function (i) { setDetailTab(card, String(i)); } });
gestureSelector: '.viz-frame', startThreshold: 12, directionRatio: 1.5, maxOverscroll: 16,
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 });
setDetailTab(card, '0', true);
if (typeof ResizeObserver !== 'undefined') {
+12 -5
View File
@@ -21,6 +21,7 @@ window.SwipeTrack = (function () {
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.
if (options.gestureSelector && (!e.target.closest || !e.target.closest(options.gestureSelector))) return;
drag.id = e.pointerId; drag.startX = e.clientX; drag.startY = e.clientY;
drag.offset = track.getBoundingClientRect().left - viewport.getBoundingClientRect().left;
drag.width = viewport.clientWidth; drag.lastX = e.clientX; drag.lastAt = e.timeStamp; drag.velocity = 0;
@@ -31,9 +32,14 @@ window.SwipeTrack = (function () {
if (e.pointerId !== drag.id || drag.vertical) return;
var dx = e.clientX - drag.startX, dy = e.clientY - drag.startY;
if (!drag.horizontal) {
if (Math.abs(dy) > 8 && Math.abs(dy) >= Math.abs(dx)) { drag.vertical = true; return; }
if (Math.abs(dx) <= 8 || Math.abs(dx) <= Math.abs(dy)) return;
drag.horizontal = true; viewport.classList.add('dragging'); track.classList.add('dragging');
var threshold = options.startThreshold || 8, ratio = options.directionRatio || 1;
if (Math.max(Math.abs(dx), Math.abs(dy)) <= threshold) return;
// Ambiguous diagonal movement belongs to page scrolling. 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 (e.cancelable) e.preventDefault();
@@ -41,8 +47,9 @@ window.SwipeTrack = (function () {
if (elapsed > 0) drag.velocity = (e.clientX - drag.lastX) / elapsed;
drag.lastX = e.clientX; drag.lastAt = e.timeStamp;
var offset = drag.offset + dx, min = -(options.count - 1) * drag.width;
if (offset > 0) offset *= .25;
else if (offset < min) offset = min + (offset - min) * .25;
var edgeLimit = options.maxOverscroll == null ? Infinity : options.maxOverscroll;
if (offset > 0) offset = Math.min(edgeLimit, offset * .25);
else if (offset < min) offset = min - Math.min(edgeLimit, (min - offset) * .25);
track.style.transform = 'translate3d(' + offset + 'px,0,0)';
if (options.onMove) options.onMove(Math.max(0, Math.min(options.count - 1, -offset / drag.width)));
});