diff --git a/src/components/ProductCard.astro b/src/components/ProductCard.astro index 6b19ff0..0b6949d 100644 --- a/src/components/ProductCard.astro +++ b/src/components/ProductCard.astro @@ -96,11 +96,52 @@ const desc = product.beschreibung[lang]; karussellWechseln(media, current + Number(control.dataset.dir)); } }); + + // Wischen/Swipen (Finger auf dem Handy, Maus ziehen am PC) — überall auf der Seite, wo eine + // Produktkarte mit mehreren Fotos vorkommt. Pointer Events statt separater Touch-/Maus-Logik, + // damit EIN Code sowohl Finger als auch Maus abdeckt. Ein "Swipe" zählt erst ab einer gewissen + // Mindeststrecke (SWIPE_SCHWELLE) und nur, wenn die Bewegung überwiegend horizontal war — sonst + // würde normales Scrollen der Seite (vertikal) versehentlich als Wisch-Geste missverstanden. + const SWIPE_SCHWELLE = 40; + let wischStart: { media: Element; x: number; y: number } | null = null; + let letzterWischZeitpunkt = 0; + + document.addEventListener("pointerdown", (e) => { + const media = (e.target as HTMLElement).closest("[data-carousel]"); + if (!media) return; + if (media.querySelectorAll(".carousel-img").length <= 1) return; + wischStart = { media, x: e.clientX, y: e.clientY }; + }); + + document.addEventListener("pointerup", (e) => { + if (!wischStart) return; + const { media, x, y } = wischStart; + wischStart = null; + const dx = e.clientX - x; + const dy = e.clientY - y; + if (Math.abs(dx) < SWIPE_SCHWELLE || Math.abs(dx) < Math.abs(dy)) return; + letzterWischZeitpunkt = Date.now(); + const imgs = [...media.querySelectorAll(".carousel-img")]; + const current = Math.max(0, imgs.findIndex((img) => img.style.display !== "none")); + karussellWechseln(media, current + (dx < 0 ? 1 : -1)); + }); + + document.addEventListener("pointercancel", () => { wischStart = null; }); + + // Direkt nach einem echten Wisch darf der Klick NICHT mehr zur Produktseite weiterspringen + // (sonst landet man ungewollt auf der Produktseite, nur weil man das Foto durchblättern + // wollte). Capture-Phase, damit das VOR dem normalen Link-Klick des + // greift. Ein kurzes Zeitfenster (300ms) reicht, da Klick direkt nach dem Loslassen kommt. + document.addEventListener("click", (e) => { + if (Date.now() - letzterWischZeitpunkt > 300) return; + const link = (e.target as HTMLElement).closest("a.product-card"); + if (link) { e.preventDefault(); e.stopPropagation(); } + }, true);