From ddb8391cfb23fe04187237deaeb611e4b5c6cb61 Mon Sep 17 00:00:00 2001 From: Maaxxs <61059039+MaaxxsDev@users.noreply.github.com> Date: Sat, 18 Jul 2026 06:44:19 +0200 Subject: [PATCH] Add mouse drag-to-scroll in the coverflow and a themed custom scrollbar Coverflow cards can now be grabbed and dragged with the mouse; touch keeps native momentum scrolling. Pointer capture only engages after real movement so ordinary clicks on card buttons still land, a capture-phase click handler swallows exactly the one click that ends a drag, and on release the row glides to the nearest card before snap re-engages. The native horizontal scrollbar under strip and coverflow is replaced by a slim centered track with a glowing brand-green thumb - draggable, click-to-jump, and hidden automatically when everything fits. Co-Authored-By: Claude Fable 5 --- hifi-src/src/pages/public/ModelPage.jsx | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/hifi-src/src/pages/public/ModelPage.jsx b/hifi-src/src/pages/public/ModelPage.jsx index ec45f06..9cc9e60 100644 --- a/hifi-src/src/pages/public/ModelPage.jsx +++ b/hifi-src/src/pages/public/ModelPage.jsx @@ -341,23 +341,34 @@ export default function ModelPage() { if (best !== null) el.scrollTo({ left: best - el.clientWidth / 2, behavior: 'smooth' }); }; + // WICHTIG: Pointer-Capture erst ab echter Bewegung (>4px) starten - sofortiges + // Capture beim Druecken wuerde auch das Click-Event auf den Container umlenken, + // womit normale Klicks auf Buttons/Links in den Karten nie ankaemen. + let pending = false; const onDown = (e) => { if (e.pointerType !== 'mouse' || e.button !== 0) return; - dragging = true; + pending = true; + dragging = false; moved = 0; startX = e.clientX; startScroll = el.scrollLeft; - el.setPointerCapture(e.pointerId); - el.style.scrollSnapType = 'none'; - el.dataset.dragging = 'true'; }; const onMove = (e) => { - if (!dragging) return; + if (!pending && !dragging) return; const dx = e.clientX - startX; moved = Math.max(moved, Math.abs(dx)); + if (!dragging) { + if (moved <= 4) return; + dragging = true; + pending = false; + el.setPointerCapture(e.pointerId); + el.style.scrollSnapType = 'none'; + el.dataset.dragging = 'true'; + } el.scrollLeft = startScroll - dx; }; const onUp = (e) => { + pending = false; if (!dragging) return; dragging = false; el.dataset.dragging = 'false';