swipe things

This commit is contained in:
2025-06-23 23:56:57 +02:00
parent a31c99453b
commit 89dad2ee13
2 changed files with 100 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
---
// SwipeNavigation component for mobile swipe-to-go-back functionality
---
<div id="swipe-container" class="fixed inset-0 pointer-events-none z-50">
<div id="swipe-area" class="absolute left-0 top-0 w-8 h-full pointer-events-auto"></div>
</div>
<script>
class SwipeNavigation {
private startX: number = 0;
private startY: number = 0;
private isTracking: boolean = false;
private readonly minSwipeDistance: number = 100;
private readonly maxVerticalDistance: number = 50;
constructor() {
this.init();
}
private init() {
const swipeArea = document.getElementById('swipe-area');
if (!swipeArea) return;
// Only enable on mobile devices
if (!this.isMobile()) return;
swipeArea.addEventListener('touchstart', this.handleTouchStart.bind(this), { passive: true });
swipeArea.addEventListener('touchmove', this.handleTouchMove.bind(this), { passive: true });
swipeArea.addEventListener('touchend', this.handleTouchEnd.bind(this), { passive: true });
}
private isMobile(): boolean {
return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
}
private handleTouchStart(e: TouchEvent) {
const touch = e.touches[0];
this.startX = touch.clientX;
this.startY = touch.clientY;
this.isTracking = true;
}
private handleTouchMove(e: TouchEvent) {
if (!this.isTracking) return;
const touch = e.touches[0];
const deltaX = touch.clientX - this.startX;
const deltaY = Math.abs(touch.clientY - this.startY);
// If vertical movement is too large, cancel the swipe
if (deltaY > this.maxVerticalDistance) {
this.isTracking = false;
return;
}
// Prevent default only if we're swiping left (negative deltaX)
if (deltaX < 0) {
e.preventDefault();
}
}
private handleTouchEnd(e: TouchEvent) {
if (!this.isTracking) return;
const touch = e.changedTouches[0];
const deltaX = touch.clientX - this.startX;
const deltaY = Math.abs(touch.clientY - this.startY);
// Check if it's a valid left swipe
if (deltaX < -this.minSwipeDistance && deltaY < this.maxVerticalDistance) {
this.goBack();
}
this.isTracking = false;
}
private goBack() {
// Check if there's history to go back to
if (window.history.length > 1) {
window.history.back();
}
}
}
// Initialize swipe navigation when the DOM is ready
document.addEventListener('DOMContentLoaded', () => {
new SwipeNavigation();
});
</script>
<style>
#swipe-area {
background: transparent;
/* Optional: Add a subtle visual indicator for debugging */
/* background: rgba(255, 0, 0, 0.1); */
}
</style>

View File

@@ -2,6 +2,7 @@
import "../styles/global.css"; import "../styles/global.css";
import Head from "./Head.astro"; import Head from "./Head.astro";
import Navigation from "../components/Navigation.astro"; import Navigation from "../components/Navigation.astro";
import SwipeNavigation from "../components/SwipeNavigation.astro";
import { getLanguageFromPath } from "../lib/i18n"; import { getLanguageFromPath } from "../lib/i18n";
import ReloadPrompt from '../components/ReloadPrompt.astro'; import ReloadPrompt from '../components/ReloadPrompt.astro';
@@ -22,6 +23,7 @@ const currentLang = getLanguageFromPath(Astro.url.pathname);
<ReloadPrompt /> <ReloadPrompt />
</main> </main>
<SwipeNavigation />
</body> </body>
</html> </html>